|
|
8a984d |
Rewrite of the following commit to support returning EINVAL for unknown
|
|
|
8a984d |
commands and therefore match upstream behaviour.
|
|
|
8a984d |
|
|
|
8a984d |
commit 9ebaabeaac1a96b0d91f52902ce1dbf4f5a562dd
|
|
|
8a984d |
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
|
|
8a984d |
Date: Tue Sep 29 14:55:02 2020 -0300
|
|
|
8a984d |
|
|
|
8a984d |
sysvipc: Return EINVAL for invalid shmctl commands
|
|
|
8a984d |
|
|
|
8a984d |
It avoids regressions on possible future commands that might require
|
|
|
8a984d |
additional libc support. The downside is new commands added by newer
|
|
|
8a984d |
kernels will need further glibc support.
|
|
|
8a984d |
|
|
|
8a984d |
Checked on x86_64-linux-gnu and i686-linux-gnu (Linux v4.15 and v5.4).
|
|
|
8a984d |
|
|
|
8a984d |
diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c
|
|
|
8a984d |
index 25c5152944a6fcf3..00768bc47614f9aa 100644
|
|
|
8a984d |
--- a/sysdeps/unix/sysv/linux/shmctl.c
|
|
|
8a984d |
+++ b/sysdeps/unix/sysv/linux/shmctl.c
|
|
|
8a984d |
@@ -33,6 +33,22 @@
|
|
|
8a984d |
int
|
|
|
8a984d |
__new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
|
|
|
8a984d |
{
|
|
|
8a984d |
+ switch (cmd)
|
|
|
8a984d |
+ {
|
|
|
8a984d |
+ case IPC_RMID:
|
|
|
8a984d |
+ case SHM_LOCK:
|
|
|
8a984d |
+ case SHM_UNLOCK:
|
|
|
8a984d |
+ case IPC_SET:
|
|
|
8a984d |
+ case IPC_STAT:
|
|
|
8a984d |
+ case SHM_STAT:
|
|
|
8a984d |
+ case SHM_STAT_ANY:
|
|
|
8a984d |
+ case IPC_INFO:
|
|
|
8a984d |
+ case SHM_INFO:
|
|
|
8a984d |
+ break;
|
|
|
8a984d |
+ default:
|
|
|
8a984d |
+ __set_errno (EINVAL);
|
|
|
8a984d |
+ break;
|
|
|
8a984d |
+ }
|
|
|
8a984d |
#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
|
|
|
8a984d |
return INLINE_SYSCALL_CALL (shmctl, shmid, cmd | __IPC_64, buf);
|
|
|
8a984d |
#else
|
|
|
8a984d |
diff --git a/sysvipc/test-sysvipc.h b/sysvipc/test-sysvipc.h
|
|
|
8a984d |
index 21ef6c656581519e..d1c8349b45b5ce49 100644
|
|
|
8a984d |
--- a/sysvipc/test-sysvipc.h
|
|
|
8a984d |
+++ b/sysvipc/test-sysvipc.h
|
|
|
8a984d |
@@ -25,7 +25,7 @@
|
|
|
8a984d |
#include <sys/shm.h>
|
|
|
8a984d |
#include <include/array_length.h>
|
|
|
8a984d |
|
|
|
8a984d |
-/* Return the first invalid command SysV IPC command from common shared
|
|
|
8a984d |
+/* Return the first invalid SysV IPC command from common shared
|
|
|
8a984d |
between message queue, shared memory, and semaphore. */
|
|
|
8a984d |
static inline int
|
|
|
8a984d |
first_common_invalid_cmd (void)
|
|
|
8a984d |
@@ -50,7 +50,7 @@ first_common_invalid_cmd (void)
|
|
|
8a984d |
return invalid;
|
|
|
8a984d |
}
|
|
|
8a984d |
|
|
|
8a984d |
-/* Return the first invalid command SysV IPC command for semaphore. */
|
|
|
8a984d |
+/* Return the first invalid SysV IPC command for semaphore. */
|
|
|
8a984d |
static inline int
|
|
|
8a984d |
first_sem_invalid_cmd (void)
|
|
|
8a984d |
{
|
|
|
8a984d |
@@ -82,7 +82,7 @@ first_sem_invalid_cmd (void)
|
|
|
8a984d |
return invalid;
|
|
|
8a984d |
}
|
|
|
8a984d |
|
|
|
8a984d |
-/* Return the first invalid command SysV IPC command for message queue. */
|
|
|
8a984d |
+/* Return the first invalid SysV IPC command for message queue. */
|
|
|
8a984d |
static inline int
|
|
|
8a984d |
first_msg_invalid_cmd (void)
|
|
|
8a984d |
{
|
|
|
8a984d |
@@ -107,4 +107,31 @@ first_msg_invalid_cmd (void)
|
|
|
8a984d |
return invalid;
|
|
|
8a984d |
}
|
|
|
8a984d |
|
|
|
8a984d |
+/* Return the first invalid SysV IPC command for shared memory. */
|
|
|
8a984d |
+static inline int
|
|
|
8a984d |
+first_shm_invalid_cmd (void)
|
|
|
8a984d |
+{
|
|
|
8a984d |
+ const int shm_cmds[] = {
|
|
|
8a984d |
+ SHM_STAT,
|
|
|
8a984d |
+ SHM_INFO,
|
|
|
8a984d |
+#ifdef SHM_STAT_ANY
|
|
|
8a984d |
+ SHM_STAT_ANY,
|
|
|
8a984d |
+#endif
|
|
|
8a984d |
+ SHM_LOCK,
|
|
|
8a984d |
+ SHM_UNLOCK
|
|
|
8a984d |
+ };
|
|
|
8a984d |
+
|
|
|
8a984d |
+ int invalid = first_common_invalid_cmd ();
|
|
|
8a984d |
+ for (int i = 0; i < array_length (shm_cmds); i++)
|
|
|
8a984d |
+ {
|
|
|
8a984d |
+ if (invalid == shm_cmds[i])
|
|
|
8a984d |
+ {
|
|
|
8a984d |
+ invalid++;
|
|
|
8a984d |
+ i = 0;
|
|
|
8a984d |
+ }
|
|
|
8a984d |
+ }
|
|
|
8a984d |
+
|
|
|
8a984d |
+ return invalid;
|
|
|
8a984d |
+}
|
|
|
8a984d |
+
|
|
|
8a984d |
#endif /* _TEST_SYSV_H */
|
|
|
8a984d |
diff --git a/sysvipc/test-sysvshm.c b/sysvipc/test-sysvshm.c
|
|
|
8a984d |
index a7c2e0bd4065dbcd..0fdfddf8550413e4 100644
|
|
|
8a984d |
--- a/sysvipc/test-sysvshm.c
|
|
|
8a984d |
+++ b/sysvipc/test-sysvshm.c
|
|
|
8a984d |
@@ -25,6 +25,8 @@
|
|
|
8a984d |
#include <sys/ipc.h>
|
|
|
8a984d |
#include <sys/shm.h>
|
|
|
8a984d |
|
|
|
8a984d |
+#include <test-sysvipc.h>
|
|
|
8a984d |
+
|
|
|
8a984d |
#include <support/support.h>
|
|
|
8a984d |
#include <support/check.h>
|
|
|
8a984d |
#include <support/temp_file.h>
|
|
|
8a984d |
@@ -81,6 +83,9 @@ do_test (void)
|
|
|
8a984d |
FAIL_EXIT1 ("shmget failed (errno=%d)", errno);
|
|
|
8a984d |
}
|
|
|
8a984d |
|
|
|
8a984d |
+ TEST_COMPARE (shmctl (shmid, first_shm_invalid_cmd (), NULL), -1);
|
|
|
8a984d |
+ TEST_COMPARE (errno, EINVAL);
|
|
|
8a984d |
+
|
|
|
8a984d |
/* Get shared memory kernel information and do some sanity checks. */
|
|
|
8a984d |
struct shmid_ds shminfo;
|
|
|
8a984d |
if (shmctl (shmid, IPC_STAT, &shminfo) == -1)
|