glibc 2.32 leaks errno in sched_rr_get_interval fallback

Bug #1896281 reported by Balint Reczey
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GLibC
Invalid
Medium
glibc (Ubuntu)
Invalid
Low
Unassigned
Groovy
Invalid
Low
Unassigned
unhide (Ubuntu)
Fix Released
Undecided
Unassigned
Groovy
Fix Released
Undecided
Unassigned

Bug Description

root@autopkgtest-lxd-rygyvj:/tmp/autopkgtest.Pui0CD/build.uqw/src# strace ./a.out
execve("./a.out", ["./a.out"], 0xfff2c8a0 /* 12 vars */) = 0
brk(NULL) = 0x1942000
uname({sysname="Linux", nodename="autopkgtest-lxd-rygyvj", ...}) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=24113, ...}) = 0
mmap2(NULL, 24113, PROT_READ, MAP_PRIVATE, 3, 0) = 0xf78ec000
close(3) = 0
openat(AT_FDCWD, "/lib/arm-linux-gnueabihf/libc.so.6", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\t\261\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=988544, ...}) = 0
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf78ea000
mmap2(NULL, 1054788, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xf77c6000
mprotect(0xf78b3000, 61440, PROT_NONE) = 0
mmap2(0xf78c2000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xec000) = 0xf78c2000
mmap2(0xf78c6000, 6212, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xf78c6000
close(3) = 0
set_tls(0xf78eac90) = 0
mprotect(0xf78c2000, 8192, PROT_READ) = 0
mprotect(0x81b000, 4096, PROT_READ) = 0
mprotect(0xf78f2000, 4096, PROT_READ) = 0
munmap(0xf78ec000, 24113) = 0
sched_rr_get_interval_time64(1, 0xfff88678) = -1 ENOSYS (Function not implemented)
sched_rr_get_interval(1, {tv_sec=0, tv_nsec=0}) = 0
dup(2) = 3
fcntl64(3, F_GETFL) = 0x402 (flags O_RDWR|O_APPEND)
brk(NULL) = 0x1942000
brk(0x1963000) = 0x1963000
fstat64(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x3), ...}) = 0
write(3, "error: Function not implemented\n", 32error: Function not implemented
) = 32
close(3) = 0
exit_group(0) = ?
+++ exited with 0 +++
root@autopkgtest-lxd-rygyvj:/tmp/autopkgtest.Pui0CD/build.uqw/src# cat test.c
#include <stdio.h>
#include <errno.h>
#include <sched.h>
int main() {
  struct timespec tp;
  errno = 0;
  sched_rr_get_interval(1, &tp);
  perror("error");
  return 0;
}

When sched_rr_get_interval_time64 is not implemented glibc falls back to sched_rr_get_interval syscall but does not clear errno.

This breaks 'unhide quick' and a few other unhide commands giving false positives as a result.

The problem is observed only on armhf testbeds.

Balint Reczey (rbalint)
Changed in glibc (Ubuntu):
importance: Undecided → Critical
importance: Critical → Medium
Steve Langasek (vorlon)
Changed in unhide (Ubuntu Groovy):
milestone: none → ubuntu-20.10
Changed in glibc (Ubuntu Groovy):
milestone: none → ubuntu-20.10
Revision history for this message
Balint Reczey (rbalint) wrote :

vorlon | ok, agreed that it's not critical for glibc, feel free to untarget

Changed in glibc (Ubuntu Groovy):
milestone: ubuntu-20.10 → none
Changed in unhide (Ubuntu Groovy):
milestone: ubuntu-20.10 → none
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package unhide - 20130526-4ubuntu1

---------------
unhide (20130526-4ubuntu1) groovy; urgency=medium

  * Work around Glibc 2.32 leaking errno from sched_rr_get_interval when
    sched_rr_get_interval_time64 syscall is not implemented (LP: #1896281)

 -- Balint Reczey <email address hidden> Fri, 18 Sep 2020 22:57:25 +0200

Changed in unhide (Ubuntu Groovy):
status: New → Fix Released
Revision history for this message
In , Balint Reczey (rbalint) wrote :

When sched_rr_get_interval_time64 is not implemented glibc falls back to sched_rr_get_interval syscall but does not clear errno.

This breaks 'unhide quick' and a few other unhide commands giving false positives as a result.

The problem is observed only on armhf in Ubuntu CI.

https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1896281

test.c:
#include <stdio.h>
#include <errno.h>
#include <sched.h>
int main() {
  struct timespec tp;
  errno = 0;
  sched_rr_get_interval(1, &tp);
  perror("error");
  return 0;
}

strace ./a.out
...
sched_rr_get_interval_time64(1, 0xfff88678) = -1 ENOSYS (Function not implemented)
sched_rr_get_interval(1, {tv_sec=0, tv_nsec=0}) = 0
dup(2) = 3
fcntl64(3, F_GETFL) = 0x402 (flags O_RDWR|O_APPEND)
brk(NULL) = 0x1942000
brk(0x1963000) = 0x1963000
fstat64(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x3), ...}) = 0
write(3, "error: Function not implemented\n", 32error: Function not implemented
) = 32
...

...

Revision history for this message
In , Andreas Schwab (schwab-linux-m68k) wrote :

errno is only defined if sched_rr_get_interval returns -1.

Revision history for this message
In , Balint Reczey (rbalint) wrote :

root@gg-armhf:~# cat test.c
#include <stdio.h>
#include <errno.h>
#include <sched.h>
int main() {
  struct timespec tp;
  errno = 0;
  int ret = sched_rr_get_interval(1, &tp);
  printf("ret == %d\n", ret);
  perror("error");
  return 0;
}
root@gg-armhf:~# ./a.out
ret == 0
error: Function not implemented
root@gg-armhf:~#

Changed in glibc:
importance: Unknown → Medium
status: Unknown → Invalid
Revision history for this message
In , Adhemerval Zanella (adhemerval-zanella) wrote :

I think this is similar (In reply to Balint Reczey from comment #2)
> root@gg-armhf:~# cat test.c
> #include <stdio.h>
> #include <errno.h>
> #include <sched.h>
> int main() {
> struct timespec tp;
> errno = 0;
> int ret = sched_rr_get_interval(1, &tp);
> printf("ret == %d\n", ret);
> perror("error");
> return 0;
> }
> root@gg-armhf:~# ./a.out
> ret == 0
> error: Function not implemented
> root@gg-armhf:~#

The errno value after a successful call does not give you any meaningful information. But I think this is similar to the recent stat y2038 support where it triggered some invalid used within glibc itself. I think it would be better to use INTERNAL_SYSCALL_CALL in such cases and only sets the errno in case of failure.

Balint Reczey (rbalint)
Changed in glibc (Ubuntu):
importance: Medium → Low
Changed in glibc (Ubuntu Groovy):
importance: Medium → Low
Changed in glibc (Ubuntu):
status: New → Invalid
Changed in glibc (Ubuntu Groovy):
status: New → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.