瀏覽代碼

[settings] Avoid potentially large stack allocations

Avoid potentially large stack allocations in fetchf_setting() and
storef_setting().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 年之前
父節點
當前提交
3880ebeb18
共有 1 個文件被更改,包括 43 次插入26 次删除
  1. 43
    26
      src/core/settings.c

+ 43
- 26
src/core/settings.c 查看文件

@@ -1046,28 +1046,32 @@ int setting_cmp ( struct setting *a, struct setting *b ) {
1046 1046
  */
1047 1047
 int fetchf_setting ( struct settings *settings, struct setting *setting,
1048 1048
 		     char *buf, size_t len ) {
1049
+	void *raw;
1049 1050
 	int raw_len;
1050
-	int check_len;
1051
-	int rc;
1051
+	int ret;
1052 1052
 
1053 1053
 	/* Fetch raw value */
1054
-	raw_len = fetch_setting_len ( settings, setting );
1054
+	raw_len = fetch_setting_copy ( settings, setting, &raw );
1055 1055
 	if ( raw_len < 0 ) {
1056
-		rc = raw_len;
1057
-		return rc;
1058
-	} else {
1059
-		uint8_t raw[raw_len];
1060
-
1061
-		/* Fetch raw value */
1062
-		check_len = fetch_setting ( settings, setting, raw,
1063
-					    sizeof ( raw ) );
1064
-		if ( check_len < 0 )
1065
-			return check_len;
1066
-		assert ( check_len == raw_len );
1056
+		ret = raw_len;
1057
+		goto err_fetch_copy;
1058
+	}
1067 1059
 
1068
-		/* Format value */
1069
-		return setting->type->format ( raw, sizeof ( raw ), buf, len );
1060
+	/* Return error if setting does not exist */
1061
+	if ( ! raw ) {
1062
+		ret = -ENOENT;
1063
+		goto err_exists;
1070 1064
 	}
1065
+
1066
+	/* Format setting */
1067
+	if ( ( ret = setting->type->format ( raw, raw_len, buf, len ) ) < 0 )
1068
+		goto err_format;
1069
+
1070
+ err_format:
1071
+	free ( raw );
1072
+ err_exists:
1073
+ err_fetch_copy:
1074
+	return ret;
1071 1075
 }
1072 1076
 
1073 1077
 /**
@@ -1080,6 +1084,7 @@ int fetchf_setting ( struct settings *settings, struct setting *setting,
1080 1084
  */
1081 1085
 int storef_setting ( struct settings *settings, struct setting *setting,
1082 1086
 		     const char *value ) {
1087
+	void *raw;
1083 1088
 	int raw_len;
1084 1089
 	int check_len;
1085 1090
 	int rc;
@@ -1088,21 +1093,33 @@ int storef_setting ( struct settings *settings, struct setting *setting,
1088 1093
 	if ( ( ! value ) || ( ! value[0] ) )
1089 1094
 		return delete_setting ( settings, setting );
1090 1095
 
1091
-	/* Parse formatted value */
1096
+	/* Get raw value length */
1092 1097
 	raw_len = setting->type->parse ( value, NULL, 0 );
1093 1098
 	if ( raw_len < 0 ) {
1094 1099
 		rc = raw_len;
1095
-		return rc;
1096
-	} else {
1097
-		uint8_t raw[raw_len];
1098
-
1099
-		/* Parse formatted value */
1100
-		check_len = setting->type->parse ( value, raw, sizeof ( raw ) );
1101
-		assert ( check_len == raw_len );
1100
+		goto err_parse_len;
1101
+	}
1102 1102
 
1103
-		/* Store raw value */
1104
-		return store_setting ( settings, setting, raw, sizeof ( raw ) );
1103
+	/* Allocate buffer for raw value */
1104
+	raw = malloc ( raw_len );
1105
+	if ( ! raw ) {
1106
+		rc = -ENOMEM;
1107
+		goto err_alloc_raw;
1105 1108
 	}
1109
+
1110
+	/* Parse formatted value */
1111
+	check_len = setting->type->parse ( value, raw, raw_len );
1112
+	assert ( check_len == raw_len );
1113
+
1114
+	/* Store raw value */
1115
+	if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
1116
+		goto err_store;
1117
+
1118
+ err_store:
1119
+	free ( raw );
1120
+ err_alloc_raw:
1121
+ err_parse_len:
1122
+	return rc;
1106 1123
 }
1107 1124
 
1108 1125
 /******************************************************************************

Loading…
取消
儲存