|
From: | buganizer-system |
Subject: | Issue 391234167: gpsd: buffer overflow in sirf_msg_ppstime |
Date: | Mon, 20 Jan 2025 18:53:29 -0800 |
With the following (new fuzz target) generated by https://github.com/google/oss-fuzz-gen:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gpsd_config.h" // Include gpsd_config.h first
#include "/src/gpsd/gpsd-3.25.1~dev/include/gpsd.h"
#define FUZZ_BUFFER_SIZE 1024
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
struct gps_device_t session;
unsigned char buf[FUZZ_BUFFER_SIZE];
size_t len;
if (size > FUZZ_BUFFER_SIZE) {
len = FUZZ_BUFFER_SIZE;
} else {
len = size;
}
memset(&session, 0, sizeof(session));
struct gps_context_t context;
memset(&context, 0, sizeof(context));
session.context = &context;
struct gpsd_errout_t errout;
memset(&errout, 0, sizeof(errout));
context.errout = errout; // Fix: Remove the &
memcpy(buf, data, len);
sirf_parse(&session, buf, len);
return 0;
}
We found the following crash:
=================================================================
==2406489==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55b4ea09babc at pc 0x55b4e9fe3214 bp 0x7ffd1d30e890 sp 0x7ffd1d30e888
READ of size 4 at 0x55b4ea09babc thread T0
#0 0x55b4e9fe3213 in mkgmtime /tmp/gpsd/gpsd-3.25.1~dev/libgps/gpsutils.c:648:36
#1 0x55b4e9e86991 in sirf_msg_ppstime /tmp/gpsd/gpsd-3.25.1~dev/drivers/driver_sirf.c:2169:40
#2 0x55b4e9e7e026 in LLVMFuzzerTestOneInput /tmp/gpsd/fuzzer/FuzzJson.c:32:5
#3 0x55b4e9d8bed4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/tmp/gpsd/fuzzer/FuzzJson+0xe4ed4) (BuildId: 0f5bfaaf0f1489c55c0f2f6a05b84f3f0a9e3316)
#4 0x55b4e9d75313 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/tmp/gpsd/fuzzer/FuzzJson+0xce313) (BuildId: 0f5bfaaf0f1489c55c0f2f6a05b84f3f0a9e3316)
#5 0x55b4e9d7aec6 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/tmp/gpsd/fuzzer/FuzzJson+0xd3ec6) (BuildId: 0f5bfaaf0f1489c55c0f2f6a05b84f3f0a9e3316)
#6 0x55b4e9da51f6 in main (/tmp/gpsd/fuzzer/FuzzJson+0xfe1f6) (BuildId: 0f5bfaaf0f1489c55c0f2f6a05b84f3f0a9e3316)
#7 0x7fe8a2b31c89 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#8 0x7fe8a2b31d44 in __libc_start_main csu/../csu/libc-start.c:360:3
#9 0x55b4e9d6fc90 in _start (/tmp/gpsd/fuzzer/FuzzJson+0xc8c90) (BuildId: 0f5bfaaf0f1489c55c0f2f6a05b84f3f0a9e3316)
0x55b4ea09babc is located 4 bytes before global variable 'mkgmtime.cumdays' defined in '/tmp/gpsd/gpsd-3.25.1~dev/libgps/gpsutils.c:644' (0x55b4ea09bac0) of size 48
0x55b4ea09babc is located 52 bytes after global variable 'safe_atof.powersOf10' defined in '/tmp/gpsd/gpsd-3.25.1~dev/libgps/gpsutils.c:143' (0x55b4ea09ba40) of size 72
SUMMARY: AddressSanitizer: global-buffer-overflow /tmp/gpsd/gpsd-3.25.1~dev/libgps/gpsutils.c:648:36 in mkgmtime
Shadow bytes around the buggy address:
0x55b4ea09b800: 04 f9 f9 f9 05 f9 f9 f9 05 f9 f9 f9 04 f9 f9 f9
0x55b4ea09b880: 06 f9 f9 f9 07 f9 f9 f9 07 f9 f9 f9 07 f9 f9 f9
0x55b4ea09b900: 04 f9 f9 f9 05 f9 f9 f9 00 f9 f9 f9 00 f9 f9 f9
0x55b4ea09b980: 03 f9 f9 f9 07 f9 f9 f9 05 f9 f9 f9 05 f9 f9 f9
0x55b4ea09ba00: 02 f9 f9 f9 04 f9 f9 f9 00 00 00 00 00 00 00 00
=>0x55b4ea09ba80: 00 f9 f9 f9 f9 f9 f9[f9]00 00 00 00 00 00 f9 f9
0x55b4ea09bb00: f9 f9 f9 f9 00 00 02 f9 f9 f9 f9 f9 04 f9 f9 f9
0x55b4ea09bb80: 00 02 f9 f9 06 f9 f9 f9 00 03 f9 f9 00 04 f9 f9
0x55b4ea09bc00: 00 04 f9 f9 00 06 f9 f9 00 f9 f9 f9 00 05 f9 f9
0x55b4ea09bc80: 03 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
0x55b4ea09bd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==2406489==ABORTING
Using the following input (base64-encoded):
ens0NDQ0NDQ0AAA0NDT///////////////////////8A
The crash is a global-buffer-overflow in mkgmtime
while accessing cumdays
. The stack trace shows sirf_msg_ppstime
calls mkgmtime
. In sirf_msg_ppstime
, the value of unpacked_date.tm_mon
is derived from the fuzzer input data via getub(buf, 5) - 1
. If getub(buf, 5)
returns 0, then unpacked_date.tm_mon
will be -1. Subsequently, in mkgmtime
, cumdays[t->tm_mon % MONTHSPERYEAR]
becomes cumdays[-1 % 12]
, which evaluates to cumdays[-1]
leading to an out-of-bounds access.
Function Name:
mkgmtime
Line 644 - 648:
static const int cumdays[MONTHSPERYEAR] =
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
year = 1900 + t->tm_year + t->tm_mon / MONTHSPERYEAR;
result = (year - 1970) * 365 + cumdays[t->tm_mon % MONTHSPERYEAR];
Function Name:
sirf_msg_ppstime
Line 2165 - 2169:
unpacked_date.tm_sec = (int)getub(buf, 3);
unpacked_date.tm_mday = (int)getub(buf, 4);
unpacked_date.tm_mon = (int)getub(buf, 5) - 1;
unpacked_date.tm_year = (int)getbeu16(buf, 6) - 1900;
session->newdata.time.tv_sec = mkgmtime(&unpacked_date);
Can you please take a look?
[Prev in Thread] | Current Thread | [Next in Thread] |