public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637]
@ 2020-09-28 14:45 Adhemerval Zanella
  2020-09-28 14:45 ` [PATCH 2/6] sysvipc: Return EINVAL for invalid semctl commands Adhemerval Zanella
                   ` (5 more replies)
  0 siblings, 6 replies; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-28 14:45 UTC (permalink / raw)
  To: libc-alpha; +Cc: Dmitry V . Levin, Robert O'Callahan

From: "Dmitry V. Levin" <ldv@altlinux.org>

Handle SEM_STAT_ANY the same way as SEM_STAT so that the buffer argument
of SEM_STAT_ANY is properly passed to the kernel and back.

The regression testcase checks for Linux specifix SysV ipc message
control extension.  For IPC_INFO/SEM_INFO it tries to match the values
against the tunable /proc values and for SEM_STAT/SEM_STAT_ANY it
check if the create message queue is within the global list returned
by the kernel.

Checked on x86_64-linux-gnu and on i686-linux-gnu (Linux v5.4 and on
Linux v4.15).

Co-authored-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 sysdeps/unix/sysv/linux/Makefile            |   2 +-
 sysdeps/unix/sysv/linux/semctl.c            |   6 +
 sysdeps/unix/sysv/linux/tst-sysvsem-linux.c | 198 ++++++++++++++++++++
 sysvipc/test-sysvsem.c                      |   1 +
 4 files changed, 206 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/unix/sysv/linux/tst-sysvsem-linux.c

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 3bd3106ef9..4a4ed3cb5d 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -101,7 +101,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
 	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
 	 test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
 	 tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill \
-	 tst-tgkill
+	 tst-tgkill tst-sysvsem-linux
 tests-internal += tst-ofdlocks-compat tst-sigcontext-get_pc
 
 CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
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);
diff --git a/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c b/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c
new file mode 100644
index 0000000000..12a3946d98
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c
@@ -0,0 +1,198 @@
+/* Basic tests for Linux SYSV semaphore extensions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+/* These are for the temporary file we generate.  */
+static char *name;
+static int semid;
+
+static void
+remove_sem (void)
+{
+  /* Enforce message queue removal in case of early test failure.
+     Ignore error since the sem may already have being removed.  */
+  semctl (semid, 0, IPC_RMID, 0);
+}
+
+static void
+do_prepare (int argc, char *argv[])
+{
+  TEST_VERIFY_EXIT (create_temp_file ("tst-sysvsem.", &name) != -1);
+}
+
+#define PREPARE do_prepare
+
+#define SEM_MODE 0644
+
+union semun
+{
+  int val;
+  struct semid_ds *buf;
+  unsigned short  *array;
+  struct seminfo *__buf;
+};
+
+struct test_seminfo
+{
+  int semmsl;
+  int semmns;
+  int semopm;
+  int semmni;
+};
+
+/* It tries to obtain some system-wide SysV semaphore information from /proc
+   to check against IPC_INFO/SEM_INFO.  The /proc only returns the tunables
+   value of SEMMSL, SEMMNS, SEMOPM, and SEMMNI.
+
+   The kernel also returns constant value for SEMVMX, SEMMNU, SEMMAP, SEMUME,
+   and also SEMUSZ and SEMAEM (for IPC_INFO).  The issue to check them is they
+   might change over kernel releases.  */
+
+static bool
+read_sem_stat (struct test_seminfo *tseminfo)
+{
+  FILE *f = fopen ("/proc/sys/kernel/sem", "r");
+  if (f == NULL)
+    return false;
+
+  int r = fscanf (f, "%d %d %d %d",
+		  &tseminfo->semmsl, &tseminfo->semmns, &tseminfo->semopm,
+		  &tseminfo->semmni);
+  TEST_VERIFY_EXIT (r == 4);
+
+  fclose (f);
+
+  return 0;
+}
+
+
+/* Check if the semaphore with IDX (index into the kernel's internal array)
+   matches the one with KEY.  The CMD is either SEM_STAT or SEM_STAT_ANY.  */
+
+static bool
+check_seminfo (int idx, key_t key, int cmd)
+{
+  struct semid_ds seminfo;
+  int sid = semctl (idx, 0, cmd, (union semun) { .buf = &seminfo });
+  /* Ignore unused array slot returned by the kernel or information from
+     unknown semaphores.  */
+  if ((sid == -1 && errno == EINVAL) || sid != semid)
+    return false;
+
+  if (sid == -1)
+    FAIL_EXIT1 ("semctl with SEM_STAT failed (errno=%d)", errno);
+
+  if (seminfo.sem_perm.__key != key)
+    FAIL_EXIT1 ("semid_ds::sem_perm::key (%d) != %d",
+		(int) seminfo.sem_perm.__key, (int) key);
+  if (seminfo.sem_perm.mode != SEM_MODE)
+    FAIL_EXIT1 ("semid_ds::sem_perm::mode (%o) != %o",
+		seminfo.sem_perm.mode, SEM_MODE);
+  if (seminfo.sem_nsems != 1)
+    FAIL_EXIT1 ("semid_ds::sem_nsems (%lu) != 1",
+		(long unsigned) seminfo.sem_nsems);
+
+  return true;
+}
+
+static int
+do_test (void)
+{
+  atexit (remove_sem);
+
+  key_t key = ftok (name, 'G');
+  if (key == -1)
+    FAIL_EXIT1 ("ftok failed: %m");
+
+  semid = semget (key, 1, IPC_CREAT | IPC_EXCL | SEM_MODE);
+  if (semid == -1)
+    FAIL_EXIT1 ("semget failed: %m");
+
+  struct test_seminfo tipcinfo;
+  bool tipcget = read_sem_stat (&tipcinfo);
+
+  int semidx;
+
+  {
+    struct seminfo ipcinfo;
+    semidx = semctl (semid, 0, IPC_INFO, (union semun) { .__buf = &ipcinfo });
+    if (semidx == -1)
+      FAIL_EXIT1 ("semctl with IPC_INFO failed: %m");
+
+    /* We only check if /proc is mounted.  */
+    if (tipcget)
+      {
+	TEST_COMPARE (ipcinfo.semmsl, tipcinfo.semmsl);
+	TEST_COMPARE (ipcinfo.semmns, tipcinfo.semmns);
+	TEST_COMPARE (ipcinfo.semopm, tipcinfo.semopm);
+	TEST_COMPARE (ipcinfo.semmni, tipcinfo.semmni);
+      }
+  }
+
+  /* Same as before but with SEM_INFO.  */
+  {
+    struct seminfo ipcinfo;
+    semidx = semctl (semid, 0, SEM_INFO, (union semun) { .__buf = &ipcinfo });
+    if (semidx == -1)
+      FAIL_EXIT1 ("semctl with IPC_INFO failed: %m");
+
+    if (tipcget)
+      {
+	TEST_COMPARE (ipcinfo.semmsl, tipcinfo.semmsl);
+	TEST_COMPARE (ipcinfo.semmns, tipcinfo.semmns);
+	TEST_COMPARE (ipcinfo.semopm, tipcinfo.semopm);
+	TEST_COMPARE (ipcinfo.semmni, tipcinfo.semmni);
+      }
+  }
+
+  /* We check if the created semaphore shows in the system-wide status.  */
+  bool found = false;
+  for (int i = 0; i <= semidx; i++)
+    {
+      if (check_seminfo (i, key, SEM_STAT))
+	{
+	  found = true;
+	  break;
+	}
+
+      /* We can't tell apart if SEM_STAT_ANY is not supported (kernel older
+	 than 4.17) or if the index used is invalid.  So it just check if
+	 value returned from a valid call matches the created semaphore.  */
+      check_seminfo (i, key, SEM_STAT_ANY);
+    }
+
+  if (!found)
+    FAIL_EXIT1 ("semctl with SEM_STAT/SEM_STAT_ANY could not find the "
+		"created  semaphore");
+
+  if (semctl (semid, 0, IPC_RMID, 0) == -1)
+    FAIL_EXIT1 ("semctl failed: %m");
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysvipc/test-sysvsem.c b/sysvipc/test-sysvsem.c
index 01dbff343a..b7284e0b48 100644
--- a/sysvipc/test-sysvsem.c
+++ b/sysvipc/test-sysvsem.c
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
+#include <stdbool.h>
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/sem.h>
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 2/6] sysvipc: Return EINVAL for invalid semctl commands
  2020-09-28 14:45 [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] Adhemerval Zanella
