linux
Insufficient buffer length leads to buffer overflow
The char[4] `method' variable does not have enough space for the 2 extra chars required by strncat(method, ..., 2), since there must also be room for the final '\0'. The rule is that strncat(dest, src, n) requires sizeof(dest) >= strlen(dest) + n + 1; and in this case 4 >= 2 + 2 + 1 does not hold. Note that this bug is *not* revealed by just enabling STACKPROTECTOR, as it is stated in the commit message.
Bug fixed by commit f3d83e24154
| Type | BufferOverflow |
| Config | "X86 && ACPI_WMI" (2nd degree) |
| Fix-in | code |
| Location | drivers/platform/x86/ |
#if defined(CONFIG_X86) && defined(CONFIG_ACPI_WMI)
#include <string.h>
static char block_object_id[3] = "XX";
void wmi_query_block()
{
char method[4]; // (4) just four bytes long
strcpy(method, "WQ"); // (5) writes two bytes plus '\0'
strncat(method, block_object_id, 2); // (6) ERROR: no space for the final '\0'
}
int get_wmid_devices(void)
{
wmi_query_block(); // (3)
return 0;
}
int acer_wmi_init(void)
{
get_wmid_devices(); // (2)
return 0;
}
#endif
int main()
{
#if defined(CONFIG_X86) && defined(CONFIG_ACPI_WMI)
acer_wmi_init(); // (1)
#endif
return 0;
}
diff --git a/simple/f3d83e2.c b/simple/f3d83e2.c
--- a/simple/f3d83e2.c
+++ b/simple/f3d83e2.c
@@ -6,7 +6,7 @@
void wmi_query_block()
{
- char method[4]; // (4) just four bytes long
+ char method[5]; // (4) just four bytes long
strcpy(method, "WQ"); // (5) writes two bytes plus '\0'
strncat(method, block_object_id, 2); // (6) ERROR: no space for the final '\0'
#if defined(CONFIG_X86) && defined(CONFIG_ACPI_WMI)
#include <string.h>
static char block_object_id[3] = "XX";
#endif
int main()
{
#if defined(CONFIG_X86) && defined(CONFIG_ACPI_WMI)
// acer_wmi_init();
char method[4];
strcpy(method, "WQ");
strncat(method, block_object_id, 2); // ERROR
#endif
return 0;
}
. call init/main.c:740:do_one_initcall() . 753: ret.result = fn(); .. dyn-call drivers/platform/x86/acer-wmi.c:1266:acer_wmi_init() ... call drivers/platform/x86/acer-wmi.c:1090:get_wmid_devices() .... call drivers/platform/x86/wmi.c:322:wmi_query_block() .... 331: char method[4]; .... 378: strcpy(method, "WQ"); .... ERROR 379: strncat(method, block->object_id, 2);