Hello all, just tried to and could reproduce this crash on a Raspbian. But because of the lack of debug symbols in Raspbian (or the lack of knowledge where to find them) I tried a i386 Buster VM, but there was no crash visible.
But a valgrind run shows following: valgrind gpxlogger -f /GPX/trk.gpx ==16014== Memcheck, a memory error detector ==16014== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==16014== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==16014== Command: gpxlogger -f /GPX/trk.gpx ==16014== ==16014== Invalid write of size 1 ==16014== at 0x4A88620: __strftime_internal (strftime_l.c:1433) ==16014== by 0x4A8A6B1: strftime_l (strftime_l.c:460) ==16014== by 0x4A8851A: strftime (strftime.c:25) ==16014== by 0x109A1A: main (gpxlogger.c:248) ==16014== Address 0x4da0084 is 0 bytes after a block of size 12 alloc'd ==16014== at 0x483356B: malloc (vg_replace_malloc.c:298) ==16014== by 0x483582C: realloc (vg_replace_malloc.c:785) ==16014== by 0x1099E6: main (gpxlogger.c:240) ==16014== To the strftime function is a buffer given for which is memory allocated in the size of the parameter "/GPX/trk.gpx" on the command line. Also the strftime function takes a parameter fnamesize-1 for this memory. If the buffer size is too small strftime returns 0 and the allocated buffer size should be increased. Unfortunately this size parameter is increased before the strftime call. Therefore we have just 12 bytes allocated but tell strftime it is allowed to write to 1035 bytes. Attached patch tries to move this addition below the strftime call. Kind regards, Bernhard
From 775532253ba4cade582866780ad9415491f6b94d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernha...@mailbox.org> Date: Tue, 18 Sep 2018 15:53:08 +0200 Subject: [PATCH] gpxlogger: Move buffer extension below the strftime call. Bug-Debian: https://bugs.debian.org/909082 Last-Update: 2018-09-18 --- gpxlogger.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gpxlogger.c b/gpxlogger.c index fda37ff..bf1844e 100644 --- a/gpxlogger.c +++ b/gpxlogger.c @@ -233,7 +233,7 @@ int main(int argc, char **argv) char *fname = NULL; time_t t; size_t s = 0; - size_t fnamesize = strlen(optarg); + size_t fnamesize = strlen(optarg) + 1; t = time(NULL); while (s == 0) { @@ -242,10 +242,11 @@ int main(int argc, char **argv) syslog(LOG_ERR, "realloc failed."); goto bailout; } else { - fnamesize += 1024; fname = newfname; } s = strftime(fname, fnamesize-1, optarg, localtime(&t)); + if (!s) + fnamesize += 1024; } fname[s] = '\0';; logfile = fopen(fname, "w"); -- 2.18.0
# Raspbian apt update apt install systemd-coredump mc export PKG="gpsd-clients gpsd-dbg valgrind gdb"; apt install $PKG; apt-mark auto $PKG mkdir gpsd/orig -p cd gpsd/orig apt source gpsd cd ../.. gpxlogger -f /GPXX/trk.gpx Speicherzugriffsfehler (Speicherabzug geschrieben) coredumpctl gdb PID: 2088 (gpxlogger) UID: 1001 (benutzer) GID: 1001 (benutzer) Signal: 11 (SEGV) Timestamp: Tue 2018-09-18 15:18:56 CEST (9min ago) Command Line: gpxlogger -f /GPXX/trk.gpx Executable: /usr/bin/gpxlogger Control Group: /user.slice/user-1001.slice/session-c2.scope Unit: session-c2.scope Slice: user-1001.slice Session: c2 Owner UID: 1001 (benutzer) Boot ID: 8be013eea88941bcabd05635419cdce7 Machine ID: 1ec87cb843e543a492b24a30f5a875c1 Hostname: raspberrypi Storage: /var/lib/systemd/coredump/core.gpxlogger.1001.8be013eea88941bcabd05635419cdce7.2088.1537276736000000000000.lz4 Message: Process 2088 (gpxlogger) of user 1001 dumped core. Stack trace of thread 2088: #0 0x00000000b6d5b404 __GI__IO_fwrite (libc.so.6) #1 0x0000000000011c04 n/a (gpxlogger) GNU gdb (Raspbian 7.12-6) 7.12.0.20161007-git Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "arm-linux-gnueabihf". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from /usr/bin/gpxlogger...(no debugging symbols found)...done. [New LWP 2088] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1". Core was generated by `gpxlogger -f /GPXX/trk.gpx'. Program terminated with signal SIGSEGV, Segmentation fault. #0 __GI__IO_fwrite (buf=0x2264c, size=1, count=39, fp=0x0) at iofwrite.c:37 37 iofwrite.c: Datei oder Verzeichnis nicht gefunden. (gdb) bt #0 __GI__IO_fwrite (buf=0x2264c, size=1, count=39, fp=0x0) at iofwrite.c:37 #1 0x00011c04 in ?? () Backtrace stopped: previous frame identical to this frame (corrupt stack?) -> Is there a dbgsym repository in Raspbian? #################### #################### #################### # Buster VM apt update apt install systemd-coredump mc gpsd-clients gpsd-dbg valgrind gdb apt build-dep gpsd mkdir gpsd/orig -p cd gpsd/orig apt source gpsd cd ../.. gpxlogger -f /GPX/trk.gpx # -> no crash valgrind gpxlogger -f /GPX/trk.gpx ==16014== Memcheck, a memory error detector ==16014== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==16014== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==16014== Command: gpxlogger -f /GPX/trk.gpx ==16014== ==16014== Invalid write of size 1 ==16014== at 0x4A88620: __strftime_internal (strftime_l.c:1433) ==16014== by 0x4A8A6B1: strftime_l (strftime_l.c:460) ==16014== by 0x4A8851A: strftime (strftime.c:25) ==16014== by 0x109A1A: main (gpxlogger.c:248) ==16014== Address 0x4da0084 is 0 bytes after a block of size 12 alloc'd ==16014== at 0x483356B: malloc (vg_replace_malloc.c:298) ==16014== by 0x483582C: realloc (vg_replace_malloc.c:785) ==16014== by 0x1099E6: main (gpxlogger.c:240) ==16014== ... gdb -q --args gpxlogger -f /GPX/trk.gpx set height 0 set width 0 set pagination off directory /home/benutzer/gpsd/orig/gpsd-3.17 b main:248 run b strftime b realloc 240 char *newfname = realloc(fname, fnamesize); (gdb) print fnamesize $4 = 12 248 s = strftime(fname, fnamesize-1, optarg, localtime(&t)); (gdb) print fnamesize $8 = 1036 (gdb) list 236 231 case 'f': /* Output file name. */ 232 { 233 char *fname = NULL; 234 time_t t; 235 size_t s = 0; 236 size_t fnamesize = strlen(optarg); 237 238 t = time(NULL); 239 while (s == 0) { 240 char *newfname = realloc(fname, fnamesize); 241 if (newfname == NULL) { 242 syslog(LOG_ERR, "realloc failed."); 243 goto bailout; 244 } else { 245 fnamesize += 1024; 246 fname = newfname; 247 } 248 s = strftime(fname, fnamesize-1, optarg, localtime(&t)); 249 } 250 fname[s] = '\0';; 251 logfile = fopen(fname, "w"); 252 if (logfile == NULL) { 253 syslog(LOG_ERR, 254 "Failed to open %s: %s, logging to stdout.", 255 fname, strerror(errno)); 256 logfile = stdout; 257 } 258 bailout: 259 free(fname); 260 break; 261 } cp orig try1 -a cd try1/gpsd-3.17 git init git add . git commit -m "Initial commit"