@ 2020-09-28 14:45 ` Adhemerval Zanella
  2020-09-28 16:33   ` Florian Weimer
  2020-09-28 14:45 ` [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639] Adhemerval Zanella
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-28 14:45 UTC (permalink / raw)
  To: libc-alpha; +Cc: Dmitry V . Levin, Robert O'Callahan

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).
---
 sysdeps/unix/sysv/linux/semctl.c |  10 +++
 sysvipc/test-sysvipc.h           | 135 +++++++++++++++++++++++++++++++
 sysvipc/test-sysvsem.c           |   5 ++
 3 files changed, 150 insertions(+)
 create mode 100644 sysvipc/test-sysvipc.h

diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
index 1cdabde8f2..dcff6e691d 100644
--- a/sysdeps/unix/sysv/linux/semctl.c
+++ b/sysdeps/unix/sysv/linux/semctl.c
@@ -158,6 +158,15 @@ __semctl64 (int semid, int semnum, int cmd, ...)
       arg64 = va_arg (ap, union semun64);
       va_end (ap);
       break;
+    case IPC_RMID:      /* arg ignored. */
+    case GETNCNT:
+    case GETPID:
+    case GETVAL:
+    case GETZCNT:
+      break;
+    default:
+      __set_errno (EINVAL);
+      return -1;
     }
 
 #if __IPC_TIME64
@@ -277,6 +286,7 @@ __semctl (int semid, int semnum, int cmd, ...)
       arg = va_arg (ap, union semun);
       va_end (ap);
       break;
+    /* __semctl64 handles non-supported commands.  */
     }
 
   struct __semid64_ds semid64;
diff --git a/sysvipc/test-sysvipc.h b/sysvipc/test-sysvipc.h
new file mode 100644
index 0000000000..86aa8df83d
--- /dev/null
+++ b/sysvipc/test-sysvipc.h
@@ -0,0 +1,135 @@
+/* Basic definition for Sysv IPC test functions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _TEST_SYSV_H
+#define _TEST_SYSV_H
+
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/msg.h>
+#include <sys/shm.h>
+#include <include/array_length.h>
+
+/* Return the first invalid command SysV IPC command from common shared
+   between message queue, shared memory, and semaphore.  */
+static inline int
+first_common_invalid_cmd (void)
+{
+  const int common_cmds[] = {
+    IPC_RMID,
+    IPC_SET,
+    IPC_STAT,
+    IPC_INFO,
+  };
+
+  int invalid = 0;
+  for (int i = 0; i < array_length (common_cmds); i++)
+    {
+      if (invalid == common_cmds[i])
+	{
+	  invalid++;
+	  i = 0;
+        }
+    }
+
+  return invalid;
+}
+
+/* Return the first invalid command SysV IPC command for message queue.  */
+static inline int
+first_msg_invalid_cmd (void)
+{
+  const int msg_cmds[] = {
+    MSG_STAT,
+    MSG_INFO,
+#ifdef MSG_STAT_ANY
+    MSG_STAT_ANY,
+#endif
+  };
+
+  int invalid = first_common_invalid_cmd ();
+  for (int i = 0; i < array_length (msg_cmds); i++)
+    {
+      if (invalid == msg_cmds[i])
+	{
+	  invalid++;
+	  i = 0;
+	}
+    }
+
+  return invalid;
+}
+
+/* Return the first invalid command SysV IPC command for semaphore.  */
+static inline int
+first_sem_invalid_cmd (void)
+{
+  const int sem_cmds[] = {
+    GETPID,
+    GETVAL,
+    GETALL,
+    GETNCNT,
+    GETZCNT,
+    SETVAL,
+    SETALL,
+    SEM_STAT,
+    SEM_INFO,
+#ifdef SEM_STAT_ANY
+    SEM_STAT_ANY,
+#endif
+  };
+
+  int invalid = first_common_invalid_cmd ();
+  for (int i = 0; i < array_length (sem_cmds); i++)
+    {
+      if (invalid == sem_cmds[i])
+	{
+	  invalid++;
+	  i = 0;
+	}
+    }
+
+  return invalid;
+}
+
+/* Return the first invalid command SysV IPC command for shared memory.  */
+static inline int
+first_shm_invalid_cmd (void)
+{
+  const int shm_cmds[] = {
+    SHM_STAT,
+    SHM_INFO,
+#ifdef SHM_STAT_ANY
+    SHM_STAT_ANY,
+#endif
+  };
+
+  int invalid = first_common_invalid_cmd ();
+  for (int i = 0; i < array_length (shm_cmds); i++)
+    {
+      if (invalid == shm_cmds[i])
+	{
+	  invalid++;
+	  i = 0;
+	}
+    }
+
+  return invalid;
+}
+
+#endif /* _TEST_SYSV_H  */
diff --git a/sysvipc/test-sysvsem.c b/sysvipc/test-sysvsem.c
index b7284e0b48..61837d8f3d 100644
--- a/sysvipc/test-sysvsem.c
+++ b/sysvipc/test-sysvsem.c
@@ -25,6 +25,8 @@
 #include <sys/ipc.h>
 #include <sys/sem.h>
 
+#include <test-sysvipc.h>
+
 #include <support/support.h>
 #include <support/check.h>
 #include <support/temp_file.h>
@@ -80,6 +82,9 @@ do_test (void)
       FAIL_EXIT1 ("semget failed (errno=%d)", errno);
     }
 
+  TEST_COMPARE (semctl (semid, 0, first_sem_invalid_cmd (), NULL), -1);
+  TEST_COMPARE (errno, EINVAL);
+
   /* Get semaphore kernel information and do some sanity checks.  */
   struct semid_ds seminfo;
   if (semctl (semid, 0, IPC_STAT, (union semun) { .buf = &seminfo }) == -1)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639]
  2020-09-28 14:45 [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] Adhemerval Zanella
  2020-09-28 14:45 ` [PATCH 2/6] sysvipc: Return EINVAL for invalid semctl commands Adhemerval Zanella
@ 2020-09-28 14:45 ` Adhemerval Zanella
  2020-09-28 14:55   ` Andreas Schwab
  2020-09-29  7:57   ` Florian Weimer
  2020-09-28 14:45 ` [PATCH 4/6] sysvipc: Return EINVAL for invalid msgctl commands Adhemerval Zanella
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-28 14:45 UTC (permalink / raw)
  To: libc-alpha; +Cc: Dmitry V . Levin, Robert O'Callahan

Both commands are Linux exntesions where the third argument is a
'struct msginfo' instead of 'struct msqid_ds' and its information
does not contain any time related fields (so there is no need to
extra conversion for __IPC_TIME64.

The regression testcase checks for Linux specifix SysV ipc message
control extension.  For IPC_INFO/MSG_INFO it tries to match the values
against the tunable /proc values and for MSG_STAT/MSG_STAT_ANY it
check if the create message queue is within the global list returned
by the kernel.

Checked on x86_64-linux-gnu and on i686-linux-gnu (Linux v5.4 and on
Linux v4.15).
---
 sysdeps/unix/sysv/linux/Makefile            |   2 +-
 sysdeps/unix/sysv/linux/msgctl.c            |  22 ++-
 sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c | 203 ++++++++++++++++++++
 3 files changed, 222 insertions(+), 5 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 4a4ed3cb5d..a54eb75d74 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -101,7 +101,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
 	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
 	 test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
 	 tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill \
-	 tst-tgkill tst-sysvsem-linux
+	 tst-tgkill tst-sysvsem-linux tst-sysvmsg-linux
 tests-internal += tst-ofdlocks-compat tst-sigcontext-get_pc
 
 CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c
index 0776472d5e..a1f24ab242 100644
--- a/sysdeps/unix/sysv/linux/msgctl.c
+++ b/sysdeps/unix/sysv/linux/msgctl.c
@@ -90,8 +90,15 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
   struct kernel_msqid64_ds ksemid, *arg = NULL;
   if (buf != NULL)
     {
-      msqid64_to_kmsqid64 (buf, &ksemid);
-      arg = &ksemid;
+      /* 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
+	{
+	  msqid64_to_kmsqid64 (buf, &ksemid);
+	  arg = &ksemid;
+	}
     }
 # ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
   if (cmd == IPC_SET)
@@ -169,8 +176,15 @@ __msgctl (int msqid, int cmd, struct msqid_ds *buf)
   struct __msqid64_ds msqid64, *buf64 = NULL;
   if (buf != NULL)
     {
-      msqid_to_msqid64 (&msqid64, buf);
-      buf64 = &msqid64;
+      /* This is a Linux extension where kernel returns a 'struct msginfo'
+	 instead.  */
+      if (cmd == IPC_INFO || cmd == MSG_INFO)
+	buf64 = (struct __msqid64_ds *) buf;
+      else
+	{
+	  msqid_to_msqid64 (&msqid64, buf);
+	  buf64 = &msqid64;
+	}
     }
 
   int ret = __msgctl64 (msqid, cmd, buf64);
diff --git a/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c b/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c
new file mode 100644
index 0000000000..79a94b3d44
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c
@@ -0,0 +1,203 @@
+/* Basic tests for Linux SYSV message queue extensions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#define MSGQ_MODE 0644
+
+/* These are for the temporary file we generate.  */
+static char *name;
+static int msqid;
+
+static void
+remove_msq (void)
+{
+  /* Enforce message queue removal in case of early test failure.
+     Ignore error since the msg may already have being removed.  */
+  msgctl (msqid, IPC_RMID, NULL);
+}
+
+static void
+do_prepare (int argc, char *argv[])
+{
+  TEST_VERIFY_EXIT (create_temp_file ("tst-sysvmsg.", &name) != -1);
+}
+
+#define PREPARE do_prepare
+
+struct test_msginfo
+{
+  int msgmax;
+  int msgmnb;
+  int msgmni;
+};
+
+/* It tries to obtain some system-wide SysV messsage queue information from
+   /proc to check against IPC_INFO/MSG_INFO.  The /proc only returns the
+   tunables value of MSGMAX, MSGMNB, and MSGMNI.
+
+   The kernel also returns constant value for MSGSSZ, MSGSEG and also MSGMAP,
+   MSGPOOL, and MSGTQL (for IPC_INFO).  The issue to check them is they might
+   change over kernel releases.  */
+
+static int
+read_proc_file (const char *file)
+{
+  FILE *f = fopen (file, "r");
+  if (f == NULL)
+    return -1;
+
+  int v;
+  int r = fscanf (f, "%d", & v);
+  TEST_VERIFY_EXIT (r == 1);
+
+  fclose (f);
+  return v;
+}
+
+static bool
+read_msg_stat (struct test_msginfo *tmsginfo)
+{
+  tmsginfo->msgmax = read_proc_file ("/proc/sys/kernel/msgmax");
+  if (tmsginfo->msgmax == -1)
+    return false;
+  tmsginfo->msgmnb = read_proc_file ("/proc/sys/kernel/msgmnb");
+  if (tmsginfo->msgmnb == -1)
+    return false;
+  tmsginfo->msgmni = read_proc_file ("/proc/sys/kernel/msgmni");
+  if (tmsginfo->msgmni == -1)
+    return false;
+  return true;
+}
+
+
+/* Check if the message queue with IDX (index into the kernel's internal
+   array) matches the one with KEY.  The CMD is either MSG_STAT or
+   MSG_STAT_ANY.  */
+
+static bool
+check_msginfo (int idx, key_t key, int cmd)
+{
+  struct msqid_ds msginfo;
+  int mid = msgctl (idx, cmd, &msginfo);
+  /* Ignore unused array slot returned by the kernel or information from
+     unknown message queue.  */
+  if ((mid == -1 && errno == EINVAL) || mid != msqid)
+    return false;
+
+  if (mid == -1)
+    FAIL_EXIT1 ("msgctl with %s failed: %m",
+		cmd == MSG_STAT ? "MSG_STAT" : "MSG_STAT_ANY");
+
+  if (msginfo.msg_perm.__key != key)
+    FAIL_EXIT1 ("msgid_ds::msg_perm::key (%d) != %d",
+		(int) msginfo.msg_perm.__key, (int) key);
+  if (msginfo.msg_perm.mode != MSGQ_MODE)
+    FAIL_EXIT1 ("msgid_ds::msg_perm::mode (%o) != %o",
+		msginfo.msg_perm.mode, MSGQ_MODE);
+  if (msginfo.msg_qnum != 0)
+    FAIL_EXIT1 ("msgid_ds::msg_qnum (%lu) != 0",
+		(long unsigned) msginfo.msg_qnum);
+
+  return true;
+}
+
+static int
+do_test (void)
+{
+  atexit (remove_msq);
+
+  key_t key = ftok (name, 'G');
+  if (key == -1)
+    FAIL_EXIT1 ("ftok failed: %m");
+
+  msqid = msgget (key, MSGQ_MODE | IPC_CREAT);
+  if (msqid == -1)
+    FAIL_EXIT1 ("msgget failed: %m");
+
+  struct test_msginfo tipcinfo;
+  bool tipcget = read_msg_stat (&tipcinfo);
+
+  int msqidx;
+
+  {
+    struct msginfo ipcinfo;
+    msqidx = msgctl (msqid, IPC_INFO, (struct msqid_ds *) &ipcinfo);
+    if (msqidx == -1)
+      FAIL_EXIT1 ("msgctl with IPC_INFO failed: %m");
+
+    /* We only check if /proc is mounted.  */
+    if (tipcget)
+      {
+	TEST_COMPARE (ipcinfo.msgmax, tipcinfo.msgmax);
+	TEST_COMPARE (ipcinfo.msgmnb, tipcinfo.msgmnb);
+	TEST_COMPARE (ipcinfo.msgmni, tipcinfo.msgmni);
+      }
+  }
+
+  /* Same as before but with MSG_INFO.  */
+  {
+    struct msginfo ipcinfo;
+    msqidx = msgctl (msqid, MSG_INFO, (struct msqid_ds *) &ipcinfo);
+    if (msqidx == -1)
+      FAIL_EXIT1 ("msgctl with IPC_INFO failed: %m");
+
+    if (tipcget)
+      {
+	TEST_COMPARE (ipcinfo.msgmax, tipcinfo.msgmax);
+	TEST_COMPARE (ipcinfo.msgmnb, tipcinfo.msgmnb);
+	TEST_COMPARE (ipcinfo.msgmni, tipcinfo.msgmni);
+      }
+  }
+
+  /* We check if the created message queue shows in global list.  */
+  bool found = false;
+  for (int i = 0; i <= msqidx; i++)
+    {
+      if (check_msginfo (i, key, MSG_STAT))
+	{
+	  found = true;
+	  break;
+	}
+
+      /* We can't tell apart if MSG_STAT_ANY is not supported (kernel older
+	 than 4.17) or if the index used is invalid.  So it just check if the
+	 value returned from a valid call matches the created message
+	 queue.  */
+      check_msginfo (i, key, MSG_STAT_ANY);
+    }
+
+  if (!found)
+    FAIL_EXIT1 ("msgctl with MSG_STAT/MSG_STAT_ANY could not find the "
+		"created message queue");
+
+  if (msgctl (msqid, IPC_RMID, NULL) == -1)
+    FAIL_EXIT1 ("msgctl failed");
+
+  return 0;
+}
+
+#include <support/test-driver.c>
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 4/6] sysvipc: Return EINVAL for invalid msgctl commands
  2020-09-28 14:45 [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] Adhemerval Zanella
  2020-09-28 14:45 ` [PATCH 2/6] sysvipc: Return EINVAL for invalid semctl commands Adhemerval Zanella
  2020-09-28 14:45 ` [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639] Adhemerval Zanella
