mirror of https://github.com/ipxe/ipxe.git
[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>pull/598/head
parent
063645118c
commit
3880ebeb18
|
@ -1046,28 +1046,32 @@ int setting_cmp ( struct setting *a, struct setting *b ) {
|
||||||
*/
|
*/
|
||||||
int fetchf_setting ( struct settings *settings, struct setting *setting,
|
int fetchf_setting ( struct settings *settings, struct setting *setting,
|
||||||
char *buf, size_t len ) {
|
char *buf, size_t len ) {
|
||||||
|
void *raw;
|
||||||
int raw_len;
|
int raw_len;
|
||||||
int check_len;
|
int ret;
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* Fetch raw value */
|
/* Fetch raw value */
|
||||||
raw_len = fetch_setting_len ( settings, setting );
|
raw_len = fetch_setting_copy ( settings, setting, &raw );
|
||||||
if ( raw_len < 0 ) {
|
if ( raw_len < 0 ) {
|
||||||
rc = raw_len;
|
ret = raw_len;
|
||||||
return rc;
|
goto err_fetch_copy;
|
||||||
} else {
|
|
||||||
uint8_t raw[raw_len];
|
|
||||||
|
|
||||||
/* Fetch raw value */
|
|
||||||
check_len = fetch_setting ( settings, setting, raw,
|
|
||||||
sizeof ( raw ) );
|
|
||||||
if ( check_len < 0 )
|
|
||||||
return check_len;
|
|
||||||
assert ( check_len == raw_len );
|
|
||||||
|
|
||||||
/* Format value */
|
|
||||||
return setting->type->format ( raw, sizeof ( raw ), buf, len );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return error if setting does not exist */
|
||||||
|
if ( ! raw ) {
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto err_exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Format setting */
|
||||||
|
if ( ( ret = setting->type->format ( raw, raw_len, buf, len ) ) < 0 )
|
||||||
|
goto err_format;
|
||||||
|
|
||||||
|
err_format:
|
||||||
|
free ( raw );
|
||||||
|
err_exists:
|
||||||
|
err_fetch_copy:
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1080,6 +1084,7 @@ int fetchf_setting ( struct settings *settings, struct setting *setting,
|
||||||
*/
|
*/
|
||||||
int storef_setting ( struct settings *settings, struct setting *setting,
|
int storef_setting ( struct settings *settings, struct setting *setting,
|
||||||
const char *value ) {
|
const char *value ) {
|
||||||
|
void *raw;
|
||||||
int raw_len;
|
int raw_len;
|
||||||
int check_len;
|
int check_len;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -1088,21 +1093,33 @@ int storef_setting ( struct settings *settings, struct setting *setting,
|
||||||
if ( ( ! value ) || ( ! value[0] ) )
|
if ( ( ! value ) || ( ! value[0] ) )
|
||||||
return delete_setting ( settings, setting );
|
return delete_setting ( settings, setting );
|
||||||
|
|
||||||
/* Parse formatted value */
|
/* Get raw value length */
|
||||||
raw_len = setting->type->parse ( value, NULL, 0 );
|
raw_len = setting->type->parse ( value, NULL, 0 );
|
||||||
if ( raw_len < 0 ) {
|
if ( raw_len < 0 ) {
|
||||||
rc = raw_len;
|
rc = raw_len;
|
||||||
return rc;
|
goto err_parse_len;
|
||||||
} else {
|
}
|
||||||
uint8_t raw[raw_len];
|
|
||||||
|
/* Allocate buffer for raw value */
|
||||||
|
raw = malloc ( raw_len );
|
||||||
|
if ( ! raw ) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto err_alloc_raw;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse formatted value */
|
/* Parse formatted value */
|
||||||
check_len = setting->type->parse ( value, raw, sizeof ( raw ) );
|
check_len = setting->type->parse ( value, raw, raw_len );
|
||||||
assert ( check_len == raw_len );
|
assert ( check_len == raw_len );
|
||||||
|
|
||||||
/* Store raw value */
|
/* Store raw value */
|
||||||
return store_setting ( settings, setting, raw, sizeof ( raw ) );
|
if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
|
||||||
}
|
goto err_store;
|
||||||
|
|
||||||
|
err_store:
|
||||||
|
free ( raw );
|
||||||
|
err_alloc_raw:
|
||||||
|
err_parse_len:
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
Loading…
Reference in New Issue