Bug 26637

Summary: semctl SEM_STAT_ANY fails to pass the buffer specified by the caller to the kernel
Product: glibc Reporter: Dmitry V. Levin <ldv>
Component: libcAssignee: Adhemerval Zanella <adhemerval.zanella>
Status: RESOLVED FIXED    
Severity: normal CC: adhemerval.zanella, drepper.fsp, fweimer
Priority: P2 Flags: ldv: security-
Version: 2.32   
Target Milestone: 2.33   
See Also: https://bugzilla.redhat.com/show_bug.cgi?id=1912670
https://sourceware.org/bugzilla/show_bug.cgi?id=29771
Host: Target:
Build: Last reconfirmed:

Description Dmitry V. Levin 2020-09-20 00:41:37 UTC
The kernel receives garbage instead of union semun.buf address specified by the caller.

$ git --no-pager grep -wc SEM_STAT_ANY sysdeps/unix/sysv/linux/semctl.c
sysdeps/unix/sysv/linux/semctl.c:2
$ git --no-pager grep -wc SEM_STAT sysdeps/unix/sysv/linux/semctl.c
sysdeps/unix/sysv/linux/semctl.c:8

A tentative fix:

diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
index f131a26fc7..1cdabde8f2 100644
--- a/sysdeps/unix/sysv/linux/semctl.c
+++ b/sysdeps/unix/sysv/linux/semctl.c
@@ -102,6 +102,7 @@ semun64_to_ksemun64 (int cmd, union semun64 semun64,
       r.array = semun64.array;
       break;
     case SEM_STAT:
+    case SEM_STAT_ANY:
     case IPC_STAT:
     case IPC_SET:
       r.buf = buf;
@@ -150,6 +151,7 @@ __semctl64 (int semid, int semnum, int cmd, ...)
     case IPC_STAT:      /* arg.buf */
     case IPC_SET:
     case SEM_STAT:
+    case SEM_STAT_ANY:
     case IPC_INFO:      /* arg.__buf */
     case SEM_INFO:
       va_start (ap, cmd);
@@ -238,6 +240,7 @@ semun_to_semun64 (int cmd, union semun semun, struct __semid64_ds *semid64)
       r.array = semun.array;
       break;
     case SEM_STAT:
+    case SEM_STAT_ANY:
     case IPC_STAT:
     case IPC_SET:
       r.buf = semid64;
@@ -267,6 +270,7 @@ __semctl (int semid, int semnum, int cmd, ...)
     case IPC_STAT:      /* arg.buf */
     case IPC_SET:
     case SEM_STAT:
+    case SEM_STAT_ANY:
     case IPC_INFO:      /* arg.__buf */
     case SEM_INFO:
       va_start (ap, cmd);
@@ -321,6 +325,7 @@ __semctl_mode16 (int semid, int semnum, int cmd, ...)
     case IPC_STAT:      /* arg.buf */
     case IPC_SET:
     case SEM_STAT:
+    case SEM_STAT_ANY:
     case IPC_INFO:      /* arg.__buf */
     case SEM_INFO:
       va_start (ap, cmd);
@@ -354,6 +359,7 @@ __old_semctl (int semid, int semnum, int cmd, ...)
     case IPC_STAT:      /* arg.buf */
     case IPC_SET:
     case SEM_STAT:
+    case SEM_STAT_ANY:
     case IPC_INFO:      /* arg.__buf */
     case SEM_INFO:
       va_start (ap, cmd);
Comment 1 Adhemerval Zanella 2020-10-02 19:41:32 UTC
Fixed on 2.33 (574500a108be1d2a6a0dc97a075c9e0a98371aba)