]> granicus.if.org Git - strace/commitdiff
tests: add more IPC decoding checks
authorEugene Syromyatnikov <evgsyr@gmail.com>
Tue, 13 Sep 2016 16:18:42 +0000 (19:18 +0300)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 13 Sep 2016 17:21:20 +0000 (17:21 +0000)
* tests/ipc_msg.c: Additional msgget (parameter format) and msgctl
(parameter format, decoding of struct msqid_ds in IPC_SET/IPC_STAT
commands) checks.
* tests/ipc_sem.c: Additional semget and semctl checks.
* tests/ipc_shm.c: Additional shmget and shmctl checks.
* tests/semop.c: Additional semop checks.  Add checks for semtimedop.
* tests/semop.test: Add explicit -e parameter in order to trace both
semop and semtimedop.
* tests/shmxt.c: Additional shmat and shmdt checks.

tests/ipc_msg.c
tests/ipc_sem.c
tests/ipc_shm.c
tests/semop.c
tests/semop.test
tests/shmxt.c

index b6b3c9931da4febc242607a84e37b71798f0b553..b493843981dd234eaf39c706108be63f33f8334b 100644 (file)
 #include <stdlib.h>
 #include <sys/msg.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.
+ */
+#undef TEST_MSGCTL_BOGUS_ADDR
+#if defined __GLIBC__ && defined POWERPC64
+# if !(defined __GLIBC_MINOR__) \
+   || ((__GLIBC__ << 16) + __GLIBC_MINOR__ < (2 << 16) + 23)
+#  define TEST_MSGCTL_BOGUS_ADDR 0
+# endif
+#endif /* __GLIBC__ && POWERPC64 */
+
+#ifndef TEST_MSGCTL_BOGUS_ADDR
+# define TEST_MSGCTL_BOGUS_ADDR 1
+#endif
+
 static int id = -1;
 
 static void
@@ -47,28 +67,62 @@ 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 TEST_MSGCTL_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 TEST_MSGCTL_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",
-               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,
-               (unsigned) ds.msg_stime, (unsigned) ds.msg_rtime,
-               (unsigned) ds.msg_ctime, (unsigned) ds.msg_qnum,
-               (unsigned) ds.msg_qbytes, (unsigned) ds.msg_lspid,
-               (unsigned) ds.msg_lrpid);
+       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,
+              (unsigned) ds.msg_stime, (unsigned) ds.msg_rtime,
+              (unsigned) ds.msg_ctime, (unsigned) ds.msg_qnum,
+              (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",
index 01445e5ba98a2932926b27e4622b99574bc5964e..4decb3f9435b5d5f5f78966cf13cdf20025f136f 100644 (file)
@@ -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,41 @@ 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");
index 27885109d7e772fe6ec4dcf270617ca1121f0b33..66960ff9fb98e43229e567203a1fc4050d567176 100644 (file)
@@ -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,15 +50,48 @@ 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, "
@@ -70,6 +106,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));
index 214ce3289b8ba4ff8a56e63e4b424d89811cc5a5..f9b74440a1d7e20867bf48b39d94a7db546d4d66 100644 (file)
@@ -1,11 +1,14 @@
 #include "tests.h"
-#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 +29,15 @@ cleanup(void)
 int
 main(void)
 {
+       static const int bogus_semid = 0xfdb97531;
+       static void * const bogus_sops = (void *) -1L;
+       static const size_t bogus_nsops = (size_t) 0xdefaceddeadbeefULL;
+
+       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 +48,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, (unsigned) bogus_nsops, sprintrc(rc));
+
+       rc = semop(bogus_semid, bogus_sops, 1);
+       printf("semop(%d, %p, %u) = %s\n",
+               bogus_semid, bogus_sops, 1, sprintrc(rc));
+
        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(rc));
+
        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 +83,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, (unsigned) bogus_nsops, sprintrc(rc));
+
+       rc = semtimedop(id, sem_b + 1, 1, ts + 1);
+       printf("semtimedop(%d, %p, 1, %p) = %s\n",
+               id, sem_b + 1, ts + 1, sprintrc(rc));
+
+       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(rc));
+
+       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;
 }
index 7e8f32cd7fb861e979abc2ffdbfa5f651cc38175..3e77d2f92220d1561b23be0b1af85383f81cd20c 100755 (executable)
@@ -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
index 8e087f3c636a3420345d48c58a92f9ce2d510425..23cc7ccf4900bf4f680a6c277c90a7e0bdcede06 100644 (file)
@@ -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);