mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-03-31 05:20:36 +02:00
shared: fix crash in _NM_UTILS_STRING_TABLE_LOOKUP_DEFINE()
If you have a LIST with 7 elements, and you lookup a value that
is not in the (sorted) list and would lie before the first element,
the binary search will dig down to imin=0, imid=0, imax=0 and
strcmp will give positive cmp value (indicating that the searched
value is sorted before).
Then, we would do "imax = imid - 1;", which wrapped to G_MAXUINT,
and the following "if (G_UNLIKELY (imin > imax))" would not hit,
resulting in an out of bound access next.
The easy fix is to not used unsigned integers.
The binary search was adapted from nm_utils_array_find_binary_search()
and nm_utils_ptrarray_find_binary_search(), which already used signed
integers to avoid this problem.
Fixes: 17d9b852c8 ('shared: explicitly implement binary search in NM_UTILS_STRING_TABLE_LOOKUP_DEFINE*()')
This commit is contained in:
parent
db37e530e8
commit
be8be0f091
1 changed files with 8 additions and 8 deletions
|
|
@ -1736,10 +1736,10 @@ fcn_name (const char *name) \
|
|||
\
|
||||
if (G_LIKELY (name)) { \
|
||||
G_STATIC_ASSERT (G_N_ELEMENTS (LIST) > 1); \
|
||||
G_STATIC_ASSERT (G_N_ELEMENTS (LIST) < G_MAXUINT / 2u - 10u); \
|
||||
unsigned imin = 0; \
|
||||
unsigned imax = (G_N_ELEMENTS (LIST) - 1); \
|
||||
unsigned imid = (G_N_ELEMENTS (LIST) - 1) / 2; \
|
||||
G_STATIC_ASSERT (G_N_ELEMENTS (LIST) < G_MAXINT / 2 - 10); \
|
||||
int imin = 0; \
|
||||
int imax = (G_N_ELEMENTS (LIST) - 1); \
|
||||
int imid = (G_N_ELEMENTS (LIST) - 1) / 2; \
|
||||
\
|
||||
for (;;) { \
|
||||
const int cmp = strcmp (LIST[imid].name, name); \
|
||||
|
|
@ -1748,15 +1748,15 @@ fcn_name (const char *name) \
|
|||
return get_operator (LIST[imid].value); \
|
||||
\
|
||||
if (cmp < 0) \
|
||||
imin = imid + 1u; \
|
||||
imin = imid + 1; \
|
||||
else \
|
||||
imax = imid - 1u; \
|
||||
imax = imid - 1; \
|
||||
\
|
||||
if (G_UNLIKELY (imin > imax)) \
|
||||
break; \
|
||||
\
|
||||
/* integer overflow cannot happen, because LIST is shorter than G_MAXUINT/2. */ \
|
||||
imid = (imin + imax) / 2u;\
|
||||
/* integer overflow cannot happen, because LIST is shorter than G_MAXINT/2. */ \
|
||||
imid = (imin + imax) / 2;\
|
||||
} \
|
||||
} \
|
||||
\
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue