[PATCH v4] tests: Additional IPC checks
Eugene Syromyatnikov
evgsyr at gmail.com
Tue Sep 13 16:18:42 UTC 2016
* tests/ipc_msg.c: Additional msgget (parameter format), msgctl
(parameter format, decoding of struct msqid_ds in IPC_SET/IPC_STAT
commands) checks.
* tests/ipc_sem.c: Additional semget, semctl checks.
* tests/ipc_shm.c: Additional shmget, shmctl checks.
* tests/semop.c: Additional semop checks. Added checks for semtimedop.
* tests/semop.test: Add explicit -e parameter in order to trace both
semop and semtimedop.
* tests/shmxt.c: Additional shmat/shmdt tests.
---
Changes since v3:
* Assertions eliminated.
* BROKEN_GLIBC macro renamed to SKIP_TEST_BOGUS_ADDR, commits merged.
* Proper order of static and local variables (which was broken after
yet another rebase) enforced.
* tests/shmxt: explicit values converted to constants.
tests/ipc_msg.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++----
tests/ipc_sem.c | 28 +++++++++++++++++++++++
tests/ipc_shm.c | 52 ++++++++++++++++++++++++++++++++++++++----
tests/semop.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/semop.test | 2 +-
tests/shmxt.c | 15 +++++++++++++
6 files changed, 219 insertions(+), 9 deletions(-)
diff --git a/tests/ipc_msg.c b/tests/ipc_msg.c
index b6b3c99..97f0c80 100644
--- a/tests/ipc_msg.c
+++ b/tests/ipc_msg.c
@@ -31,6 +31,28 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
+#include <sys/types.h>
+
+#include "xlat.h"
+#include "xlat/resource_flags.h"
+
+/*
+ * Before glibc-2.22-122-gbe48165, ppc64 code tried to retrieve data provided in
+ * third argument of msgctl call (in case of IPC_SET cmd) which led to
+ * segmentation fault.
+ */
+#if !(defined SKIP_TEST_BOGUS_ADDR)
+# if defined __GLIBC__ && defined POWERPC && defined POWERPC64
+# if !(defined __GLIBC_MINOR__) || \
+ ((__GLIBC__ << 16) + __GLIBC_MINOR__ < (2 << 16) + 23)
+# define SKIP_TEST_BOGUS_ADDR 1
+# endif
+# endif /* __GLIBC__ && _powerpc__ && __ppc64__ */
+#endif /* !SKIP_TEST_BOGUS_ADDR */
+
+#ifndef SKIP_TEST_BOGUS_ADDR
+# define SKIP_TEST_BOGUS_ADDR 0
+#endif
static int id = -1;
@@ -47,21 +69,50 @@ main(void)
{
static const key_t private_key =
(key_t) (0xffffffff00000000ULL | IPC_PRIVATE);
+
+ static const key_t bogus_key = (key_t) 0xeca86420fdb97531ULL;
+ static const int bogus_msgid = 0xfdb97531;
+ static const int bogus_cmd = 0xdeadbeef;
+#if !SKIP_TEST_BOGUS_ADDR
+ static void * const bogus_addr = (void *) -1L;
+#endif
+ static const int bogus_flags = 0xface1e55 & ~IPC_CREAT;
+
int rc;
struct msqid_ds ds;
+ rc = msgget(bogus_key, bogus_flags);
+ printf("msgget\\(%#llx, %s%s%s%#x\\|%#04o\\) += %s\n",
+ zero_extend_signed_to_ull(bogus_key),
+ IPC_CREAT & bogus_flags ? "IPC_CREAT\\|" : "",
+ IPC_EXCL & bogus_flags ? "IPC_EXCL\\|" : "",
+ IPC_NOWAIT & bogus_flags ? "IPC_NOWAIT\\|" : "",
+ bogus_flags & ~(0777 | IPC_CREAT | IPC_EXCL | IPC_NOWAIT),
+ bogus_flags & 0777,
+ sprintrc_grep(rc));
+
id = msgget(private_key, 0600);
if (id < 0)
perror_msg_and_skip("msgget");
printf("msgget\\(IPC_PRIVATE, 0600\\) += %d\n", id);
atexit(cleanup);
+ rc = msgctl(bogus_msgid, bogus_cmd, NULL);
+ printf("msgctl\\(%d, (IPC_64\\|)?%#x /\\* MSG_\\?\\?\\? \\*/, NULL\\) "
+ "+= %s\n", bogus_msgid, bogus_cmd, sprintrc_grep(rc));
+
+#if !SKIP_TEST_BOGUS_ADDR
+ rc = msgctl(bogus_msgid, IPC_SET, bogus_addr);
+ printf("msgctl\\(%d, (IPC_64\\|)?IPC_SET, %p\\) += %s\n",
+ bogus_msgid, bogus_addr, sprintrc_grep(rc));
+#endif
+
if (msgctl(id, IPC_STAT, &ds))
perror_msg_and_skip("msgctl IPC_STAT");
- printf("msgctl\\(%d, (IPC_64\\|)?IPC_STAT, \\{msg_perm=\\{uid=%u, gid=%u, "
- "mode=%#o, key=%u, cuid=%u, cgid=%u\\}, msg_stime=%u, msg_rtime=%u, "
- "msg_ctime=%u, msg_qnum=%u, msg_qbytes=%u, msg_lspid=%u, "
- "msg_lrpid=%u\\}\\) += 0\n",
+ printf("msgctl\\(%d, (IPC_64\\|)?IPC_STAT, \\{msg_perm=\\{uid=%u, "
+ "gid=%u, mode=%#o, key=%u, cuid=%u, cgid=%u\\}, msg_stime=%u, "
+ "msg_rtime=%u, msg_ctime=%u, msg_qnum=%u, msg_qbytes=%u, "
+ "msg_lspid=%u, msg_lrpid=%u\\}\\) += 0\n",
id, (unsigned) ds.msg_perm.uid, (unsigned) ds.msg_perm.gid,
(unsigned) ds.msg_perm.mode, (unsigned) ds.msg_perm.__key,
(unsigned) ds.msg_perm.cuid, (unsigned) ds.msg_perm.cgid,
@@ -70,6 +121,13 @@ main(void)
(unsigned) ds.msg_qbytes, (unsigned) ds.msg_lspid,
(unsigned) ds.msg_lrpid);
+ if (msgctl(id, IPC_SET, &ds))
+ perror_msg_and_skip("msgctl IPC_SET");
+ printf("msgctl\\(%d, (IPC_64\\|)?IPC_SET, \\{msg_perm=\\{uid=%u, "
+ "gid=%u, mode=%#o\\}, ...\\}\\) += 0\n",
+ id, (unsigned) ds.msg_perm.uid, (unsigned) ds.msg_perm.gid,
+ (unsigned) ds.msg_perm.mode);
+
rc = msgctl(0, MSG_INFO, &ds);
printf("msgctl\\(0, (IPC_64\\|)?MSG_INFO, %p\\) += %s\n",
&ds, sprintrc_grep(rc));
diff --git a/tests/ipc_sem.c b/tests/ipc_sem.c
index 01445e5..1bdc357 100644
--- a/tests/ipc_sem.c
+++ b/tests/ipc_sem.c
@@ -32,6 +32,9 @@
#include <stdlib.h>
#include <sys/sem.h>
+#include "xlat.h"
+#include "xlat/resource_flags.h"
+
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
@@ -55,17 +58,42 @@ main(void)
{
static const key_t private_key =
(key_t) (0xffffffff00000000ULL | IPC_PRIVATE);
+ static const key_t bogus_key = (key_t) 0xeca86420fdb97531ULL;
+ static const int bogus_semid = 0xfdb97531;
+ static const int bogus_semnum = 0xeca86420;
+ static const int bogus_size = 0xdec0ded1;
+ static const int bogus_flags = 0xface1e55;
+ static const int bogus_cmd = 0xdeadbeef;
+ static const unsigned long bogus_arg =
+ (unsigned long) 0xbadc0dedfffffaceULL;
+
int rc;
union semun un;
struct semid_ds ds;
struct seminfo info;
+ rc = semget(bogus_key, bogus_size, bogus_flags);
+ printf("semget\\(%#llx, %d, %s%s%s%#x\\|%#04o\\) += %s\n",
+ zero_extend_signed_to_ull(bogus_key), bogus_size,
+ IPC_CREAT & bogus_flags ? "IPC_CREAT\\|" : "",
+ IPC_EXCL & bogus_flags ? "IPC_EXCL\\|" : "",
+ IPC_NOWAIT & bogus_flags ? "IPC_NOWAIT\\|" : "",
+ bogus_flags & ~(0777 | IPC_CREAT | IPC_EXCL | IPC_NOWAIT),
+ bogus_flags & 0777,
+ sprintrc_grep(rc));
+
id = semget(private_key, 1, 0600);
if (id < 0)
perror_msg_and_skip("semget");
printf("semget\\(IPC_PRIVATE, 1, 0600\\) += %d\n", id);
atexit(cleanup);
+ rc = semctl(bogus_semid, bogus_semnum, bogus_cmd, bogus_arg);
+ printf("semctl\\(%d, %d, (IPC_64\\|)?%#x /\\* SEM_\\?\\?\\? \\*/, "
+ "(%#lx|\\[(%#lx|0)\\])\\) += %s\n",
+ bogus_semid, bogus_semnum, bogus_cmd, bogus_arg, bogus_arg,
+ sprintrc_grep(rc));
+
un.buf = &ds;
if (semctl(id, 0, IPC_STAT, un))
perror_msg_and_skip("semctl IPC_STAT");
diff --git a/tests/ipc_shm.c b/tests/ipc_shm.c
index 2788510..22a1ac7 100644
--- a/tests/ipc_shm.c
+++ b/tests/ipc_shm.c
@@ -32,6 +32,9 @@
#include <stdlib.h>
#include <sys/shm.h>
+#include "xlat.h"
+#include "xlat/shm_resource_flags.h"
+
static int id = -1;
static void
@@ -47,21 +50,55 @@ main(void)
{
static const key_t private_key =
(key_t) (0xffffffff00000000ULL | IPC_PRIVATE);
+
+ static const key_t bogus_key = (key_t)0xeca86420fdb97531ULL;
+ static const int bogus_id = 0xdefaced1;
+ static const int bogus_cmd = 0xdefaced2;
+ static void * const bogus_addr = (void *) -1L;
+ static const size_t bogus_size =
+ /* musl sets size to SIZE_MAX if size argument is greater than
+ * PTRDIFF_MAX - musl/src/ipc/shmget.c */
+ #ifdef __GLIBC__
+ (size_t) 0xdec0ded1dec0ded2ULL;
+ #else
+ (size_t) 0x1e55c0de5dec0dedULL;
+ #endif
+ static const int bogus_flags = 0xface1e55;
+
int rc;
struct shmid_ds ds;
+ rc = shmget(bogus_key, bogus_size, bogus_flags);
+ printf("shmget\\(%#llx, %zu, %s%s%s%#x\\|%#04o\\) += %s\n",
+ zero_extend_signed_to_ull(bogus_key), bogus_size,
+ IPC_CREAT & bogus_flags ? "IPC_CREAT\\|" : "",
+ IPC_EXCL & bogus_flags ? "IPC_EXCL\\|" : "",
+ SHM_HUGETLB & bogus_flags ? "SHM_HUGETLB\\|" : "",
+ bogus_flags & ~(0777 | IPC_CREAT | IPC_EXCL | SHM_HUGETLB),
+ bogus_flags & 0777,
+ sprintrc_grep(rc));
+
id = shmget(private_key, 1, 0600);
if (id < 0)
perror_msg_and_skip("shmget");
printf("shmget\\(IPC_PRIVATE, 1, 0600\\) += %d\n", id);
atexit(cleanup);
+ rc = shmctl(bogus_id, bogus_cmd, NULL);
+ printf("shmctl\\(%d, (IPC_64\\|)?%#x /\\* SHM_\\?\\?\\? \\*/, "
+ "NULL\\) += %s\n",
+ bogus_id, bogus_cmd, sprintrc_grep(rc));
+
+ rc = shmctl(bogus_id, IPC_STAT, bogus_addr);
+ printf("shmctl\\(%d, (IPC_64\\|)?IPC_STAT, %p\\) += %s\n",
+ bogus_id, bogus_addr, sprintrc_grep(rc));
+
if (shmctl(id, IPC_STAT, &ds))
perror_msg_and_skip("shmctl IPC_STAT");
- printf("shmctl\\(%d, (IPC_64\\|)?IPC_STAT, \\{shm_perm=\\{uid=%u, gid=%u, "
- "mode=%#o, key=%u, cuid=%u, cgid=%u\\}, shm_segsz=%u, shm_cpid=%u, "
- "shm_lpid=%u, shm_nattch=%u, shm_atime=%u, shm_dtime=%u, "
- "shm_ctime=%u\\}\\) += 0\n",
+ printf("shmctl\\(%d, (IPC_64\\|)?IPC_STAT, \\{shm_perm=\\{uid=%u, "
+ "gid=%u, mode=%#o, key=%u, cuid=%u, cgid=%u\\}, shm_segsz=%u, "
+ "shm_cpid=%u, shm_lpid=%u, shm_nattch=%u, shm_atime=%u, "
+ "shm_dtime=%u, shm_ctime=%u\\}\\) += 0\n",
id, (unsigned) ds.shm_perm.uid, (unsigned) ds.shm_perm.gid,
(unsigned) ds.shm_perm.mode, (unsigned) ds.shm_perm.__key,
(unsigned) ds.shm_perm.cuid, (unsigned) ds.shm_perm.cgid,
@@ -70,6 +107,13 @@ main(void)
(unsigned) ds.shm_atime, (unsigned) ds.shm_dtime,
(unsigned) ds. shm_ctime);
+ if (shmctl(id, IPC_SET, &ds))
+ perror_msg_and_skip("shmctl IPC_SET");
+ printf("shmctl\\(%d, (IPC_64\\|)?IPC_SET, \\{shm_perm=\\{uid=%u, "
+ "gid=%u, mode=%#o\\}, ...\\}\\) += 0\n",
+ id, (unsigned) ds.shm_perm.uid, (unsigned) ds.shm_perm.gid,
+ (unsigned) ds.shm_perm.mode);
+
rc = shmctl(0, SHM_INFO, &ds);
printf("shmctl\\(0, (IPC_64\\|)?SHM_INFO, %p\\) += %s\n",
&ds, sprintrc_grep(rc));
diff --git a/tests/semop.c b/tests/semop.c
index 214ce32..8eb1e2b 100644
--- a/tests/semop.c
+++ b/tests/semop.c
@@ -2,10 +2,14 @@
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include "xlat.h"
+#include "xlat/semop_flags.h"
+
union semun
{
int val;
@@ -26,6 +30,15 @@ cleanup(void)
int
main(void)
{
+ static const int bogus_semid = 0xfdb97531;
+ static void * const bogus_sops = (void *) -1L;
+ static const unsigned bogus_nsops = 0xdeadbeef;
+
+ static const struct timespec ts_data = { 1, 123456789 };
+
+ struct timespec *ts = tail_memdup(&ts_data, sizeof(*ts));
+ int rc;
+
id = semget(IPC_PRIVATE, 1, 0600);
if (id < 0)
perror_msg_and_skip("semget");
@@ -36,10 +49,32 @@ main(void)
perror_msg_and_skip("semctl");
struct sembuf *const sem_b = tail_alloc(sizeof(*sem_b));
+ struct sembuf *const sem_b2 = tail_alloc(sizeof(*sem_b2));
+
+ rc = semop(bogus_semid, NULL, bogus_nsops);
+ printf("semop(%d, NULL, %u) = %s\n",
+ bogus_semid, bogus_nsops, sprintrc(-1));
+
+ rc = semop(bogus_semid, bogus_sops, 1);
+ printf("semop(%d, %p, %u) = %s\n",
+ bogus_semid, bogus_sops, 1, sprintrc(-1));
+
sem_b->sem_num = 0;
sem_b->sem_op = 1;
sem_b->sem_flg = SEM_UNDO;
+ sem_b2->sem_num = 0xface;
+ sem_b2->sem_op = 0xf00d;
+ sem_b2->sem_flg = 0xbeef;
+
+ rc = semop(bogus_semid, sem_b2, 2);
+ printf("semop(%d, [{%hu, %hd, %s%s%#hx}, %p], %u) = %s\n",
+ bogus_semid, sem_b2->sem_num, sem_b2->sem_op,
+ sem_b2->sem_flg & SEM_UNDO ? "SEM_UNDO|" : "",
+ sem_b2->sem_flg & IPC_NOWAIT ? "IPC_NOWAIT|" : "",
+ sem_b2->sem_flg & ~(SEM_UNDO | IPC_NOWAIT),
+ sem_b2 + 1, 2, sprintrc(-1));
+
if (semop(id, sem_b, 1))
perror_msg_and_skip("semop, 1");
printf("semop(%d, [{0, 1, SEM_UNDO}], 1) = 0\n", id);
@@ -49,6 +84,36 @@ main(void)
perror_msg_and_skip("semop, -1");
printf("semop(%d, [{0, -1, SEM_UNDO}], 1) = 0\n", id);
+ rc = semtimedop(bogus_semid, NULL, bogus_nsops, NULL);
+ printf("semtimedop(%d, NULL, %u, NULL) = %s\n",
+ bogus_semid, bogus_nsops, sprintrc(-1));
+
+ rc = semtimedop(id, sem_b + 1, 1, ts + 1);
+ printf("semtimedop(%d, %p, 1, %p) = %s\n",
+ id, sem_b + 1, ts + 1, sprintrc(-1));
+
+ rc = semtimedop(bogus_semid, sem_b2, 2, ts);
+ printf("semtimedop(%d, [{%hu, %hd, %s%s%#hx}, %p], %u, {%jd, %jd}) = "
+ "%s\n",
+ bogus_semid, sem_b2->sem_num, sem_b2->sem_op,
+ sem_b2->sem_flg & SEM_UNDO ? "SEM_UNDO|" : "",
+ sem_b2->sem_flg & IPC_NOWAIT ? "IPC_NOWAIT|" : "",
+ sem_b2->sem_flg & ~(SEM_UNDO | IPC_NOWAIT),
+ sem_b2 + 1, 2,
+ (intmax_t) ts->tv_sec, (intmax_t) ts->tv_nsec,
+ sprintrc(-1));
+
+ sem_b->sem_op = 1;
+ if (semtimedop(id, sem_b, 1, NULL))
+ perror_msg_and_skip("semtimedop, 1");
+ printf("semtimedop(%d, [{0, 1, SEM_UNDO}], 1, NULL) = 0\n", id);
+
+ sem_b->sem_op = -1;
+ if (semtimedop(id, sem_b, 1, ts))
+ perror_msg_and_skip("semtimedop, -1");
+ printf("semtimedop(%d, [{0, -1, SEM_UNDO}], 1, {%jd, %jd}) = 0\n", id,
+ (intmax_t) ts->tv_sec, (intmax_t) ts->tv_nsec);
+
puts("+++ exited with 0 +++");
return 0;
}
diff --git a/tests/semop.test b/tests/semop.test
index 7e8f32c..3e77d2f 100755
--- a/tests/semop.test
+++ b/tests/semop.test
@@ -3,4 +3,4 @@
# Check semop syscall decoding.
. "${srcdir=.}/init.sh"
-run_strace_match_diff -a32
+run_strace_match_diff -a32 -e trace=semop,semtimedop
diff --git a/tests/shmxt.c b/tests/shmxt.c
index 8e087f3..23cc7cc 100644
--- a/tests/shmxt.c
+++ b/tests/shmxt.c
@@ -21,11 +21,23 @@ cleanup(void)
int
main(void)
{
+ static const int bogus_shmid = 0xfdb97531;
+ static const void * const bogus_shmaddr =
+ (void *) (unsigned long) 0xdec0ded1dec0ded2ULL;
+ static const int bogus_shmflg = 0xffffface;
+
+ long rc;
+
id = shmget(IPC_PRIVATE, 1, 0600);
if (id < 0)
perror_msg_and_skip("shmget");
atexit(cleanup);
+ rc = (long) shmat(bogus_shmid, bogus_shmaddr, bogus_shmflg);
+ printf("%s(%d, %p, SHM_REMAP|SHM_RDONLY|SHM_RND|%#x) = %s\n",
+ SHMAT, bogus_shmid, bogus_shmaddr, bogus_shmflg & ~0x7000,
+ sprintrc(rc));
+
shmat(id, NULL, SHM_REMAP);
printf("%s(%d, NULL, SHM_REMAP) = -1 %s (%m)\n",
SHMAT, id, errno2name());
@@ -35,6 +47,9 @@ main(void)
perror_msg_and_skip("shmat SHM_RDONLY");
printf("%s(%d, NULL, SHM_RDONLY) = %p\n", SHMAT, id, shmaddr);
+ rc = shmdt(NULL);
+ printf("shmdt(NULL) = %s\n", sprintrc(rc));
+
if (shmdt(shmaddr))
perror_msg_and_skip("shmdt");
printf("shmdt(%p) = 0\n", shmaddr);
--
1.7.10.4
More information about the Strace-devel
mailing list