@ 2020-09-28 14:45 ` Adhemerval Zanella
  2020-09-29  7:58   ` Florian Weimer
  2020-09-28 14:45 ` [PATCH 5/6] sysvipc: Fix IPC_INFO and SHM_INFO handling [BZ #26636] Adhemerval Zanella
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-28 14:45 UTC (permalink / raw)
  To: libc-alpha; +Cc: Dmitry V . Levin, Robert O'Callahan

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).
---
 sysdeps/unix/sysv/linux/msgctl.c | 40 ++++++++++++++++++++++++--------
 sysvipc/test-sysvmsg.c           |  5 ++++
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c
index a1f24ab242..5a5e7482f2 100644
--- a/sysdeps/unix/sysv/linux/msgctl.c
+++ b/sysdeps/unix/sysv/linux/msgctl.c
@@ -88,25 +88,45 @@ __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:
+#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)
diff --git a/sysvipc/test-sysvmsg.c b/sysvipc/test-sysvmsg.c
index 84efdade5e..ada2881065 100644
--- a/sysvipc/test-sysvmsg.c
+++ b/sysvipc/test-sysvmsg.c
@@ -24,6 +24,8 @@
 #include <sys/ipc.h>
 #include <sys/msg.h>
 
+#include <test-sysvipc.h>
+
 #include <support/support.h>
 #include <support/check.h>
 #include <support/temp_file.h>
@@ -86,6 +88,9 @@ do_test (void)
       FAIL_EXIT1 ("msgget failed (errno=%d)", errno);
     }
 
+  TEST_COMPARE (msgctl (msqid, first_msg_invalid_cmd (), NULL), -1);
+  TEST_COMPARE (errno, EINVAL);
+
   /* Get message queue kernel information and do some sanity checks.  */
   struct msqid_ds msginfo;
   if (msgctl (msqid, IPC_STAT, &msginfo) == -1)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 5/6] sysvipc: Fix IPC_INFO and SHM_INFO handling [BZ #26636]
  2020-09-28 14:45 [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2020-09-28 14:45 ` [PATCH 4/6] sysvipc: Return EINVAL for invalid msgctl commands Adhemerval Zanella
