MPERS_PRINTER_DECL(bool, fetch_struct_stat, struct tcb *tcp, const unsigned long addr, struct strace_stat *const dst) { #ifdef HAVE_STRUCT_STAT struct_stat buf; if (umove_or_printaddr(tcp, addr, &buf)) return false; dst->dev = zero_extend_signed_to_ull(buf.st_dev); dst->ino = zero_extend_signed_to_ull(buf.st_ino); dst->rdev = zero_extend_signed_to_ull(buf.st_rdev); dst->size = zero_extend_signed_to_ull(buf.st_size); dst->blocks = zero_extend_signed_to_ull(buf.st_blocks); dst->blksize = zero_extend_signed_to_ull(buf.st_blksize); dst->mode = zero_extend_signed_to_ull(buf.st_mode); dst->nlink = zero_extend_signed_to_ull(buf.st_nlink); dst->uid = zero_extend_signed_to_ull(buf.st_uid); dst->gid = zero_extend_signed_to_ull(buf.st_gid); dst->atime = sign_extend_unsigned_to_ll(buf.st_atime); dst->ctime = sign_extend_unsigned_to_ll(buf.st_ctime); dst->mtime = sign_extend_unsigned_to_ll(buf.st_mtime); dst->atime_nsec = TIME_NSEC(buf.st_atime_nsec); dst->ctime_nsec = TIME_NSEC(buf.st_ctime_nsec); dst->mtime_nsec = TIME_NSEC(buf.st_mtime_nsec); return true; #else /* !HAVE_STRUCT_STAT */ printaddr(addr); return false; #endif }
static void print_ts(const struct timespec *ts) { printf("{tv_sec=%lld, tv_nsec=%llu}", (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec)); print_time_t_nsec(ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec), 1); }
int main(void) { TAIL_ALLOC_OBJECT_CONST_PTR(struct timeval, tv); TAIL_ALLOC_OBJECT_CONST_PTR(struct timezone, tz); if (syscall(__NR_gettimeofday, tv, NULL)) perror_msg_and_skip("gettimeofday"); printf("gettimeofday({tv_sec=%lld, tv_usec=%llu}, NULL) = 0\n", (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec)); if (syscall(__NR_gettimeofday, tv, tz)) perror_msg_and_skip("gettimeofday"); printf("gettimeofday({tv_sec=%lld, tv_usec=%llu}" ", {tz_minuteswest=%d, tz_dsttime=%d}) = 0\n", (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec), tz->tz_minuteswest, tz->tz_dsttime); tv->tv_sec = -1; tv->tv_usec = 1000000; assert(syscall(__NR_settimeofday, tv, tz) == -1); printf("settimeofday({tv_sec=%lld, tv_usec=%llu}" ", {tz_minuteswest=%d, tz_dsttime=%d}) = -1 EINVAL (%m)\n", (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec), tz->tz_minuteswest, tz->tz_dsttime); tv->tv_sec = 0xdeadbeefU; tv->tv_usec = 0xfacefeedU; assert(syscall(__NR_settimeofday, tv, tz) == -1); printf("settimeofday({tv_sec=%lld, tv_usec=%llu}" ", {tz_minuteswest=%d, tz_dsttime=%d}) = -1 EINVAL (%m)\n", (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec), tz->tz_minuteswest, tz->tz_dsttime); tv->tv_sec = (time_t) 0xcafef00ddeadbeefLL; tv->tv_usec = (suseconds_t) 0xbadc0dedfacefeedLL; assert(syscall(__NR_settimeofday, tv, tz) == -1); printf("settimeofday({tv_sec=%lld, tv_usec=%llu}" ", {tz_minuteswest=%d, tz_dsttime=%d}) = -1 EINVAL (%m)\n", (long long) tv->tv_sec, zero_extend_signed_to_ull(tv->tv_usec), tz->tz_minuteswest, tz->tz_dsttime); puts("+++ exited with 0 +++"); return 0; }
static void do_send(int fd, char *msg, unsigned int msg_size, struct timespec *tmout, bool cropped) { long rc; long saved_errno; do { rc = syscall(__NR_mq_timedsend, fd, msg, msg_size, 42, tmout); saved_errno = errno; printf("mq_timedsend(%d, ", fd); printstr(MSG_START, msg_size > MSG_MAX_UNCUT ? MSG_MAX_UNCUT : msg_size); if (cropped) printf("..."); errno = saved_errno; printf(", %u, 42, {tv_sec=%lld, tv_nsec=%llu}) = %s\n", msg_size, (long long) tmout->tv_sec, zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc)); errno = saved_errno; if (rc == -1) { if (errno == EINTR) continue; perror_msg_and_skip("mq_timedsend"); } # if DUMPIO_WRITE dumpstr(MSG_START, msg_size); # endif } while (rc); }
static void print_old_dirent(struct tcb *tcp, long addr) { kernel_dirent d; if (umove_or_printaddr(tcp, addr, &d)) return; tprintf("{d_ino=%llu, d_off=%llu, d_reclen=%u, d_name=", zero_extend_signed_to_ull(d.d_ino), zero_extend_signed_to_ull(d.d_off), d.d_reclen); if (d.d_reclen > D_NAME_LEN_MAX) d.d_reclen = D_NAME_LEN_MAX; printpathn(tcp, addr + offsetof(kernel_dirent, d_name), d.d_reclen); tprints("}"); }
static const char * sprint_siginfo(const siginfo_t *const si, const char *const status_text) { static char buf[1024]; snprintf(buf, sizeof(buf), "{si_signo=SIGCHLD" ", si_code=%s" ", si_pid=%u" ", si_uid=%u" ", si_status=%s" ", si_utime=%llu" ", si_stime=%llu}", si_code_2_name(si->si_code), si->si_pid, si->si_uid, status_text, zero_extend_signed_to_ull(si->si_utime), zero_extend_signed_to_ull(si->si_stime)); return buf; }
static void print_old_kernel_stat(struct tcb *const tcp, const kernel_ulong_t addr) { struct __old_kernel_stat buf; if (umove_or_printaddr(tcp, addr, &buf)) return; struct strace_stat st = { .dev = zero_extend_signed_to_ull(buf.st_dev), .ino = zero_extend_signed_to_ull(buf.st_ino), .rdev = zero_extend_signed_to_ull(buf.st_rdev), .size = zero_extend_signed_to_ull(buf.st_size), .mode = zero_extend_signed_to_ull(buf.st_mode), .nlink = zero_extend_signed_to_ull(buf.st_nlink), .uid = zero_extend_signed_to_ull(buf.st_uid), .gid = zero_extend_signed_to_ull(buf.st_gid), .atime = sign_extend_unsigned_to_ll(buf.st_atime), .ctime = sign_extend_unsigned_to_ll(buf.st_ctime), .mtime = sign_extend_unsigned_to_ll(buf.st_mtime) }; print_struct_stat(tcp, &st); } SYS_FUNC(oldstat) { if (entering(tcp)) { printpath(tcp, tcp->u_arg[0]); tprints(", "); } else { print_old_kernel_stat(tcp, tcp->u_arg[1]); } return 0; } SYS_FUNC(oldfstat) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); tprints(", "); } else { print_old_kernel_stat(tcp, tcp->u_arg[1]); } return 0; }
static void do_recv(int fd, char *msg, unsigned int msg_size, struct timespec *tmout, bool cropped) { long rc; long saved_errno; unsigned prio; do { rc = syscall(__NR_mq_timedreceive, fd, msg, MSG_SIZE, &prio, tmout); saved_errno = errno; printf("mq_timedreceive(%d, ", fd); if (rc >= 0) { printstr(MSG_START, rc > MSG_MAX_UNCUT ? MSG_MAX_UNCUT : rc); if (cropped) printf("..."); } else { printf("%p", msg); } errno = saved_errno; printf(", %u, [42], {tv_sec=%lld, tv_nsec=%llu}) = %s\n", MSG_SIZE, (long long) tmout->tv_sec, zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc)); errno = saved_errno; if (rc == -1) { if (errno == EINTR) continue; perror_msg_and_skip("mq_timedreceive"); } if ((rc >= 0) && ((unsigned long) rc != msg_size)) error_msg_and_skip("mq_timedreceive size mismatch" ": expected %u, got %ld", msg_size, rc); # if DUMPIO_READ dumpstr(MSG_START, rc); # endif } while (rc < 0); }
static void print_si_info(const siginfo_t *sip) { if (sip->si_errno) { tprints(", si_errno="); if ((unsigned) sip->si_errno < nerrnos && errnoent[sip->si_errno]) tprints(errnoent[sip->si_errno]); else tprintf("%d", sip->si_errno); } if (SI_FROMUSER(sip)) { switch (sip->si_code) { case SI_USER: printsigsource(sip); break; case SI_TKILL: printsigsource(sip); break; #if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN case SI_TIMER: tprintf(", si_timerid=%#x, si_overrun=%d", sip->si_timerid, sip->si_overrun); printsigval(sip); break; #endif default: printsigsource(sip); if (sip->si_ptr) printsigval(sip); break; } } else { switch (sip->si_signo) { case SIGCHLD: printsigsource(sip); tprints(", si_status="); if (sip->si_code == CLD_EXITED) tprintf("%d", sip->si_status); else printsignal(sip->si_status); tprintf(", si_utime=%llu, si_stime=%llu", zero_extend_signed_to_ull(sip->si_utime), zero_extend_signed_to_ull(sip->si_stime)); break; case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: tprints(", si_addr="); printaddr(ptr_to_kulong(sip->si_addr)); break; case SIGPOLL: switch (sip->si_code) { case POLL_IN: case POLL_OUT: case POLL_MSG: tprintf(", si_band=%ld", (long) sip->si_band); break; } break; #ifdef HAVE_SIGINFO_T_SI_SYSCALL case SIGSYS: { const char *scname = syscall_name((unsigned) sip->si_syscall); tprints(", si_call_addr="); printaddr(ptr_to_kulong(sip->si_call_addr)); tprints(", si_syscall="); if (scname) tprintf("__NR_%s", scname); else tprintf("%u", (unsigned) sip->si_syscall); tprints(", si_arch="); printxval(audit_arch, sip->si_arch, "AUDIT_ARCH_???"); break; } #endif default: if (sip->si_pid || sip->si_uid) printsigsource(sip); if (sip->si_ptr) printsigval(sip); } } }
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; TAIL_ALLOC_OBJECT_CONST_PTR(struct timespec, ts); int rc; id = semget(IPC_PRIVATE, 1, 0600); if (id < 0) perror_msg_and_skip("semget"); atexit(cleanup); union semun sem_union = { .val = 0 }; if (semctl(id, 0, SETVAL, sem_union) == -1) perror_msg_and_skip("semctl"); TAIL_ALLOC_OBJECT_CONST_PTR(struct sembuf, sem_b); TAIL_ALLOC_OBJECT_CONST_PTR(struct sembuf, 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|" : "", (short) (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); sem_b->sem_op = -1; if (semop(id, sem_b, 1)) 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)); ts->tv_sec = 1; ts->tv_nsec = 123456789; rc = semtimedop(bogus_semid, sem_b2, 2, ts); printf("semtimedop(%d, [{%hu, %hd, %s%s%#hx}, ... /* %p */], %u" ", {tv_sec=%lld, tv_nsec=%llu}) = %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|" : "", (short) (sem_b2->sem_flg & ~(SEM_UNDO | IPC_NOWAIT)), sem_b2 + 1, 2, (long long) ts->tv_sec, zero_extend_signed_to_ull(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" ", {tv_sec=%lld, tv_nsec=%llu}) = 0\n", id, (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec)); sem_b->sem_op = 1; ts->tv_sec = 0xdeadbeefU; ts->tv_nsec = 0xfacefeedU; rc = semtimedop(id, sem_b, 1, ts); printf("semtimedop(%d, [{0, 1, SEM_UNDO}], 1" ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n", id, (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec), sprintrc(rc)); sem_b->sem_op = -1; ts->tv_sec = (time_t) 0xcafef00ddeadbeefLL; ts->tv_nsec = (long) 0xbadc0dedfacefeedLL; rc = semtimedop(id, sem_b, 1, ts); printf("semtimedop(%d, [{0, -1, SEM_UNDO}], 1" ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n", id, (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec), sprintrc(rc)); puts("+++ exited with 0 +++"); return 0; }
int 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); #ifdef __GLIBC__ # define SEMCTL_BOGUS_ARG_FMT "(%#lx|\\[(%#lx|NULL)\\])" #else # define SEMCTL_BOGUS_ARG_FMT "(%#lx|\\[(%#lx|NULL)\\]|NULL)" #endif printf("semctl\\(%d, %d, (IPC_64\\|)?%#x /\\* SEM_\\?\\?\\? \\*/" ", " SEMCTL_BOGUS_ARG_FMT "\\) += %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"); printf("semctl\\(%d, 0, (IPC_64\\|)?IPC_STAT, \\[?%p\\]?\\) += 0\n", id, &ds); un.__buf = &info; rc = semctl(0, 0, SEM_INFO, un); printf("semctl\\(0, 0, (IPC_64\\|)?SEM_INFO, \\[?%p\\]?\\) += %s\n", &info, sprintrc_grep(rc)); un.buf = &ds; rc = semctl(id, 0, SEM_STAT, un); printf("semctl\\(%d, 0, (IPC_64\\|)?SEM_STAT, \\[?%p\\]?\\) += %s\n", id, &ds, sprintrc_grep(rc)); return 0; }
int main(void) { syscall(__NR_timer_settime, 0xdefaced, TIMER_ABSTIME, NULL, NULL); printf("timer_settime(%d, TIMER_ABSTIME, NULL, NULL)" " = -1 EINVAL (%m)\n", 0xdefaced); long rc; int tid; struct sigevent sev = { .sigev_notify = SIGEV_NONE }; if (syscall(__NR_timer_create, CLOCK_MONOTONIC, &sev, &tid)) perror_msg_and_skip("timer_create"); printf("timer_create(CLOCK_MONOTONIC, {sigev_signo=0" ", sigev_notify=SIGEV_NONE}, [%d]) = 0\n", tid); TAIL_ALLOC_OBJECT_CONST_PTR(struct itimerspec, its_new); TAIL_ALLOC_OBJECT_CONST_PTR(struct itimerspec, its_old); its_new->it_interval.tv_sec = 0xdeadbeefU; its_new->it_interval.tv_nsec = 0xfacefeedU; its_new->it_value.tv_sec = (time_t) 0xcafef00ddeadbeefLL; its_new->it_value.tv_nsec = (long) 0xbadc0dedfacefeedLL; rc = syscall(__NR_timer_settime, tid, 0, its_new, its_old); printf("timer_settime(%d, 0" ", {it_interval={tv_sec=%lld, tv_nsec=%llu}" ", it_value={tv_sec=%lld, tv_nsec=%llu}}, %p) = %s\n", tid, (long long) its_new->it_interval.tv_sec, zero_extend_signed_to_ull(its_new->it_interval.tv_nsec), (long long) its_new->it_value.tv_sec, zero_extend_signed_to_ull(its_new->it_value.tv_nsec), its_old, sprintrc(rc)); its_new->it_interval.tv_sec = 0xdeface1; its_new->it_interval.tv_nsec = 0xdeface2; its_new->it_value.tv_sec = 0xdeface3; its_new->it_value.tv_nsec = 0xdeface4; its_old->it_interval.tv_sec = 0xdeface5; its_old->it_interval.tv_nsec = 0xdeface6; its_old->it_value.tv_sec = 0xdeface7; its_old->it_value.tv_nsec = 0xdeface8; if (syscall(__NR_timer_settime, tid, 0, its_new, its_old)) perror_msg_and_skip("timer_settime"); printf("timer_settime(%d, 0" ", {it_interval={tv_sec=%lld, tv_nsec=%llu}" ", it_value={tv_sec=%lld, tv_nsec=%llu}}" ", {it_interval={tv_sec=%lld, tv_nsec=%llu}" ", it_value={tv_sec=%lld, tv_nsec=%llu}}" ") = 0\n", tid, (long long) its_new->it_interval.tv_sec, zero_extend_signed_to_ull(its_new->it_interval.tv_nsec), (long long) its_new->it_value.tv_sec, zero_extend_signed_to_ull(its_new->it_value.tv_nsec), (long long) its_old->it_interval.tv_sec, zero_extend_signed_to_ull(its_old->it_interval.tv_nsec), (long long) its_old->it_value.tv_sec, zero_extend_signed_to_ull(its_old->it_value.tv_nsec)); if (syscall(__NR_timer_gettime, tid, its_old)) perror_msg_and_skip("timer_gettime"); printf("timer_gettime(%d" ", {it_interval={tv_sec=%lld, tv_nsec=%llu}" ", it_value={tv_sec=%lld, tv_nsec=%llu}}) = 0\n", tid, (long long) its_old->it_interval.tv_sec, zero_extend_signed_to_ull(its_old->it_interval.tv_nsec), (long long) its_old->it_value.tv_sec, zero_extend_signed_to_ull(its_old->it_value.tv_nsec)); puts("+++ exited with 0 +++"); return 0; }
static const char * sprint_rusage(const struct rusage *const ru) { static char buf[1024]; snprintf(buf, sizeof(buf), "{ru_utime={tv_sec=%lld, tv_usec=%llu}" ", ru_stime={tv_sec=%lld, tv_usec=%llu}" #if VERBOSE ", ru_maxrss=%llu" ", ru_ixrss=%llu" ", ru_idrss=%llu" ", ru_isrss=%llu" ", ru_minflt=%llu" ", ru_majflt=%llu" ", ru_nswap=%llu" ", ru_inblock=%llu" ", ru_oublock=%llu" ", ru_msgsnd=%llu" ", ru_msgrcv=%llu" ", ru_nsignals=%llu" ", ru_nvcsw=%llu" ", ru_nivcsw=%llu}" #else ", ...}" #endif , (long long) ru->ru_utime.tv_sec , zero_extend_signed_to_ull(ru->ru_utime.tv_usec) , (long long) ru->ru_stime.tv_sec , zero_extend_signed_to_ull(ru->ru_stime.tv_usec) #if VERBOSE , zero_extend_signed_to_ull(ru->ru_maxrss) , zero_extend_signed_to_ull(ru->ru_ixrss) , zero_extend_signed_to_ull(ru->ru_idrss) , zero_extend_signed_to_ull(ru->ru_isrss) , zero_extend_signed_to_ull(ru->ru_minflt) , zero_extend_signed_to_ull(ru->ru_majflt) , zero_extend_signed_to_ull(ru->ru_nswap) , zero_extend_signed_to_ull(ru->ru_inblock) , zero_extend_signed_to_ull(ru->ru_oublock) , zero_extend_signed_to_ull(ru->ru_msgsnd) , zero_extend_signed_to_ull(ru->ru_msgrcv) , zero_extend_signed_to_ull(ru->ru_nsignals) , zero_extend_signed_to_ull(ru->ru_nvcsw) , zero_extend_signed_to_ull(ru->ru_nivcsw) #endif ); return buf; }
int main(void) { static const kernel_ulong_t bogus_zero = (kernel_ulong_t) 0x8765432100000000ULL; static const kernel_ulong_t bogus_oflags = (kernel_ulong_t) 0xdefaced100000003ULL; static const kernel_ulong_t bogus_mode = (kernel_ulong_t) 0xdec0deadfacefeedULL; static const kernel_ulong_t bogus_fd = (kernel_ulong_t) 0xfeedfacedeadba5eULL; static const kernel_ulong_t bogus_zero_size = (sizeof(kernel_ulong_t) > sizeof(int)) ? (kernel_ulong_t) 0 : (kernel_ulong_t) 0xface1e5500000000ULL; static const kernel_ulong_t bogus_size = (kernel_ulong_t) 0xbadc0dedda7a1057ULL; static const kernel_ulong_t bogus_prio = (kernel_ulong_t) 0xdec0ded1defaced3ULL; static const struct timespec bogus_tmout_data = { .tv_sec = (time_t) 0xdeadfacebeeff00dLL, .tv_nsec = (long) 0xfacefee1deadfeedLL, }; static const struct timespec future_tmout_data = { .tv_sec = (time_t) 0x7ea1fade7e57faceLL, .tv_nsec = 999999999, }; struct_sigevent bogus_sev_data = { .sigev_notify = 0xdefaced, .sigev_signo = 0xfacefeed, .sigev_value.sival_ptr = (unsigned long) 0xdeadbeefbadc0dedULL }; const char *errstr; long rc; kernel_long_t *bogus_attrs = tail_alloc(sizeof(*bogus_attrs) * NUM_ATTRS); char *msg = tail_alloc(MSG_SIZE); TAIL_ALLOC_OBJECT_CONST_PTR(unsigned, bogus_prio_ptr); struct timespec *bogus_tmout = tail_memdup(&bogus_tmout_data, sizeof(*bogus_tmout)); struct timespec *future_tmout = tail_memdup(&future_tmout_data, sizeof(*future_tmout)); struct_sigevent *bogus_sev = tail_memdup(&bogus_sev_data, sizeof(*bogus_sev)); int fd = -1; fill_memory_ex(msg, MSG_SIZE, MSG_START, MSG_SIZE); fill_memory_ex(bogus_attrs, sizeof(*bogus_attrs) * NUM_ATTRS, 0xbb, 0x70); /* mq_open */ /* Zero values, non-O_CREAT mode */ rc = syscall(__NR_mq_open, NULL, bogus_zero, bogus_mode, NULL); printf("mq_open(NULL, O_RDONLY) = %s\n", sprintrc(rc)); /* O_CREAT parsing, other flags, bogs values */ rc = syscall(__NR_mq_open, msg, O_CREAT | bogus_oflags, bogus_mode, NULL); printf("mq_open(%p, O_ACCMODE|O_CREAT, %#o, NULL) = %s\n", msg, (unsigned short) bogus_mode, sprintrc(rc)); /* Partially invalid attributes structure */ rc = syscall(__NR_mq_open, msg, O_CREAT | bogus_oflags, bogus_mode, bogus_attrs + 1); printf("mq_open(%p, O_ACCMODE|O_CREAT, %#o, %p) = %s\n", msg, (unsigned short) bogus_mode, bogus_attrs + 1, sprintrc(rc)); /* Valid attributes structure */ rc = syscall(__NR_mq_open, msg, O_CREAT | bogus_oflags, bogus_mode, bogus_attrs); printf("mq_open(%p, O_ACCMODE|O_CREAT, %#o, {mq_flags=%#llx" ", mq_maxmsg=%lld, mq_msgsize=%lld, mq_curmsgs=%lld}) = %s\n", msg, (unsigned short) bogus_mode, (unsigned long long) (kernel_ulong_t) bogus_attrs[0], (long long) bogus_attrs[1], (long long) bogus_attrs[2], (long long) bogus_attrs[3], sprintrc(rc)); /* mq_timedsend */ /* Zero values*/ rc = syscall(__NR_mq_timedsend, bogus_zero, NULL, bogus_zero_size, bogus_zero, NULL); printf("mq_timedsend(0, NULL, 0, 0, NULL) = %s\n", sprintrc(rc)); /* Invalid pointers */ rc = syscall(__NR_mq_timedsend, bogus_fd, msg + MSG_SIZE, bogus_size, bogus_prio, bogus_tmout + 1); printf("mq_timedsend(%d, %p, %llu, %u, %p) = %s\n", (int) bogus_fd, msg + MSG_SIZE, (unsigned long long) bogus_size, (unsigned) bogus_prio, bogus_tmout + 1, sprintrc(rc)); /* Partially invalid message (memory only partially available) */ rc = syscall(__NR_mq_timedsend, bogus_fd, msg + MSG_SIZE - MSG_CUT, MSG_SIZE, bogus_prio, bogus_tmout); printf("mq_timedsend(%d, %p, %llu, %u, {tv_sec=%lld, tv_nsec=%llu})" " = %s\n", (int) bogus_fd, msg + MSG_SIZE - MSG_CUT, (unsigned long long) MSG_SIZE, (unsigned) bogus_prio, (long long) bogus_tmout->tv_sec, zero_extend_signed_to_ull(bogus_tmout->tv_nsec), sprintrc(rc)); /* Fully valid message, uncut */ rc = syscall(__NR_mq_timedsend, bogus_fd, msg + MSG_SIZE - MSG_CUT, MSG_CUT, bogus_prio, bogus_tmout); errstr = sprintrc(rc); printf("mq_timedsend(%d, ", (int) bogus_fd); printstr(MSG_START + MSG_SIZE - MSG_CUT, MSG_CUT); printf(", %llu, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n", (unsigned long long) MSG_CUT, (unsigned) bogus_prio, (long long) bogus_tmout->tv_sec, zero_extend_signed_to_ull(bogus_tmout->tv_nsec), errstr); /* Partially invalid message, cut at maxstrlen */ rc = syscall(__NR_mq_timedsend, bogus_fd, msg + MSG_CUT, MSG_SIZE, bogus_prio, bogus_tmout); errstr = sprintrc(rc); printf("mq_timedsend(%d, ", (int) bogus_fd); printstr(MSG_START + MSG_CUT, MSG_MAX_UNCUT); printf("..., %llu, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n", (unsigned long long) MSG_SIZE, (unsigned) bogus_prio, (long long) bogus_tmout->tv_sec, zero_extend_signed_to_ull(bogus_tmout->tv_nsec), errstr); /* mq_timedreceive */ /* Zero values */ rc = syscall(__NR_mq_timedreceive, bogus_zero, NULL, bogus_zero_size, NULL, NULL); printf("mq_timedreceive(0, NULL, 0, NULL, NULL) = %s\n", sprintrc(rc)); /* Invalid addresses */ rc = syscall(__NR_mq_timedreceive, bogus_fd, msg + MSG_SIZE, bogus_size, bogus_prio_ptr + 1, bogus_tmout + 1); printf("mq_timedreceive(%d, %p, %llu, %p, %p) = %s\n", (int) bogus_fd, msg + MSG_SIZE, (unsigned long long) bogus_size, bogus_prio_ptr + 1, bogus_tmout + 1, sprintrc(rc)); /* Invalid fd, valid msg pointer */ rc = syscall(__NR_mq_timedreceive, bogus_fd, msg, bogus_size, bogus_prio_ptr, bogus_tmout); printf("mq_timedreceive(%d, %p, %llu, %p, {tv_sec=%lld, tv_nsec=%llu}) " "= %s\n", (int) bogus_fd, msg, (unsigned long long) bogus_size, bogus_prio_ptr, (long long) bogus_tmout->tv_sec, zero_extend_signed_to_ull(bogus_tmout->tv_nsec), sprintrc(rc)); /* mq_notify */ /* Zero values */ rc = syscall(__NR_mq_notify, bogus_zero, NULL); printf("mq_notify(0, NULL) = %s\n", sprintrc(rc)); /* Invalid pointer */ rc = syscall(__NR_mq_notify, bogus_fd, bogus_sev + 1); printf("mq_notify(%d, %p) = %s\n", (int) bogus_fd, bogus_sev + 1, sprintrc(rc)); /* Invalid SIGEV_* */ rc = syscall(__NR_mq_notify, bogus_fd, bogus_sev); printf("mq_notify(%d, {sigev_value={sival_int=%d, sival_ptr=%#lx}" ", sigev_signo=%u, sigev_notify=%#x /* SIGEV_??? */}) = %s\n", (int) bogus_fd, bogus_sev->sigev_value.sival_int, bogus_sev->sigev_value.sival_ptr, bogus_sev->sigev_signo, bogus_sev->sigev_notify, sprintrc(rc)); /* SIGEV_NONE */ bogus_sev->sigev_notify = SIGEV_NONE; rc = syscall(__NR_mq_notify, bogus_fd, bogus_sev); printf("mq_notify(%d, {sigev_value={sival_int=%d, sival_ptr=%#lx}" ", sigev_signo=%u, sigev_notify=SIGEV_NONE}) = %s\n", (int) bogus_fd, bogus_sev->sigev_value.sival_int, bogus_sev->sigev_value.sival_ptr, bogus_sev->sigev_signo, sprintrc(rc)); /* SIGEV_SIGNAL */ bogus_sev->sigev_notify = SIGEV_SIGNAL; bogus_sev->sigev_signo = SIGALRM; rc = syscall(__NR_mq_notify, bogus_fd, bogus_sev); printf("mq_notify(%d, {sigev_value={sival_int=%d, sival_ptr=%#lx}" ", sigev_signo=SIGALRM, sigev_notify=SIGEV_SIGNAL}) = %s\n", (int) bogus_fd, bogus_sev->sigev_value.sival_int, bogus_sev->sigev_value.sival_ptr, sprintrc(rc)); /* SIGEV_THREAD */ bogus_sev->sigev_notify = SIGEV_THREAD; bogus_sev->sigev_un.sigev_thread.function = (unsigned long) 0xdeadbeefbadc0dedULL; bogus_sev->sigev_un.sigev_thread.attribute = (unsigned long) 0xcafef00dfacefeedULL; rc = syscall(__NR_mq_notify, bogus_fd, bogus_sev); printf("mq_notify(%d, {sigev_value={sival_int=%d, sival_ptr=%#lx}" ", sigev_signo=SIGALRM, sigev_notify=SIGEV_THREAD" ", sigev_notify_function=%#lx, sigev_notify_attributes=%#lx})" " = %s\n", (int) bogus_fd, bogus_sev->sigev_value.sival_int, bogus_sev->sigev_value.sival_ptr, bogus_sev->sigev_un.sigev_thread.function, bogus_sev->sigev_un.sigev_thread.attribute, sprintrc(rc)); /* mq_unlink */ /* Zero values */ rc = syscall(__NR_mq_unlink, NULL); printf("mq_unlink(NULL) = %s\n", sprintrc(rc)); /* Invalid ptr */ rc = syscall(__NR_mq_unlink, msg + MSG_SIZE); printf("mq_unlink(%p) = %s\n", msg + MSG_SIZE, sprintrc(rc)); /* Long unterminated string */ rc = syscall(__NR_mq_unlink, msg); errstr = sprintrc(rc); printf("mq_unlink(%p) = %s\n", msg, errstr); /* Sending and receiving test */ if (asprintf(&mq_name, "strace-mq_sendrecv-%u.sample", getpid()) < 0) perror_msg_and_fail("asprintf"); # if DUMPIO_READ || DUMPIO_WRITE close(0); # endif bogus_attrs[1] = 2; bogus_attrs[2] = MSG_SIZE; fd = rc = syscall(__NR_mq_open, mq_name, O_CREAT|O_RDWR|O_NONBLOCK, S_IRWXU, bogus_attrs); errstr = sprintrc(rc); if (rc < 0) perror_msg_and_skip("mq_open"); else atexit(cleanup); # if DUMPIO_READ || DUMPIO_WRITE if (fd != 0) error_msg_and_skip("mq_open returned fd other than 0"); # endif fill_memory_ex(bogus_attrs, sizeof(*bogus_attrs) * NUM_ATTRS, 0xbb, 0x70); printf("mq_open(\"%s\", O_RDWR|O_CREAT|O_NONBLOCK, 0700" ", {mq_flags=%#llx, mq_maxmsg=2, mq_msgsize=%u" ", mq_curmsgs=%lld}) = %s\n", mq_name, (unsigned long long) (kernel_ulong_t) bogus_attrs[0], MSG_SIZE, (long long) bogus_attrs[3], errstr); rc = syscall(__NR_mq_getsetattr, fd, NULL, bogus_attrs); if (rc < 0) perror_msg_and_skip("mq_getsetattr"); if ((bogus_attrs[1] < 2) || (bogus_attrs[2] < MSG_SIZE)) error_msg_and_skip("mq too small"); do_send(fd, msg, MSG_CUT, future_tmout, false); do_send(fd, msg, MSG_SIZE, future_tmout, true); memset(msg, '\0', MSG_SIZE); do_recv(fd, msg, MSG_CUT, future_tmout, false); memset(msg, '\0', MSG_SIZE); do_recv(fd, msg, MSG_SIZE, future_tmout, true); return 0; } #else SKIP_MAIN_UNDEFINED("__NR_mq_open && __NR_mq_timedsend && " "__NR_mq_timedreceive && __NR_mq_notify && __NR_mq_unlink");