Package: plptools
Version: 1.0.13-2
Severity: important

Dear Maintainer,

The following report ONLY applies to the i686 32 bits port of the plpfuse tool 
from the plptools package.
The issue is grave (severity 7) on i686 32 bits system.
The issue is NOT present at all on amd64 64 bits system.

1. Quick issue description

When plpfuse is started to transfer data from and to a Psion S5mx, through a 
serial port, plpfuse crashes with a core dump.
The directory from the Psion is not mounted. It is impossible to transfer data 
in both direction.
On i686 32 bits system, the package is unusable.

2. Detailed issue description

In debug mode, plpfuse is started with the following command :
$ plpfuse -d -d -d /media/lionel/psion

The result of this command is as follows :
FUSE library version: 2.9.9
nullpath_ok: 0
nopath: 0
utime_omit_ok: 0
unique: 2, opcode: INIT (26), nodeid: 0, insize: 104, pid: 0
INIT: 7.38
flags=0x73fffffb
max_readahead=0x00020000
   INIT: 7.19
   flags=0x00000011
   max_readahead=0x00020000
   max_write=0x00020000
   max_background=0
   congestion_threshold=0
   unique: 2, success, outsize: 40
unique: 4, opcode: LOOKUP (1), nodeid: 1, insize: 45, pid: 4003
LOOKUP /BDMV
getattr /BDMV
Segmentation fault (core dumped)

