Bug 2214075

Summary: statserial can loop
Product: [Fedora] Fedora Reporter: Jaroslav Škarvada <jskarvad>
Component: statserialAssignee: Tim Waugh <twaugh>
Status: NEW --- QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: unspecified    
Version: 39CC: dmitry, twaugh
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Jaroslav Škarvada 2023-06-11 16:51:12 UTC
There is incorrect optimization in the code that relies on the fact that the TIOCMGET ioctl cannot get value 0 in the arg. It seems this may happen e.g. with the tty0tty null modem emulator, where the "arg == old_status" check is always true (because old_status is explicitly initialized to 0) causing statserial to loops even with the "-n" argument. I will PR workaround patch.

Reproducible: Always

Steps to Reproduce:
1. modprobe tty0tty
2. statserial -n /dev/tnt0
3.
Actual Results:  
It loops until serial status is changed.

Expected Results:  
It returns the status of the serial port.

Incorrect code:
  unsigned int old_status = 0;  /* value of previous call */
  unsigned int arg;             /* value returned by ioctl */
...
  for (;;) {
    /* get modem status info */
    status = ioctl(fd, TIOCMGET, &arg);
...
    /* avoid unneccessary screen updates */
    if (arg == old_status)
    {
      sleep(1);
      continue;
    }
    old_status = arg;
...
For "arg" being "0" we have the loop.

Strace:
openat(AT_FDCWD, "/dev/tnt1", O_RDONLY) = 3
ioctl(3, TIOCMGET, [0])                 = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=1, tv_nsec=0}, 0x7ffc316de900) = 0
ioctl(3, TIOCMGET, [0])                 = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=1, tv_nsec=0}, 0x7ffc316de900) = 0
ioctl(3, TIOCMGET, [0])                 = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=1, tv_nsec=0}, 0x7ffc316de900) = 0
...

Comment 1 Jaroslav Škarvada 2023-06-11 17:04:45 UTC
https://src.fedoraproject.org/rpms/statserial/pull-request/1

Comment 2 Fedora Release Engineering 2023-08-16 08:10:28 UTC
This bug appears to have been reported against 'rawhide' during the Fedora Linux 39 development cycle.
Changing version to 39.