@ 2020-09-28 14:45 ` Adhemerval Zanella
  2020-09-28 14:45 ` [PATCH 6/6] sysvipc: Return EINVAL for invalid shmctl commands Adhemerval Zanella
  2020-09-28 14:59 ` [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] Florian Weimer
  5 siblings, 0 replies; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-28 14:45 UTC (permalink / raw)
  To: libc-alpha; +Cc: Dmitry V . Levin, Robert O'Callahan

Both commands are Linux extensions where the third argument is either
a 'struct shminfo' (IPC_INFO) or a 'struct shm_info' (SHM_INFO) instead
of 'struct shmid_ds'.  And their information does not contain any time
related fields, so there is no need to extra conversion for __IPC_TIME64.

The regression testcase checks for Linux specifix SysV ipc message
control extension.  For SHM_INFO it tries to match the values against the
tunable /proc values and for MSG_STAT/MSG_STAT_ANY it check if the create\
shared memory is within the global list returned by the kernel.

Checked on x86_64-linux-gnu and on i686-linux-gnu (Linux v5.4 and on
Linux v4.15).
---
 sysdeps/unix/sysv/linux/Makefile            |   2 +-
 sysdeps/unix/sysv/linux/shmctl.c            |  24 ++-
 sysdeps/unix/sysv/linux/tst-sysvshm-linux.c | 195 ++++++++++++++++++++
 3 files changed, 214 insertions(+), 7 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/tst-sysvshm-linux.c

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index a54eb75d74..5a78614457 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -101,7 +101,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
 	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
 	 test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
 	 tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill \
-	 tst-tgkill tst-sysvsem-linux tst-sysvmsg-linux
+	 tst-tgkill tst-sysvsem-linux tst-sysvmsg-linux tst-sysvshm-linux
 tests-internal += tst-ofdlocks-compat tst-sigcontext-get_pc
 
 CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c
index 76d88441f1..1d19a798b1 100644
--- a/sysdeps/unix/sysv/linux/shmctl.c
+++ b/sysdeps/unix/sysv/linux/shmctl.c
@@ -90,8 +90,15 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
   struct kernel_shmid64_ds kshmid, *arg = NULL;
   if (buf != NULL)
     {
-      shmid64_to_kshmid64 (buf, &kshmid);
-      arg = &kshmid;
+      /* This is a Linux extension where kernel expects either a
+	 'struct shminfo' (IPC_INFO) or 'struct shm_info' (SHM_INFO).  */
+      if (cmd == IPC_INFO || cmd == SHM_INFO)
+	arg = (struct kernel_shmid64_ds *) buf;
+      else
+	{
+	  shmid64_to_kshmid64 (buf, &kshmid);
+	  arg = &kshmid;
+	}
     }
 # ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
   if (cmd == IPC_SET)
@@ -107,7 +114,6 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
 
   switch (cmd)
     {
-      case IPC_INFO:
       case IPC_STAT:
       case SHM_STAT:
       case SHM_STAT_ANY:
@@ -168,8 +174,15 @@ __shmctl (int shmid, int cmd, struct shmid_ds *buf)
   struct __shmid64_ds shmid64, *buf64 = NULL;
   if (buf != NULL)
     {
-      shmid_to_shmid64 (&shmid64, buf);
-      buf64 = &shmid64;
+      /* This is a Linux extension where kernel expects either a
+	 'struct shminfo' (IPC_INFO) or 'struct shm_info' (SHM_INFO).  */
+      if (cmd == IPC_INFO || cmd == SHM_INFO)
+	buf64 = (struct __shmid64_ds *) buf;
+      else
+	{
+	  shmid_to_shmid64 (&shmid64, buf);
+	  buf64 = &shmid64;
+	}
     }
 
   int ret = __shmctl64 (shmid, cmd, buf64);
@@ -178,7 +191,6 @@ __shmctl (int shmid, int cmd, struct shmid_ds *buf)
 
   switch (cmd)
     {
-      case IPC_INFO:
       case IPC_STAT:
       case SHM_STAT:
       case SHM_STAT_ANY:
diff --git a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c
new file mode 100644
index 0000000000..0e89b5eeff
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c
@@ -0,0 +1,195 @@
+/* Basic tests for Linux SYSV shared memory extensions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#define SHM_MODE 0644
+
+/* These are for the temporary file we generate.  */
+static char *name;
+static int shmid;
+static long int pgsz;
+
+static void
+remove_shm (void)
+{
+  /* Enforce message queue removal in case of early test failure.
+     Ignore error since the shm may already have being removed.  */
+  shmctl (shmid, IPC_RMID, NULL);
+}
+
+static void
+do_prepare (int argc, char *argv[])
+{
+  TEST_VERIFY_EXIT (create_temp_file ("tst-sysvshm.", &name) != -1);
+}
+
+#define PREPARE do_prepare
+
+struct test_shminfo
+{
+  unsigned long shmall;
+  unsigned long shmmax;
+  unsigned long shmmni;
+};
+
+/* It tries to obtain some system-wide SysV shared memory information from
+   /proc to check against IPC_INFO/SHM_INFO.  The /proc only returns the
+   tunables value of SHMALL, SHMMAX, and SHMMNI.  */
+
+static unsigned long
+read_proc_file (const char *file)
+{
+  FILE *f = fopen (file, "r");
+  if (f == NULL)
+    return -1;
+
+  unsigned long v;
+  int r = fscanf (f, "%lu", & v);
+  TEST_VERIFY_EXIT (r == 1);
+
+  fclose (f);
+  return v;
+}
+
+static bool
+read_shm_stat (struct test_shminfo *tipcinfo)
+{
+  tipcinfo->shmall = read_proc_file ("/proc/sys/kernel/shmall");
+  if (tipcinfo->shmall == -1)
+    return false;
+  tipcinfo->shmmax = read_proc_file ("/proc/sys/kernel/shmmax");
+  if (tipcinfo->shmmax == -1)
+    return false;
+  tipcinfo->shmmni = read_proc_file ("/proc/sys/kernel/shmmni");
+  if (tipcinfo->shmmni == -1)
+    return false;
+  return true;
+}
+
+
+/* Check if the message queue with IDX (index into the kernel's internal
+   array) matches the one with KEY.  The CMD is either SHM_STAT or
+   SHM_STAT_ANY.  */
+
+static bool
+check_shminfo (int idx, key_t key, int cmd)
+{
+  struct shmid_ds shminfo;
+  int sid = shmctl (idx, cmd, &shminfo);
+  /* Ignore unused array slot returned by the kernel or information from
+     unknown message queue.  */
+  if ((sid == -1 && errno == EINVAL) || sid != shmid)
+    return false;
+
+  if (sid == -1)
+    FAIL_EXIT1 ("shmctl with %s failed: %m",
+		cmd == SHM_STAT ? "SHM_STAT" : "SHM_STAT_ANY");
+
+  if (shminfo.shm_perm.__key != key)
+    FAIL_EXIT1 ("shmid_ds::shm_perm::key (%d) != %d",
+		(int) shminfo.shm_perm.__key, (int) key);
+  if (shminfo.shm_perm.mode != SHM_MODE)
+    FAIL_EXIT1 ("shmid_ds::shm_perm::mode (%o) != %o",
+		shminfo.shm_perm.mode, SHM_MODE);
+  if (shminfo.shm_segsz != pgsz)
+    FAIL_EXIT1 ("shmid_ds::shm_segsz (%lu) != %lu",
+		(long unsigned) shminfo.shm_segsz, pgsz);
+
+  return true;
+}
+
+static int
+do_test (void)
+{
+  atexit (remove_shm);
+
+  pgsz = sysconf (_SC_PAGESIZE);
+  if (pgsz == -1)
+    FAIL_EXIT1 ("sysconf (_SC_PAGESIZE) failed: %m");
+
+  key_t key = ftok (name, 'G');
+  if (key == -1)
+    FAIL_EXIT1 ("ftok failed: %m");
+
+  shmid = shmget (key, pgsz, IPC_CREAT | IPC_EXCL | SHM_MODE);
+  if (shmid == -1)
+    FAIL_EXIT1 ("shmget failed: %m");
+
+  struct test_shminfo tipcinfo;
+  bool tipcget = read_shm_stat (&tipcinfo);
+
+  int shmidx;
+
+  /* Note: SHM_INFO does not return a shminfo, but rather a 'struct shm_info'
+     and it is tricky to verify it since it returns system resources consumed
+     by shared memory.  The shmctl implementation handles SHM_INFO as
+     IPC_INFO, so the IPC_INFO test should validate SHM_INFO as well.  */
+
+  {
+    struct shminfo ipcinfo;
+    shmidx = shmctl (shmid, IPC_INFO, (struct shmid_ds *) &ipcinfo);
+    if (shmidx == -1)
+      FAIL_EXIT1 ("shmctl with IPC_INFO failed: %m");
+
+    /* We only check if /proc is mounted.  */
+    if (tipcget)
+      {
+	TEST_COMPARE (ipcinfo.shmall, tipcinfo.shmall);
+	TEST_COMPARE (ipcinfo.shmmax, tipcinfo.shmmax);
+	TEST_COMPARE (ipcinfo.shmmni, tipcinfo.shmmni);
+      }
+  }
+
+  /* We check if the created shared memory shows in the global list.  */
+  bool found = false;
+  for (int i = 0; i <= shmidx; i++)
+    {
+      if (check_shminfo (i, key, SHM_STAT))
+	{
+	  found = true;
+	  break;
+	}
+
+      /* We can't tell apart if SHM_STAT_ANY is not supported (kernel older
+	 than 4.17) or if the index used is invalid.  So it just check if
+	 value returned from a valid call matches the created message
+	 queue.  */
+      check_shminfo (i, key, SHM_STAT_ANY);
+    }
+
+  if (!found)
+    FAIL_EXIT1 ("shmctl with SHM_STAT/SHM_STAT_ANY could not find the "
+		"created shared memory");
+
+  if (shmctl (shmid, IPC_RMID, NULL) == -1)
+    FAIL_EXIT1 ("shmctl failed");
+
+  return 0;
+}
+
+#include <support/test-driver.c>
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 6/6] sysvipc: Return EINVAL for invalid shmctl commands
  2020-09-28 14:45 [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2020-09-28 14:45 ` [PATCH 5/6] sysvipc: Fix IPC_INFO and SHM_INFO handling [BZ #26636] Adhemerval Zanella
@ 2020-09-28 14:45 ` Adhemerval Zanella
  2020-09-28 14:59 ` [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] Florian Weimer
  5 siblings, 0 replies; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-28 14:45 UTC (permalink / raw)
  To: libc-alpha; +Cc: Dmitry V . Levin, Robert O'Callahan

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).
---
 sysdeps/unix/sysv/linux/shmctl.c | 41 ++++++++++++++++++++++++--------
 sysvipc/test-sysvshm.c           |  5 ++++
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c
index 1d19a798b1..98eae91482 100644
--- a/sysdeps/unix/sysv/linux/shmctl.c
+++ b/sysdeps/unix/sysv/linux/shmctl.c
@@ -88,25 +88,46 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
 {
 #if __IPC_TIME64
   struct kernel_shmid64_ds kshmid, *arg = NULL;
-  if (buf != NULL)
+#else
+  shmctl_arg_t *arg;
+#endif
+
+  switch (cmd)
     {
-      /* This is a Linux extension where kernel expects either a
-	 'struct shminfo' (IPC_INFO) or 'struct shm_info' (SHM_INFO).  */
-      if (cmd == IPC_INFO || cmd == SHM_INFO)
-	arg = (struct kernel_shmid64_ds *) buf;
-      else
+    case IPC_RMID:
+      arg = NULL;
+      break;
+
+    case IPC_SET:
+    case IPC_STAT:
+    case SHM_STAT:
+#if __IPC_TIME64
+      if (buf != NULL)
 	{
 	  shmid64_to_kshmid64 (buf, &kshmid);
 	  arg = &kshmid;
 	}
-    }
 # ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
-  if (cmd == IPC_SET)
-    arg->shm_perm.mode *= 0x10000U;
+      if (cmd == IPC_SET)
+        arg->msg_perm.mode *= 0x10000U;
 # endif
 #else
-  shmctl_arg_t *arg = buf;
+      arg = buf;
 #endif
+      break;
+
+    case IPC_INFO:
+    case SHM_INFO:
+      /* This is a Linux extension where kernel expects either a
+	 'struct shminfo' (IPC_INFO) or 'struct shm_info' (SHM_INFO).  */
+      arg = (__typeof__ (arg)) buf;
+      break;
+
+    default:
+      __set_errno (EINVAL);
+      return -1;
+    }
+
 
   int ret = shmctl_syscall (shmid, cmd, arg);
   if (ret < 0)
diff --git a/sysvipc/test-sysvshm.c b/sysvipc/test-sysvshm.c
index f083fd280b..a1b8b4823e 100644
--- a/sysvipc/test-sysvshm.c
+++ b/sysvipc/test-sysvshm.c
@@ -25,6 +25,8 @@
 #include <sys/ipc.h>
 #include <sys/shm.h>
 
+#include <test-sysvipc.h>
+
 #include <support/support.h>
 #include <support/check.h>
 #include <support/temp_file.h>
