]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
UBSan: Avoid unsigned integer overflow in utf8_{,un}escape()
authorJouni Malinen <j@w1.fi>
Sat, 23 Feb 2019 14:03:47 +0000 (16:03 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 25 Feb 2019 17:48:49 +0000 (19:48 +0200)
Split the if/while loop condition into two independent steps so that
in_size-- happens only in the case in_size is nonzero. This gets rid of
unnecessary UBSan warnings.

common.c:1087:16: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')
common.c:1076:16: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')
common.c:1119:16: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')

Signed-off-by: Jouni Malinen <j@w1.fi>
src/utils/common.c

index 1eb33705bef340b6c3f387760bb5b26a4e605ec7..f58d2351ba071e9a1dc9003d98a9ffa7b4a73d6c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * wpa_supplicant/hostapd / common helper functions, etc.
- * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -1073,7 +1073,8 @@ size_t utf8_unescape(const char *inp, size_t in_size,
                in_size--;
        }
 
-       while (in_size--) {
+       while (in_size) {
+               in_size--;
                if (res_size >= out_size)
                        return 0;
 
@@ -1084,8 +1085,9 @@ size_t utf8_unescape(const char *inp, size_t in_size,
                        return res_size;
 
                case '\\':
-                       if (!in_size--)
+                       if (!in_size)
                                return 0;
+                       in_size--;
                        inp++;
                        /* fall through */
 
@@ -1116,7 +1118,8 @@ size_t utf8_escape(const char *inp, size_t in_size,
        if (!in_size)
                in_size = os_strlen(inp);
 
-       while (in_size--) {
+       while (in_size) {
+               in_size--;
                if (res_size++ >= out_size)
                        return 0;