Fix integer underflow for signed/unsigned conversion 38/223338/1
authorSemun Lee <semun.lee@samsung.com>
Wed, 29 Jan 2020 01:05:44 +0000 (10:05 +0900)
committerSemun Lee <semun.lee@samsung.com>
Wed, 29 Jan 2020 01:18:21 +0000 (10:18 +0900)
Change-Id: I491df014536346147252db49d2bca959e0937bdf
Signed-off-by: Semun Lee <semun.lee@samsung.com>
src/bluetooth-gatt.c

index 1826561..142b227 100644 (file)
@@ -1097,35 +1097,41 @@ static void __bt_gatt_destroy_service(bt_gatt_h gatt_handle)
 }
 
 /* LCOV_EXCL_START */
-static int __convert_int_to_signed_bits(int i, int size)
+static unsigned int __convert_int_to_signed_bits(int i, int size)
 {
+       unsigned int signed_bits;
        if (i < 0)
-               i = (1 << (size - 1)) + (i & ((1 << (size - 1)) - 1));
+               signed_bits = (1 << (size - 1)) + (i & ~(0xFFFFFFFF << (size - 1)));
+       else
+               signed_bits = (unsigned int)i;
 
-       return i;
+       return signed_bits;
 }
 
-static int __convert_unsigned_to_signed(int value, int size)
+static int __convert_unsigned_to_signed(unsigned int value, int size)
 {
-       if ((value & (1 << (size-1))) != 0) {
-               value = -1 * ((1 << (size-1))
-                               - (value & ((1 << (size-1)) - 1)));
+       int signed_value;
+       if ((value & (1 << (size - 1))) != 0) {
+               signed_value = -1 * (int)((1 << (size - 1))
+                               - (value & ~(0xFFFFFFFF << (size - 1))));
+       } else {
+               signed_value = (int)value;
        }
-       return value;
+       return signed_value;
 }
 
-static int __convert_unsigned_byte_to_int(char b)
+static unsigned int __convert_unsigned_byte_to_int(char b)
 {
        return b & 0xFF;
 }
 
-static int __convert_unsigned_bytes_to_int16(char b0, char b1)
+static unsigned int __convert_unsigned_bytes_to_int16(char b0, char b1)
 {
        return (__convert_unsigned_byte_to_int(b0)
                + (__convert_unsigned_byte_to_int(b1) << 8));
 }
 
-static int __convert_unsigned_bytes_to_int32(char b0, char b1, char b2, char b3)
+static unsigned int __convert_unsigned_bytes_to_int32(char b0, char b1, char b2, char b3)
 {
        return (__convert_unsigned_byte_to_int(b0)
                + (__convert_unsigned_byte_to_int(b1) << 8))
@@ -1532,6 +1538,7 @@ int bt_gatt_set_int_value(bt_gatt_h gatt_handle, bt_data_type_int_e type,
        char *tmp;
        int fmt_size;
        int idx = offset;
+       unsigned int value_bits;
        bt_gatt_common_s *handle = (bt_gatt_common_s *)gatt_handle;
        bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
        bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)gatt_handle;
@@ -1593,17 +1600,17 @@ int bt_gatt_set_int_value(bt_gatt_h gatt_handle, bt_data_type_int_e type,
 
        switch (type) {
        case BT_DATA_TYPE_SINT8:
-               value = __convert_int_to_signed_bits(value, 8);
-               (*val)[idx] = (char)(value & 0xFF);
+               value_bits = __convert_int_to_signed_bits(value, 8);
+               (*val)[idx] = (char)(value_bits & 0xFF);
                break;
        case BT_DATA_TYPE_UINT8:
                (*val)[idx] = (char)(value & 0xFF);
                break;
 
        case BT_DATA_TYPE_SINT16:
-               value = __convert_int_to_signed_bits(value, 16);
-                (*val)[idx++] = (char)(value & 0xFF);
-                (*val)[idx] = (char)((value >> 8) & 0xFF);
+               value_bits = __convert_int_to_signed_bits(value, 16);
+                (*val)[idx++] = (char)(value_bits & 0xFF);
+                (*val)[idx] = (char)((value_bits >> 8) & 0xFF);
                break;
        case BT_DATA_TYPE_UINT16:
                 (*val)[idx++] = (char)(value & 0xFF);
@@ -1611,11 +1618,11 @@ int bt_gatt_set_int_value(bt_gatt_h gatt_handle, bt_data_type_int_e type,
                break;
 
        case BT_DATA_TYPE_SINT32:
-               value = __convert_int_to_signed_bits(value, 32);
-               (*val)[idx++] = (char)(value & 0xFF);
-               (*val)[idx++] = (char)((value >> 8) & 0xFF);
-               (*val)[idx++] = (char)((value >> 16) & 0xFF);
-               (*val)[idx] = (char)((value >> 24) & 0xFF);
+               value_bits = __convert_int_to_signed_bits(value, 32);
+               (*val)[idx++] = (char)(value_bits & 0xFF);
+               (*val)[idx++] = (char)((value_bits >> 8) & 0xFF);
+               (*val)[idx++] = (char)((value_bits >> 16) & 0xFF);
+               (*val)[idx] = (char)((value_bits >> 24) & 0xFF);
                break;
        case BT_DATA_TYPE_UINT32:
                (*val)[idx++] = (char)(value & 0xFF);
@@ -1656,8 +1663,8 @@ int bt_gatt_set_float_value(bt_gatt_h gatt_handle, bt_data_type_float_e type,
        int ret;
        char **val = NULL;
        int *val_len = NULL;
-       int mant;
-       int exp;
+       unsigned int mant;
+       unsigned int exp;
        char *tmp;
        int fmt_size;
        int idx = offset;