about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2020-09-29 14:45:09 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2020-10-02 16:11:59 -0300
commitbe9b0b9a012780a403a266c90878efffb9a5f3ca (patch)
tree35bbc1910849c6687267b06b24b84373e48a832d /sysdeps/unix/sysv/linux
parent20a00dbefca5695cccaa44846a482db8ccdd85ab (diff)
downloadglibc-be9b0b9a012780a403a266c90878efffb9a5f3ca.tar.gz
glibc-be9b0b9a012780a403a266c90878efffb9a5f3ca.tar.xz
glibc-be9b0b9a012780a403a266c90878efffb9a5f3ca.zip
sysvipc: Return EINVAL for invalid msgctl commands
It avoids regressions on possible future commands that might require
additional libc support.  The downside is new commands added by newer
kernels will need further glibc support.

Checked on x86_64-linux-gnu and i686-linux-gnu (Linux v4.15 and v5.4).
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r--sysdeps/unix/sysv/linux/msgctl.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c
index a1f24ab242..f4493de573 100644
--- a/sysdeps/unix/sysv/linux/msgctl.c
+++ b/sysdeps/unix/sysv/linux/msgctl.c
@@ -88,25 +88,46 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
 {
 #if __IPC_TIME64
   struct kernel_msqid64_ds ksemid, *arg = NULL;
-  if (buf != NULL)
+#else
+  msgctl_arg_t *arg;
+#endif
+
+  switch (cmd)
     {
-      /* This is a Linux extension where kernel returns a 'struct msginfo'
-	 instead.  */
-      if (cmd == IPC_INFO || cmd == MSG_INFO)
-	arg = (struct kernel_msqid64_ds *) buf;
-      else
+    case IPC_RMID:
+      arg = NULL;
+      break;
+
+    case IPC_SET:
+    case IPC_STAT:
+    case MSG_STAT:
+    case MSG_STAT_ANY:
+#if __IPC_TIME64
+      if (buf != NULL)
 	{
 	  msqid64_to_kmsqid64 (buf, &ksemid);
 	  arg = &ksemid;
 	}
-    }
 # ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
-  if (cmd == IPC_SET)
-    arg->msg_perm.mode *= 0x10000U;
+      if (cmd == IPC_SET)
+	arg->msg_perm.mode *= 0x10000U;
 # endif
 #else
-  msgctl_arg_t *arg = buf;
+      arg = buf;
 #endif
+      break;
+
+    case IPC_INFO:
+    case MSG_INFO:
+      /* This is a Linux extension where kernel returns a 'struct msginfo'
+	 instead.  */
+      arg = (__typeof__ (arg)) buf;
+      break;
+
+    default:
+      __set_errno (EINVAL);
+      return -1;
+    }
 
   int ret = msgctl_syscall (msqid, cmd, arg);
   if (ret < 0)