@@ -81,6 +83,9 @@ do_test (void)
       FAIL_EXIT1 ("shmget failed (errno=%d)", errno);
     }
 
+  TEST_COMPARE (shmctl (shmid, first_shm_invalid_cmd (), NULL), -1);
+  TEST_COMPARE (errno, EINVAL);
+
   /* Get shared memory kernel information and do some sanity checks.  */
   struct shmid_ds shminfo;
   if (shmctl (shmid, IPC_STAT, &shminfo) == -1)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639]
  2020-09-28 14:45 ` [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639] Adhemerval Zanella
@ 2020-09-28 14:55   ` Andreas Schwab
  2020-09-29  7:57   ` Florian Weimer
  1 sibling, 0 replies; 19+ messages in thread
From: Andreas Schwab @ 2020-09-28 14:55 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha
  Cc: Adhemerval Zanella, Robert O'Callahan, Dmitry V . Levin

On Sep 28 2020, Adhemerval Zanella via Libc-alpha wrote:

> Both commands are Linux exntesions where the third argument is a

                          extensions

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637]
  2020-09-28 14:45 [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] Adhemerval Zanella
                   ` (4 preceding siblings ...)
  2020-09-28 14:45 ` [PATCH 6/6] sysvipc: Return EINVAL for invalid shmctl commands Adhemerval Zanella
@ 2020-09-28 14:59 ` Florian Weimer
  2020-09-28 21:06   ` Adhemerval Zanella
  5 siblings, 1 reply; 19+ messages in thread
From: Florian Weimer @ 2020-09-28 14:59 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha
  Cc: Adhemerval Zanella, Robert O'Callahan, Dmitry V . Levin

* Adhemerval Zanella via Libc-alpha:

> +/* Check if the semaphore with IDX (index into the kernel's internal array)
> +   matches the one with KEY.  The CMD is either SEM_STAT or SEM_STAT_ANY.  */
> +
> +static bool
> +check_seminfo (int idx, key_t key, int cmd)
> +{
> +  struct semid_ds seminfo;
> +  int sid = semctl (idx, 0, cmd, (union semun) { .buf = &seminfo });
> +  /* Ignore unused array slot returned by the kernel or information from
> +     unknown semaphores.  */
> +  if ((sid == -1 && errno == EINVAL) || sid != semid)
> +    return false;
> +
> +  if (sid == -1)
> +    FAIL_EXIT1 ("semctl with SEM_STAT failed (errno=%d)", errno);
> +
> +  if (seminfo.sem_perm.__key != key)
> +    FAIL_EXIT1 ("semid_ds::sem_perm::key (%d) != %d",
> +		(int) seminfo.sem_perm.__key, (int) key);
> +  if (seminfo.sem_perm.mode != SEM_MODE)
> +    FAIL_EXIT1 ("semid_ds::sem_perm::mode (%o) != %o",
> +		seminfo.sem_perm.mode, SEM_MODE);
> +  if (seminfo.sem_nsems != 1)
> +    FAIL_EXIT1 ("semid_ds::sem_nsems (%lu) != 1",
> +		(long unsigned) seminfo.sem_nsems);
> +
> +  return true;
> +}

Did you mean to include idx in the FAIL_EXIT1 output?  Otherwise you
could use TEST_COMPARE here?

> diff --git a/sysvipc/test-sysvsem.c b/sysvipc/test-sysvsem.c
> index 01dbff343a..b7284e0b48 100644
> --- a/sysvipc/test-sysvsem.c
> +++ b/sysvipc/test-sysvsem.c
> @@ -20,6 +20,7 @@
>  #include <stdlib.h>
>  #include <errno.h>
>  #include <string.h>
> +#include <stdbool.h>
>  #include <sys/types.h>
>  #include <sys/ipc.h>
>  #include <sys/sem.h>

Stray change?

Rest looks okay to me.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/6] sysvipc: Return EINVAL for invalid semctl commands
  2020-09-28 14:45 ` [PATCH 2/6] sysvipc: Return EINVAL for invalid semctl commands Adhemerval Zanella
@ 2020-09-28 16:33   ` Florian Weimer
  2020-09-28 21:07     ` Adhemerval Zanella
  0 siblings, 1 reply; 19+ messages in thread
From: Florian Weimer @ 2020-09-28 16:33 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha
  Cc: Adhemerval Zanella, Robert O'Callahan, Dmitry V . Levin

* Adhemerval Zanella via Libc-alpha:

> diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
> index 1cdabde8f2..dcff6e691d 100644
> --- a/sysdeps/unix/sysv/linux/semctl.c
> +++ b/sysdeps/unix/sysv/linux/semctl.c
> @@ -158,6 +158,15 @@ __semctl64 (int semid, int semnum, int cmd, ...)
>        arg64 = va_arg (ap, union semun64);
>        va_end (ap);
>        break;
> +    case IPC_RMID:      /* arg ignored. */

Missing space after “.”.

> +/* Return the first invalid command SysV IPC command for shared memory.  */
> +static inline int
> +first_shm_invalid_cmd (void)
> +{
> +  const int shm_cmds[] = {
> +    SHM_STAT,
> +    SHM_INFO,
> +#ifdef SHM_STAT_ANY
> +    SHM_STAT_ANY,
> +#endif
> +  };
> +
> +  int invalid = first_common_invalid_cmd ();
> +  for (int i = 0; i < array_length (shm_cmds); i++)
> +    {
> +      if (invalid == shm_cmds[i])
> +	{
> +	  invalid++;
> +	  i = 0;
> +	}
> +    }
> +
> +  return invalid;
> +}

I think this change should go into the shmctl patch?  Maybe add the
tests separately at the end? 

Rest looks okay to me.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637]
  2020-09-28 14:59 ` [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] Florian Weimer
@ 2020-09-28 21:06   ` Adhemerval Zanella
  0 siblings, 0 replies; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-28 21:06 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha
  Cc: Robert O'Callahan, Dmitry V . Levin



On 28/09/2020 11:59, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> +/* Check if the semaphore with IDX (index into the kernel's internal array)
>> +   matches the one with KEY.  The CMD is either SEM_STAT or SEM_STAT_ANY.  */
>> +
>> +static bool
>> +check_seminfo (int idx, key_t key, int cmd)
>> +{
>> +  struct semid_ds seminfo;
>> +  int sid = semctl (idx, 0, cmd, (union semun) { .buf = &seminfo });
>> +  /* Ignore unused array slot returned by the kernel or information from
>> +     unknown semaphores.  */
>> +  if ((sid == -1 && errno == EINVAL) || sid != semid)
>> +    return false;
>> +
>> +  if (sid == -1)
>> +    FAIL_EXIT1 ("semctl with SEM_STAT failed (errno=%d)", errno);
>> +
>> +  if (seminfo.sem_perm.__key != key)
>> +    FAIL_EXIT1 ("semid_ds::sem_perm::key (%d) != %d",
>> +		(int) seminfo.sem_perm.__key, (int) key);
>> +  if (seminfo.sem_perm.mode != SEM_MODE)
>> +    FAIL_EXIT1 ("semid_ds::sem_perm::mode (%o) != %o",
>> +		seminfo.sem_perm.mode, SEM_MODE);
>> +  if (seminfo.sem_nsems != 1)
>> +    FAIL_EXIT1 ("semid_ds::sem_nsems (%lu) != 1",
>> +		(long unsigned) seminfo.sem_nsems);
>> +
>> +  return true;
>> +}
> 
> Did you mean to include idx in the FAIL_EXIT1 output?  Otherwise you
> could use TEST_COMPARE here?

Not really, I have changed to use TEST_COMPARE.

> 
>> diff --git a/sysvipc/test-sysvsem.c b/sysvipc/test-sysvsem.c
>> index 01dbff343a..b7284e0b48 100644
>> --- a/sysvipc/test-sysvsem.c
>> +++ b/sysvipc/test-sysvsem.c
>> @@ -20,6 +20,7 @@
>>  #include <stdlib.h>
>>  #include <errno.h>
>>  #include <string.h>
>> +#include <stdbool.h>
>>  #include <sys/types.h>
>>  #include <sys/ipc.h>
>>  #include <sys/sem.h>
> 
> Stray change?

