gpsd-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Issue 391234167: gpsd: buffer overflow in sirf_msg_ppstime


From: buganizer-system
Subject: Issue 391234167: gpsd: buffer overflow in sirf_msg_ppstime
Date: Mon, 20 Jan 2025 18:53:29 -0800

Replying to this email means your email address will be shared with the team that works on this product.
https://issues.oss-fuzz.com/issues/391234167

Reference Info: 391234167 gpsd: buffer overflow in sirf_msg_ppstime
component:  Public Trackers > 1362134 > OSS Fuzz
status:  New
reporter:  oc...@google.com
cc:  aj...@gmail.com, ga...@gmail.com, gpsd-dev@nongnu.org
collaborators:  co...@oss-fuzz.com
type:  Vulnerability
access level:  Default access
priority:  P2
severity:  S2
retention:  Component default
Project:  gpsd
Reported:  Jan 21, 2025

oc...@google.com added comment #1:

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

Analysis

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?




Generated by Google IssueTracker notification system.

You're receiving this email because you are subscribed to updates on Google IssueTracker issue 391234167
Unsubscribe from this issue.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]