Extraction of the backtrace with gdb in the corresponding core dump shows the 
following result :
Core was generated by `plpfuse -d -d -d /media/lionel/psion'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  __gettimeofday (tv=0x0, tz=0xbf811070) at ../include/time.h:389
389     ../include/time.h: Aucun fichier ou dossier de ce type.
(gdb) bt
#0  __gettimeofday (tv=0x0, tz=0xbf811070) at ../include/time.h:389
#1  0xb7eb14d3 in PsiTime::PsiTime (this=0xbf811054, time=0) at 
./lib/psitime.cc:40
#2  0xb7eb20db in PlpDirent::PlpDirent (this=0xbf811040) at 
./lib/plpdirent.cc:44
#3  0x00452924 in rfsv_getattr (name=0x1026941 "BDMV", attr=0xbf81110c, 
size=0xbf811110, time=0xbf811114)
    at ./plpfuse/main.cc:291
#4  0x00454a00 in plp_getattr (path=0x1026941 "BDMV", st=0xbf8111f4) at 
./plpfuse/fuse.c:255
#5  0xb7e31786 in ?? () from /lib/i386-linux-gnu/libfuse.so.2
#6  0xb7e318f1 in ?? () from /lib/i386-linux-gnu/libfuse.so.2
#7  0xb7e3e6cc in ?? () from /lib/i386-linux-gnu/libfuse.so.2
#8  0xb7e3ad71 in fuse_session_loop () from /lib/i386-linux-gnu/libfuse.so.2
#9  0xb7e30ef2 in fuse_loop () from /lib/i386-linux-gnu/libfuse.so.2
#10 0x00452e7f in fuse (argc=5, argv=0xbf811614) at ./plpfuse/main.cc:405
#11 0x00451ac5 in main (argc=5, argv=0xbf811614) at ./plpfuse/main.cc:471

Detailed backtrace requires the installation of the plptools-dbgsym package.

3. Issue investigation and analysis

The backtrace shows a crash in gettimeofday(), after a call from 
PsiTime::PsiTime of the plptools library used by plpfuse.
gettimeofday() is called with a NULL first parameter, which is the cause of the 
crash.

I found out the following information in the man page of gettimeofdays :

3.a. The synopsis of gettimeofday is as follows :
int gettimeofday(struct timeval *restrict tv,
                 struct timezone *_Nullable restrict tz);
According to this synopsis, only the second parameter in "_Nullable".

3.b. DESCRIPTION
If  either  tv  or tz is NULL, the corresponding structure is not set or 
returned.  (However, compilation warnings
will result if tv is NULL.)
According to this description, both parameters can be NULL, but with 
compilation warnings for the first parameter.

3.c. STANDARDS
  SVr4, 4.3BSD.  POSIX.1-2001 describes gettimeofday() but not settimeofday().  
POSIX.1-2008 marks gettimeofday() as
  obsolete, recommending the use of clock_gettime(2) instead.
According to this warning, using gettimeofday() is no longer recommanded by 
POSIX.

4. Issue fix and patch

The code calling gettimeofday(), and maybe also the gettimeofday() man page, 
need some rework.

I did fix the issue of plpfuse on i686 32 bits systems, without actually 
replacing gettimeofday().
The proposed patch is as follows :

diff -u plptools-1.0.13.orig/lib/psitime.cc plptools-1.0.13/lib/psitime.cc
--- plptools-1.0.13.orig/lib/psitime.cc 2014-10-15 03:57:36.000000000 +0200
+++ plptools-1.0.13/lib/psitime.cc      2024-10-09 20:50:04.655072539 +0200
@@ -37,7 +37,7 @@
 
 PsiTime::PsiTime(time_t time) {
     ptzValid = false;
-    gettimeofday(NULL, &utz);
+    gettimeofday(&utv, &utz);
     setUnixTime(time);
 }
 
@@ -52,7 +52,7 @@
        tryPsiZone();
     }
     /* get our own timezone */
-    gettimeofday(NULL, &utz);
+    gettimeofday(&utv, &utz);
     psi2unix();
 }
 
@@ -62,7 +62,7 @@
     ptzValid = false;
     tryPsiZone();
     /* get our own timezone */
-    gettimeofday(NULL, &utz);
+    gettimeofday(&utv, &utz);    
     psi2unix();
 }

This patch avoids calling gettimeofday() with a NULL first parameter.
The patch reuses the utv variable already present in the code.
Validation of the proposed patch by upstream is recommanded, because usage of 
gettimeofday() seems deprecated by POSIX.

5. Additional information related to plptools packages in Debian

5.a. The issue is present in plptools 1.0.13-2, from Debian 12 Bookworm, 
current stable version.

5.b. The issue is also present in plptool 1.0.13-3, currently in testing/sid.

5.c. The proposed patch also fixes the issue in plptools 1.0.13-3 from testing. 
This has been tested in Bookwork.

5.d. The plptools 1.0.13-3 package fixes other issues in the code. Some issues 
fixed are related to build failing in 32 bits.
Build failing are related to 32 bits toolchain changes between Bookwork and 
Trixie.
These toolchain changes allow to detect issues in the code, but the issue with 
gettimeofday() is not detected.
I did not examine all details of the 32 bits toolchain changes between Bookwork 
and Trixie.

5.e. The proposed patch has also been applied and tested on amd64 64 bits 
system.
As far as I know, it does not break plpfuse on amd64 64 bits system.
Again, the issue described is NOT present on amd64 64 bits system.
The issue is specific to i686 32 bits build, and maybe to other 32 bits 
architectures, but I did not test them.

5.f. The issue described is not present in Debian 11 Bullseye, including in 
i686 32 bits architecture.
The issue has been introduced by Debian 12 Bookworm.
Debian 11 Bullseye uses plptools 1.0.13-2, the same package version that Debian 
12 Bookworm.
This means that a change in the libc, or in the 32 bits toolchain, did make 
this issue appear in Debian 12 Bookworm.
I suspect a change in the implementation of gettimeofday() in the 32 bits libc, 
but I did not investigate this part.
Additional investigation is recommanded, with comparisons between Debian 11 
Bullseye, Debian 12 Bookworm and testing/sid.

6. Testing

It is possible to observe the core dump without a Psion computer.
To fully test the provided patch, it is mandatory to use a Psion computer 
connected to a serial port.
I use a Psion S5mx, with serial port connections to amd64 64 bits systems and 
to i686 32 bits systems.

On my Debian 12 Bookworm systems, transfers from and to the Psion S5mx work 
correctly with the provided patch,
both on i686 32 bits systems and on amd64 64 bits systems.

Thanks !

-- System Information:
Debian Release: 12.8
  APT prefers stable-updates
  APT policy: (900, 'stable-updates'), (900, 'stable-security'), (900, 
'stable'), (300, 'stable-debug')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 6.1.0-28-amd64 (SMP w/8 CPU threads; PREEMPT)
Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8), 
LANGUAGE=fr:en_US
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages plptools depends on:
ii  debconf [debconf-2.0]      1.5.82
ii  fuse3 [fuse]               3.14.0-4
ii  libc6                      2.36-9+deb12u9
ii  libfuse2                   2.9.9-6+b1
ii  libgcc-s1                  12.2.0-14
ii  libreadline8               8.2-1.3
ii  libstdc++6                 12.2.0-14
ii  lsb-base                   11.6
ii  sysvinit-utils [lsb-base]  3.06-4

plptools recommends no packages.
plptools suggests no packages.

-- debconf information:
  plptools/customize:
  plptools/frontends/remoteaddr:
  plptools/plpprintd/start: false
  plptools/ncpd/start: true
  plptools/ncpd/listenat: 127.0.0.1
  plptools/ncpd/serial: /dev/ttyS0
  plptools/plpfuse/start: false
  plptools/plpprintd/printqueue: psion

Reply via email to