Yes, I removed it.

> 
> Rest looks okay to me.

Thanks.

> 
> Thanks,
> Florian
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/6] sysvipc: Return EINVAL for invalid semctl commands
  2020-09-28 16:33   ` Florian Weimer
@ 2020-09-28 21:07     ` Adhemerval Zanella
  0 siblings, 0 replies; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-28 21:07 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha
  Cc: Robert O'Callahan, Dmitry V . Levin



On 28/09/2020 13:33, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
>> index 1cdabde8f2..dcff6e691d 100644
>> --- a/sysdeps/unix/sysv/linux/semctl.c
>> +++ b/sysdeps/unix/sysv/linux/semctl.c
>> @@ -158,6 +158,15 @@ __semctl64 (int semid, int semnum, int cmd, ...)
>>        arg64 = va_arg (ap, union semun64);
>>        va_end (ap);
>>        break;
>> +    case IPC_RMID:      /* arg ignored. */
> 
> Missing space after “.”.

Ack.

> 
>> +/* Return the first invalid command SysV IPC command for shared memory.  */
>> +static inline int
>> +first_shm_invalid_cmd (void)
>> +{
>> +  const int shm_cmds[] = {
>> +    SHM_STAT,
>> +    SHM_INFO,
>> +#ifdef SHM_STAT_ANY
>> +    SHM_STAT_ANY,
>> +#endif
>> +  };
>> +
>> +  int invalid = first_common_invalid_cmd ();
>> +  for (int i = 0; i < array_length (shm_cmds); i++)
>> +    {
>> +      if (invalid == shm_cmds[i])
>> +	{
>> +	  invalid++;
>> +	  i = 0;
>> +	}
>> +    }
>> +
>> +  return invalid;
>> +}
> 
> I think this change should go into the shmctl patch?  Maybe add the
> tests separately at the end? 

Ok, I move each first_*_invalid_cmd to its own patch.

> 
> Rest looks okay to me.
> 
> Thanks,
> Florian
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639]
  2020-09-28 14:45 ` [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639] Adhemerval Zanella
  2020-09-28 14:55   ` Andreas Schwab
@ 2020-09-29  7:57   ` Florian Weimer
  2020-09-29 12:37     ` Adhemerval Zanella
  1 sibling, 1 reply; 19+ messages in thread
From: Florian Weimer @ 2020-09-29  7:57 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha
  Cc: Adhemerval Zanella, Robert O'Callahan, Dmitry V . Levin

* Adhemerval Zanella via Libc-alpha:

> +static int
> +read_proc_file (const char *file)
> +{
> +  FILE *f = fopen (file, "r");
> +  if (f == NULL)
> +    return -1;
> +
> +  int v;
> +  int r = fscanf (f, "%d", & v);
> +  TEST_VERIFY_EXIT (r == 1);
> +
> +  fclose (f);
> +  return v;
> +}

You could use xfopen and xfclose.

> +/* Check if the message queue with IDX (index into the kernel's internal
> +   array) matches the one with KEY.  The CMD is either MSG_STAT or
> +   MSG_STAT_ANY.  */
> +
> +static bool
> +check_msginfo (int idx, key_t key, int cmd)
> +{
> +  struct msqid_ds msginfo;
> +  int mid = msgctl (idx, cmd, &msginfo);
> +  /* Ignore unused array slot returned by the kernel or information from
> +     unknown message queue.  */
> +  if ((mid == -1 && errno == EINVAL) || mid != msqid)
> +    return false;
> +
> +  if (mid == -1)
> +    FAIL_EXIT1 ("msgctl with %s failed: %m",
> +		cmd == MSG_STAT ? "MSG_STAT" : "MSG_STAT_ANY");
> +
> +  if (msginfo.msg_perm.__key != key)
> +    FAIL_EXIT1 ("msgid_ds::msg_perm::key (%d) != %d",
> +		(int) msginfo.msg_perm.__key, (int) key);
> +  if (msginfo.msg_perm.mode != MSGQ_MODE)
> +    FAIL_EXIT1 ("msgid_ds::msg_perm::mode (%o) != %o",
> +		msginfo.msg_perm.mode, MSGQ_MODE);
> +  if (msginfo.msg_qnum != 0)
> +    FAIL_EXIT1 ("msgid_ds::msg_qnum (%lu) != 0",
> +		(long unsigned) msginfo.msg_qnum);

As in the other patch, you might want to use TEST_COMPARE here.

Rest looks okay, I think.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 4/6] sysvipc: Return EINVAL for invalid msgctl commands
  2020-09-28 14:45 ` [PATCH 4/6] sysvipc: Return EINVAL for invalid msgctl commands Adhemerval Zanella
@ 2020-09-29  7:58   ` Florian Weimer
  2020-09-29 13:26     ` Adhemerval Zanella
  0 siblings, 1 reply; 19+ messages in thread
From: Florian Weimer @ 2020-09-29  7:58 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha
  Cc: Adhemerval Zanella, Robert O'Callahan, Dmitry V . Levin

* Adhemerval Zanella via Libc-alpha:

> 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.

Looks okay to me for now.

I think eventually we need to rethink what we want to do about these,
for the architectures that don't need translation.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639]
  2020-09-29  7:57   ` Florian Weimer
@ 2020-09-29 12:37     ` Adhemerval Zanella
  2020-09-29 12:58       ` Adhemerval Zanella
  0 siblings, 1 reply; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-29 12:37 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha
  Cc: Robert O'Callahan, Dmitry V . Levin



On 29/09/2020 04:57, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> +static int
>> +read_proc_file (const char *file)
>> +{
>> +  FILE *f = fopen (file, "r");
>> +  if (f == NULL)
>> +    return -1;
>> +
>> +  int v;
>> +  int r = fscanf (f, "%d", & v);
>> +  TEST_VERIFY_EXIT (r == 1);
>> +
>> +  fclose (f);
>> +  return v;
>> +}
> 
> You could use xfopen and xfclose.

Indeed, I will change it.

> 
>> +/* Check if the message queue with IDX (index into the kernel's internal
>> +   array) matches the one with KEY.  The CMD is either MSG_STAT or
>> +   MSG_STAT_ANY.  */
>> +
>> +static bool
>> +check_msginfo (int idx, key_t key, int cmd)
>> +{
>> +  struct msqid_ds msginfo;
>> +  int mid = msgctl (idx, cmd, &msginfo);
>> +  /* Ignore unused array slot returned by the kernel or information from
>> +     unknown message queue.  */
>> +  if ((mid == -1 && errno == EINVAL) || mid != msqid)
>> +    return false;
>> +
>> +  if (mid == -1)
>> +    FAIL_EXIT1 ("msgctl with %s failed: %m",
>> +		cmd == MSG_STAT ? "MSG_STAT" : "MSG_STAT_ANY");
>> +
>> +  if (msginfo.msg_perm.__key != key)
>> +    FAIL_EXIT1 ("msgid_ds::msg_perm::key (%d) != %d",
>> +		(int) msginfo.msg_perm.__key, (int) key);
>> +  if (msginfo.msg_perm.mode != MSGQ_MODE)
>> +    FAIL_EXIT1 ("msgid_ds::msg_perm::mode (%o) != %o",
>> +		msginfo.msg_perm.mode, MSGQ_MODE);
>> +  if (msginfo.msg_qnum != 0)
>> +    FAIL_EXIT1 ("msgid_ds::msg_qnum (%lu) != 0",
>> +		(long unsigned) msginfo.msg_qnum);
> 
> As in the other patch, you might want to use TEST_COMPARE here.

Yes, I changed it as well from the other patch review.

> 
> Rest looks okay, I think.
> 
> Thanks,
> Florian
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639]
  2020-09-29 12:37     ` Adhemerval Zanella
@ 2020-09-29 12:58       ` Adhemerval Zanella
  2020-09-29 13:01         ` Florian Weimer
  0 siblings, 1 reply; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-29 12:58 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha
  Cc: Robert O'Callahan, Dmitry V . Levin



On 29/09/2020 09:37, Adhemerval Zanella wrote:
> 
> 
> On 29/09/2020 04:57, Florian Weimer wrote:
>> * Adhemerval Zanella via Libc-alpha:
>>
>>> +static int
>>> +read_proc_file (const char *file)
>>> +{
>>> +  FILE *f = fopen (file, "r");
>>> +  if (f == NULL)
>>> +    return -1;
>>> +
>>> +  int v;
>>> +  int r = fscanf (f, "%d", & v);
>>> +  TEST_VERIFY_EXIT (r == 1);
>>> +
>>> +  fclose (f);
>>> +  return v;
>>> +}
>>
>> You could use xfopen and xfclose.
> 
> Indeed, I will change it.

In fact I though about it before and for this test we do want to 
check if the /proc file is accessible and just check against the 
tunable value if it were the case.  Otherwise the test will always
fail if /proc is not mounted (not really the expected scenario I 
give you).

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639]
  2020-09-29 12:58       ` Adhemerval Zanella
