* 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 ------------------------------------------------------------------------------ _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel