summaryrefslogtreecommitdiff
path: root/src/read.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2021-09-06 00:14:57 -0400
committerPaul Smith <psmith@gnu.org>2021-09-06 00:14:57 -0400
commitabb1e8d10b4751eeeb7304c77cead828d248094b (patch)
treef494a12f2f950edbba83b2540a5e46947fbf704e /src/read.c
parentcc6dc70b160b81ca93e50db6a760bba9a670f4b0 (diff)
downloadmake-git-abb1e8d10b4751eeeb7304c77cead828d248094b.tar.gz
Remove UBSAN issues discovered via fuzzing tests.
The arithmetic conversions in C say that if a binary operator has an unsigned and signed type as operands and the unsigned type has a greater rank then the signed value is converted to unsigned. This is bad if the signed value is negative. There are a few places in the code which have this situation; convert the signed value to positive and add instead of subtracting. Reported by He Jingxuan <jingxuan.he@inf.ethz.ch> * src/read.c (find_map_unquote): Use a positive int in memmove(). (find_char_unquote): Ditto. (find_percent_cached): Ditto.
Diffstat (limited to 'src/read.c')
-rw-r--r--src/read.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/read.c b/src/read.c
index 65052fc3..4ef94c9a 100644
--- a/src/read.c
+++ b/src/read.c
@@ -2354,8 +2354,12 @@ find_map_unquote (char *string, int stopmap)
string_len = strlen (string);
/* The number of backslashes is now -I.
Copy P over itself to swallow half of them. */
- memmove (&p[i], &p[i/2], (string_len - (p - string)) - (i/2) + 1);
- p += i/2;
+ {
+ /* Avoid arithmetic conversion of negative values to unsigned. */
+ int hi = -(i/2);
+ memmove (&p[i], &p[i/2], (string_len - (p - string)) + hi + 1);
+ p += i/2;
+ }
if (i % 2 == 0)
/* All the backslashes quoted each other; the STOPCHAR was
unquoted. */
@@ -2397,8 +2401,12 @@ find_char_unquote (char *string, int stop)
string_len = strlen (string);
/* The number of backslashes is now -I.
Copy P over itself to swallow half of them. */
- memmove (&p[i], &p[i/2], (string_len - (p - string)) - (i/2) + 1);
- p += i/2;
+ {
+ /* Avoid arithmetic conversion of negative values to unsigned. */
+ int hi = -(i/2);
+ memmove (&p[i], &p[i/2], (string_len - (p - string)) + hi + 1);
+ p += i/2;
+ }
if (i % 2 == 0)
/* All the backslashes quoted each other; the STOPCHAR was
unquoted. */
@@ -2523,8 +2531,12 @@ find_percent_cached (const char **string)
/* The number of backslashes is now -I.
Copy P over itself to swallow half of them. */
- memmove (&pv[i], &pv[i/2], (slen - (pv - new)) - (i/2) + 1);
- p += i/2;
+ {
+ /* Avoid arithmetic conversion of negative values to unsigned. */
+ int hi = -(i/2);
+ memmove (&pv[i], &pv[i/2], (slen - (pv - new)) + hi + 1);
+ p += i/2;
+ }
/* If the backslashes quoted each other; the % was unquoted. */
if (i % 2 == 0)