@ 2020-09-29 13:01         ` Florian Weimer
  2020-09-29 13:04           ` Adhemerval Zanella
  0 siblings, 1 reply; 19+ messages in thread
From: Florian Weimer @ 2020-09-29 13:01 UTC (permalink / raw)
  To: Adhemerval Zanella
  Cc: Adhemerval Zanella via Libc-alpha, Robert O'Callahan,
	Dmitry V . Levin

* Adhemerval Zanella:

> On 29/09/2020 09:37, Adhemerval Zanella wrote:
>> 
>> 
>> On 29/09/2020 04:57, Florian Weimer wrote:
>>> * Adhemerval Zanella via Libc-alpha:
>>>
>>>> +static int
>>>> +read_proc_file (const char *file)
>>>> +{
>>>> +  FILE *f = fopen (file, "r");
>>>> +  if (f == NULL)
>>>> +    return -1;
>>>> +
>>>> +  int v;
>>>> +  int r = fscanf (f, "%d", & v);
>>>> +  TEST_VERIFY_EXIT (r == 1);
>>>> +
>>>> +  fclose (f);
>>>> +  return v;
>>>> +}
>>>
>>> You could use xfopen and xfclose.
>> 
>> Indeed, I will change it.
>
> In fact I though about it before and for this test we do want to 
> check if the /proc file is accessible and just check against the 
> tunable value if it were the case.  Otherwise the test will always
> fail if /proc is not mounted (not really the expected scenario I 
> give you).

Maybe add FAIL_UNSUPPORTED for this case at the start of the test?

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639]
  2020-09-29 13:01         ` Florian Weimer
@ 2020-09-29 13:04           ` Adhemerval Zanella
  0 siblings, 0 replies; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-29 13:04 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Adhemerval Zanella via Libc-alpha, Robert O'Callahan,
	Dmitry V . Levin



On 29/09/2020 10:01, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> On 29/09/2020 09:37, Adhemerval Zanella wrote:
>>>
>>>
>>> On 29/09/2020 04:57, Florian Weimer wrote:
>>>> * Adhemerval Zanella via Libc-alpha:
>>>>
>>>>> +static int
>>>>> +read_proc_file (const char *file)
>>>>> +{
>>>>> +  FILE *f = fopen (file, "r");
>>>>> +  if (f == NULL)
>>>>> +    return -1;
>>>>> +
>>>>> +  int v;
>>>>> +  int r = fscanf (f, "%d", & v);
>>>>> +  TEST_VERIFY_EXIT (r == 1);
>>>>> +
>>>>> +  fclose (f);
>>>>> +  return v;
>>>>> +}
>>>>
>>>> You could use xfopen and xfclose.
>>>
>>> Indeed, I will change it.
>>
>> In fact I though about it before and for this test we do want to 
>> check if the /proc file is accessible and just check against the 
>> tunable value if it were the case.  Otherwise the test will always
>> fail if /proc is not mounted (not really the expected scenario I 
>> give you).
> 
> Maybe add FAIL_UNSUPPORTED for this case at the start of the test?

I don't have a strong opinion, I will add the FAIL_UNSUPPORTED for
case /proc is not accessible then.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 4/6] sysvipc: Return EINVAL for invalid msgctl commands
  2020-09-29  7:58   ` Florian Weimer
@ 2020-09-29 13:26     ` Adhemerval Zanella
  2020-09-29 17:05       ` Florian Weimer
  0 siblings, 1 reply; 19+ messages in thread
From: Adhemerval Zanella @ 2020-09-29 13:26 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha
  Cc: Robert O'Callahan, Dmitry V . Levin



On 29/09/2020 04:58, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> 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.
> 
> Looks okay to me for now.
> 
> I think eventually we need to rethink what we want to do about these,
> for the architectures that don't need translation.

We already have __IPC_TIME64 to tell apart the ABI that require it, 
we might to put the switch only if it is set.  However, I am not sure
if it is really an improvement, since we will still need to revise
it for architecture with __IPC_TIME64 == 1 anyway.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 4/6] sysvipc: Return EINVAL for invalid msgctl commands
  2020-09-29 13:26     ` Adhemerval Zanella
@ 2020-09-29 17:05       ` Florian Weimer
  0 siblings, 0 replies; 19+ messages in thread
From: Florian Weimer @ 2020-09-29 17:05 UTC (permalink / raw)
  To: Adhemerval Zanella
  Cc: Adhemerval Zanella via Libc-alpha, Robert O'Callahan,
	Dmitry V . Levin

* Adhemerval Zanella:

> On 29/09/2020 04:58, Florian Weimer wrote:
>> * Adhemerval Zanella via Libc-alpha:
>> 
>>> 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.
>> 
>> Looks okay to me for now.
>> 
>> I think eventually we need to rethink what we want to do about these,
>> for the architectures that don't need translation.
>
> We already have __IPC_TIME64 to tell apart the ABI that require it, 
> we might to put the switch only if it is set.  However, I am not sure
> if it is really an improvement, since we will still need to revise
> it for architecture with __IPC_TIME64 == 1 anyway.

It's an improvement for users on architectures which can use this
facility.  I think we should not artificially hold back architectures
with full userspace/kernel alignment just because there are other
architectures out there which are more complicated.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2020-09-29 17:05 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-28 14:45 [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] Adhemerval Zanella
2020-09-28 14:45 ` [PATCH 2/6] sysvipc: Return EINVAL for invalid semctl commands Adhemerval Zanella
2020-09-28 16:33   ` Florian Weimer
2020-09-28 21:07     ` Adhemerval Zanella
2020-09-28 14:45 ` [PATCH 3/6] sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639] Adhemerval Zanella
2020-09-28 14:55   ` Andreas Schwab
2020-09-29  7:57   ` Florian Weimer
2020-09-29 12:37     ` Adhemerval Zanella
2020-09-29 12:58       ` Adhemerval Zanella
2020-09-29 13:01         ` Florian Weimer
2020-09-29 13:04           ` Adhemerval Zanella
2020-09-28 14:45 ` [PATCH 4/6] sysvipc: Return EINVAL for invalid msgctl commands Adhemerval Zanella
2020-09-29  7:58   ` Florian Weimer
2020-09-29 13:26     ` Adhemerval Zanella
2020-09-29 17:05       ` Florian Weimer
2020-09-28 14:45 ` [PATCH 5/6] sysvipc: Fix IPC_INFO and SHM_INFO handling [BZ #26636] Adhemerval Zanella
2020-09-28 14:45 ` [PATCH 6/6] sysvipc: Return EINVAL for invalid shmctl commands Adhemerval Zanella
2020-09-28 14:59 ` [PATCH 1/6] sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] Florian Weimer
2020-09-28 21:06   ` Adhemerval Zanella

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).