m_options: limit list entries to 100

Limit list entries to 100. obj_settings_list is not designed to hold
more items, and it quickly starts taking ages to add all items. 100 is
more than enough.

Fixes 30s timeout on OSS-Fuzz and generally fixes possible DoS on mpv.
This commit is contained in:
Kacper Michajłow 2024-06-17 19:56:52 +02:00
parent 783150722d
commit b3b542af51
2 changed files with 36 additions and 6 deletions

View File

@ -671,6 +671,8 @@ Options of this type can be changed at runtime using the ``change-list``
command, which takes the suffix (without the ``-``) as separate operation
parameter.
An object settings list can hold up to 100 elements.
CONFIGURATION FILES
===================

View File

@ -2917,10 +2917,18 @@ static void obj_settings_list_del_at(m_obj_settings_t **p_obj_list, int idx)
// Insert such that *p_obj_list[idx] is set to item.
// If idx < 0, set idx = count + idx + 1 (i.e. -1 inserts it as last element).
// Memory referenced by *item is not copied.
static void obj_settings_list_insert_at(m_obj_settings_t **p_obj_list, int idx,
static bool obj_settings_list_insert_at(struct mp_log *log,
m_obj_settings_t **p_obj_list, int idx,
m_obj_settings_t *item)
{
int num = obj_settings_list_num_items(*p_obj_list);
// Limit list entries to 100. obj_settings_list is not designed to hold more
// items, and it quickly starts taking ages to add all items.
if (num > 100) {
mp_warn(log, "Object settings list capacity exceeded: "
"a maximum of 100 elements is allowed.");
return false;
}
if (idx < 0)
idx = num + idx + 1;
assert(idx >= 0 && idx <= num);
@ -2930,6 +2938,7 @@ static void obj_settings_list_insert_at(m_obj_settings_t **p_obj_list, int idx,
(num - idx) * sizeof(m_obj_settings_t));
(*p_obj_list)[idx] = *item;
(*p_obj_list)[num + 1] = (m_obj_settings_t){0};
return true;
}
static int obj_settings_list_find_by_label(m_obj_settings_t *obj_list,
@ -3266,7 +3275,10 @@ done: ;
.enabled = enabled,
.attribs = plist,
};
obj_settings_list_insert_at(_ret, -1, &item);
if (!obj_settings_list_insert_at(log, _ret, -1, &item)) {
obj_setting_free(&item);
return M_OPT_OUT_OF_RANGE;
}
return 1;
}
@ -3421,7 +3433,11 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
m_obj_settings_t item = {
.name = talloc_strdup(NULL, ""),
};
obj_settings_list_insert_at(&res, -1, &item);
if (!obj_settings_list_insert_at(log, &res, -1, &item)) {
obj_setting_free(&item);
ret = M_OPT_OUT_OF_RANGE;
goto done;
}
}
}
}
@ -3446,7 +3462,11 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
for (int n = 0; res && res[n].name; n++) {
int label = obj_settings_list_find_by_label0(list, res[n].label);
if (label < 0) {
obj_settings_list_insert_at(&list, prepend_counter, &res[n]);
if (!obj_settings_list_insert_at(log, &list, prepend_counter, &res[n])) {
obj_setting_free(&res[n]);
ret = M_OPT_OUT_OF_RANGE;
goto done;
}
prepend_counter++;
} else {
// Prefer replacement semantics, instead of actually
@ -3460,7 +3480,11 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
for (int n = 0; res && res[n].name; n++) {
int label = obj_settings_list_find_by_label0(list, res[n].label);
if (label < 0) {
obj_settings_list_insert_at(&list, -1, &res[n]);
if (!obj_settings_list_insert_at(log, &list, -1, &res[n])) {
obj_setting_free(&res[n]);
ret = M_OPT_OUT_OF_RANGE;
goto done;
}
} else {
// Prefer replacement semantics, instead of actually
// appending.
@ -3485,7 +3509,11 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
} else {
int found = obj_settings_find_by_content(list, &res[n]);
if (found < 0) {
obj_settings_list_insert_at(&list, -1, &res[n]);
if (!obj_settings_list_insert_at(log, &list, -1, &res[n])) {
obj_setting_free(&res[n]);
ret = M_OPT_OUT_OF_RANGE;
goto done;
}
} else {
obj_settings_list_del_at(&list, found);
obj_setting_free(&res[n]);