1d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes/* 239bac055674d23770b9a724221b728e443196ea7Elliott Hughes * Check decoding of ppoll syscall. 339bac055674d23770b9a724221b728e443196ea7Elliott Hughes * 439bac055674d23770b9a724221b728e443196ea7Elliott Hughes * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org> 5d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * All rights reserved. 6d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * 7d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * Redistribution and use in source and binary forms, with or without 8d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * modification, are permitted provided that the following conditions 9d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * are met: 10d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * 1. Redistributions of source code must retain the above copyright 11d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * notice, this list of conditions and the following disclaimer. 12d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * 2. Redistributions in binary form must reproduce the above copyright 13d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * notice, this list of conditions and the following disclaimer in the 14d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * documentation and/or other materials provided with the distribution. 15d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * 3. The name of the author may not be used to endorse or promote products 16d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * derived from this software without specific prior written permission. 17d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * 18d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes */ 29d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 30d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes#include "tests.h" 3139bac055674d23770b9a724221b728e443196ea7Elliott Hughes#include <asm/unistd.h> 3239bac055674d23770b9a724221b728e443196ea7Elliott Hughes 3339bac055674d23770b9a724221b728e443196ea7Elliott Hughes#ifdef __NR_ppoll 3439bac055674d23770b9a724221b728e443196ea7Elliott Hughes 3539bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <errno.h> 3639bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <poll.h> 3739bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <signal.h> 3839bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <stdio.h> 3939bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <string.h> 4039bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <unistd.h> 41d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 4239bac055674d23770b9a724221b728e443196ea7Elliott Hughesstatic const char *errstr; 4339bac055674d23770b9a724221b728e443196ea7Elliott Hughes 4439bac055674d23770b9a724221b728e443196ea7Elliott Hughesstatic long 4539bac055674d23770b9a724221b728e443196ea7Elliott Hughessys_ppoll(const kernel_ulong_t ufds, 4639bac055674d23770b9a724221b728e443196ea7Elliott Hughes const kernel_ulong_t nfds, 4739bac055674d23770b9a724221b728e443196ea7Elliott Hughes const kernel_ulong_t tsp, 4839bac055674d23770b9a724221b728e443196ea7Elliott Hughes const kernel_ulong_t sigmask, 4939bac055674d23770b9a724221b728e443196ea7Elliott Hughes const kernel_ulong_t sigsetsize) 50d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes{ 5139bac055674d23770b9a724221b728e443196ea7Elliott Hughes long rc = syscall(__NR_ppoll, ufds, nfds, tsp, sigmask, sigsetsize); 5239bac055674d23770b9a724221b728e443196ea7Elliott Hughes errstr = sprintrc(rc); 5339bac055674d23770b9a724221b728e443196ea7Elliott Hughes return rc; 5439bac055674d23770b9a724221b728e443196ea7Elliott Hughes} 55d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 5639bac055674d23770b9a724221b728e443196ea7Elliott Hughesint 5739bac055674d23770b9a724221b728e443196ea7Elliott Hughesmain(void) 5839bac055674d23770b9a724221b728e443196ea7Elliott Hughes{ 5939bac055674d23770b9a724221b728e443196ea7Elliott Hughes static const kernel_ulong_t bogus_nfds = 6039bac055674d23770b9a724221b728e443196ea7Elliott Hughes (kernel_ulong_t) 0xdeadbeeffacefeedULL; 6139bac055674d23770b9a724221b728e443196ea7Elliott Hughes static const kernel_ulong_t bogus_sigsetsize = 6239bac055674d23770b9a724221b728e443196ea7Elliott Hughes (kernel_ulong_t) 0xdeadbeefbadc0dedULL; 6339bac055674d23770b9a724221b728e443196ea7Elliott Hughes static const char *const POLLWRNORM_str = 6439bac055674d23770b9a724221b728e443196ea7Elliott Hughes (POLLWRNORM == POLLOUT) ? "" : "|POLLWRNORM"; 6539bac055674d23770b9a724221b728e443196ea7Elliott Hughes static const char *const USR2_CHLD_str = 6639bac055674d23770b9a724221b728e443196ea7Elliott Hughes (SIGUSR2 < SIGCHLD) ? "USR2 CHLD" : "CHLD USR2"; 6739bac055674d23770b9a724221b728e443196ea7Elliott Hughes void *const efault = tail_alloc(1024) + 1024; 6839bac055674d23770b9a724221b728e443196ea7Elliott Hughes TAIL_ALLOC_OBJECT_CONST_PTR(struct timespec, ts); 6939bac055674d23770b9a724221b728e443196ea7Elliott Hughes const unsigned int sigset_size = get_sigset_size(); 7039bac055674d23770b9a724221b728e443196ea7Elliott Hughes void *const sigmask = tail_alloc(sigset_size); 7139bac055674d23770b9a724221b728e443196ea7Elliott Hughes struct pollfd *fds; 72d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes sigset_t mask; 7339bac055674d23770b9a724221b728e443196ea7Elliott Hughes int pipe_fd[4]; 7439bac055674d23770b9a724221b728e443196ea7Elliott Hughes long rc; 7539bac055674d23770b9a724221b728e443196ea7Elliott Hughes 7639bac055674d23770b9a724221b728e443196ea7Elliott Hughes sys_ppoll(0, bogus_nfds, 0, 0, bogus_sigsetsize); 7739bac055674d23770b9a724221b728e443196ea7Elliott Hughes if (ENOSYS == errno) 7839bac055674d23770b9a724221b728e443196ea7Elliott Hughes perror_msg_and_skip("ppoll"); 7939bac055674d23770b9a724221b728e443196ea7Elliott Hughes printf("ppoll(NULL, %u, NULL, NULL, %llu) = %s\n", 8039bac055674d23770b9a724221b728e443196ea7Elliott Hughes (unsigned) bogus_nfds, (unsigned long long) bogus_sigsetsize, 8139bac055674d23770b9a724221b728e443196ea7Elliott Hughes errstr); 8239bac055674d23770b9a724221b728e443196ea7Elliott Hughes 8339bac055674d23770b9a724221b728e443196ea7Elliott Hughes sys_ppoll((unsigned long) efault, 42, (unsigned long) efault + 8, 8439bac055674d23770b9a724221b728e443196ea7Elliott Hughes (unsigned long) efault + 16, sigset_size); 8539bac055674d23770b9a724221b728e443196ea7Elliott Hughes printf("ppoll(%p, %u, %p, %p, %u) = %s\n", 8639bac055674d23770b9a724221b728e443196ea7Elliott Hughes efault, 42, efault + 8, efault + 16, sigset_size, errstr); 8739bac055674d23770b9a724221b728e443196ea7Elliott Hughes 8839bac055674d23770b9a724221b728e443196ea7Elliott Hughes ts->tv_sec = 0xdeadbeefU; 8939bac055674d23770b9a724221b728e443196ea7Elliott Hughes ts->tv_nsec = 0xfacefeedU; 9039bac055674d23770b9a724221b728e443196ea7Elliott Hughes sys_ppoll(0, 0, (unsigned long) ts, 0, sigset_size); 9139bac055674d23770b9a724221b728e443196ea7Elliott Hughes printf("ppoll(NULL, 0, {tv_sec=%lld, tv_nsec=%llu}, NULL, %u) = %s\n", 9239bac055674d23770b9a724221b728e443196ea7Elliott Hughes (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec), 9339bac055674d23770b9a724221b728e443196ea7Elliott Hughes sigset_size, errstr); 9439bac055674d23770b9a724221b728e443196ea7Elliott Hughes 9539bac055674d23770b9a724221b728e443196ea7Elliott Hughes ts->tv_sec = (time_t) 0xcafef00ddeadbeefLL; 9639bac055674d23770b9a724221b728e443196ea7Elliott Hughes ts->tv_nsec = (long) 0xbadc0dedfacefeedL; 9739bac055674d23770b9a724221b728e443196ea7Elliott Hughes sys_ppoll(0, 0, (unsigned long) ts, 0, sigset_size); 9839bac055674d23770b9a724221b728e443196ea7Elliott Hughes printf("ppoll(NULL, 0, {tv_sec=%lld, tv_nsec=%llu}, NULL, %u) = %s\n", 9939bac055674d23770b9a724221b728e443196ea7Elliott Hughes (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec), 10039bac055674d23770b9a724221b728e443196ea7Elliott Hughes sigset_size, errstr); 10139bac055674d23770b9a724221b728e443196ea7Elliott Hughes 10239bac055674d23770b9a724221b728e443196ea7Elliott Hughes if (pipe(pipe_fd) || pipe(pipe_fd + 2)) 10339bac055674d23770b9a724221b728e443196ea7Elliott Hughes perror_msg_and_fail("pipe"); 10439bac055674d23770b9a724221b728e443196ea7Elliott Hughes 10539bac055674d23770b9a724221b728e443196ea7Elliott Hughes ts->tv_sec = 42; 10639bac055674d23770b9a724221b728e443196ea7Elliott Hughes ts->tv_nsec = 999999999; 10739bac055674d23770b9a724221b728e443196ea7Elliott Hughes 10839bac055674d23770b9a724221b728e443196ea7Elliott Hughes const struct pollfd fds1[] = { 10939bac055674d23770b9a724221b728e443196ea7Elliott Hughes { .fd = pipe_fd[0], .events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND }, 11039bac055674d23770b9a724221b728e443196ea7Elliott Hughes { .fd = pipe_fd[1], .events = POLLOUT | POLLWRNORM | POLLWRBAND }, 11139bac055674d23770b9a724221b728e443196ea7Elliott Hughes { .fd = pipe_fd[2], .events = POLLIN | POLLPRI }, 11239bac055674d23770b9a724221b728e443196ea7Elliott Hughes { .fd = pipe_fd[3], .events = POLLOUT } 11339bac055674d23770b9a724221b728e443196ea7Elliott Hughes }; 11439bac055674d23770b9a724221b728e443196ea7Elliott Hughes fds = efault - sizeof(fds1); 11539bac055674d23770b9a724221b728e443196ea7Elliott Hughes memcpy(fds, fds1, sizeof(fds1)); 11639bac055674d23770b9a724221b728e443196ea7Elliott Hughes 117d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes sigemptyset(&mask); 118d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes sigaddset(&mask, SIGUSR2); 119d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes sigaddset(&mask, SIGCHLD); 12039bac055674d23770b9a724221b728e443196ea7Elliott Hughes memcpy(sigmask, &mask, sigset_size); 121d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 12239bac055674d23770b9a724221b728e443196ea7Elliott Hughes rc = sys_ppoll((unsigned long) fds, 12339bac055674d23770b9a724221b728e443196ea7Elliott Hughes F8ILL_KULONG_MASK | ARRAY_SIZE(fds1), (unsigned long) ts, 12439bac055674d23770b9a724221b728e443196ea7Elliott Hughes (unsigned long) sigmask, sigset_size); 12539bac055674d23770b9a724221b728e443196ea7Elliott Hughes if (rc != 2) 12639bac055674d23770b9a724221b728e443196ea7Elliott Hughes perror_msg_and_fail("ppoll 1"); 12739bac055674d23770b9a724221b728e443196ea7Elliott Hughes printf("ppoll([{fd=%d, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}" 12839bac055674d23770b9a724221b728e443196ea7Elliott Hughes ", {fd=%d, events=POLLOUT%s|POLLWRBAND}" 12939bac055674d23770b9a724221b728e443196ea7Elliott Hughes#if VERBOSE 13039bac055674d23770b9a724221b728e443196ea7Elliott Hughes ", {fd=%d, events=POLLIN|POLLPRI}, {fd=%d, events=POLLOUT}]" 13139bac055674d23770b9a724221b728e443196ea7Elliott Hughes#else 13239bac055674d23770b9a724221b728e443196ea7Elliott Hughes ", ...]" 13339bac055674d23770b9a724221b728e443196ea7Elliott Hughes#endif 13439bac055674d23770b9a724221b728e443196ea7Elliott Hughes ", %u, {tv_sec=42, tv_nsec=999999999}, [%s], %u) = %ld" 13539bac055674d23770b9a724221b728e443196ea7Elliott Hughes " ([{fd=%d, revents=POLLOUT%s}, {fd=%d, revents=POLLOUT}]" 13639bac055674d23770b9a724221b728e443196ea7Elliott Hughes ", left {tv_sec=%u, tv_nsec=%u})\n", 13739bac055674d23770b9a724221b728e443196ea7Elliott Hughes pipe_fd[0], pipe_fd[1], POLLWRNORM_str, 13839bac055674d23770b9a724221b728e443196ea7Elliott Hughes#if VERBOSE 13939bac055674d23770b9a724221b728e443196ea7Elliott Hughes pipe_fd[2], pipe_fd[3], 14039bac055674d23770b9a724221b728e443196ea7Elliott Hughes#endif 141dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned int) ARRAY_SIZE(fds1), USR2_CHLD_str, 142dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned int) sigset_size, rc, pipe_fd[1], POLLWRNORM_str, 143dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes pipe_fd[3], (unsigned int) ts->tv_sec, 144dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes (unsigned int) ts->tv_nsec); 145d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 14639bac055674d23770b9a724221b728e443196ea7Elliott Hughes ts->tv_sec = 0; 14739bac055674d23770b9a724221b728e443196ea7Elliott Hughes ts->tv_nsec = 999; 14839bac055674d23770b9a724221b728e443196ea7Elliott Hughes const struct pollfd fds2[] = { 14939bac055674d23770b9a724221b728e443196ea7Elliott Hughes { .fd = pipe_fd[1], .events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND }, 15039bac055674d23770b9a724221b728e443196ea7Elliott Hughes { .fd = pipe_fd[0], .events = POLLOUT | POLLWRNORM | POLLWRBAND } 151d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes }; 15239bac055674d23770b9a724221b728e443196ea7Elliott Hughes fds = efault - sizeof(fds2); 15339bac055674d23770b9a724221b728e443196ea7Elliott Hughes memcpy(fds, fds2, sizeof(fds2)); 154d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 15539bac055674d23770b9a724221b728e443196ea7Elliott Hughes memset(&mask, -1, sizeof(mask)); 156d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes sigdelset(&mask, SIGHUP); 157d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes sigdelset(&mask, SIGKILL); 158d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes sigdelset(&mask, SIGSTOP); 15939bac055674d23770b9a724221b728e443196ea7Elliott Hughes memcpy(sigmask, &mask, sigset_size); 160d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 16139bac055674d23770b9a724221b728e443196ea7Elliott Hughes rc = sys_ppoll((unsigned long) fds, 16239bac055674d23770b9a724221b728e443196ea7Elliott Hughes F8ILL_KULONG_MASK | ARRAY_SIZE(fds2), (unsigned long) ts, 16339bac055674d23770b9a724221b728e443196ea7Elliott Hughes (unsigned long) sigmask, sigset_size); 16439bac055674d23770b9a724221b728e443196ea7Elliott Hughes if (rc != 0) 16539bac055674d23770b9a724221b728e443196ea7Elliott Hughes perror_msg_and_fail("ppoll 2"); 16639bac055674d23770b9a724221b728e443196ea7Elliott Hughes printf("ppoll([{fd=%d, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}" 16739bac055674d23770b9a724221b728e443196ea7Elliott Hughes ", {fd=%d, events=POLLOUT%s|POLLWRBAND}], %u" 16839bac055674d23770b9a724221b728e443196ea7Elliott Hughes ", {tv_sec=0, tv_nsec=999}, ~[HUP KILL STOP], %u)" 16939bac055674d23770b9a724221b728e443196ea7Elliott Hughes " = %ld (Timeout)\n", 17039bac055674d23770b9a724221b728e443196ea7Elliott Hughes pipe_fd[1], pipe_fd[0], POLLWRNORM_str, 17139bac055674d23770b9a724221b728e443196ea7Elliott Hughes (unsigned) ARRAY_SIZE(fds2), sigset_size, rc); 172d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 17339bac055674d23770b9a724221b728e443196ea7Elliott Hughes if (F8ILL_KULONG_SUPPORTED) { 17439bac055674d23770b9a724221b728e443196ea7Elliott Hughes sys_ppoll(f8ill_ptr_to_kulong(fds), ARRAY_SIZE(fds2), 17539bac055674d23770b9a724221b728e443196ea7Elliott Hughes f8ill_ptr_to_kulong(ts), f8ill_ptr_to_kulong(sigmask), 17639bac055674d23770b9a724221b728e443196ea7Elliott Hughes sigset_size); 17739bac055674d23770b9a724221b728e443196ea7Elliott Hughes printf("ppoll(%#llx, %u, %#llx, %#llx, %u) = %s\n", 17839bac055674d23770b9a724221b728e443196ea7Elliott Hughes (unsigned long long) f8ill_ptr_to_kulong(fds), 17939bac055674d23770b9a724221b728e443196ea7Elliott Hughes (unsigned) ARRAY_SIZE(fds2), 18039bac055674d23770b9a724221b728e443196ea7Elliott Hughes (unsigned long long) f8ill_ptr_to_kulong(ts), 18139bac055674d23770b9a724221b728e443196ea7Elliott Hughes (unsigned long long) f8ill_ptr_to_kulong(sigmask), 18239bac055674d23770b9a724221b728e443196ea7Elliott Hughes (unsigned) sigset_size, errstr); 18339bac055674d23770b9a724221b728e443196ea7Elliott Hughes } 184d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 18539bac055674d23770b9a724221b728e443196ea7Elliott Hughes puts("+++ exited with 0 +++"); 186d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes return 0; 187d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes} 18839bac055674d23770b9a724221b728e443196ea7Elliott Hughes 18939bac055674d23770b9a724221b728e443196ea7Elliott Hughes#else 19039bac055674d23770b9a724221b728e443196ea7Elliott Hughes 19139bac055674d23770b9a724221b728e443196ea7Elliott HughesSKIP_MAIN_UNDEFINED("__NR_ppoll") 19239bac055674d23770b9a724221b728e443196ea7Elliott Hughes 19339bac055674d23770b9a724221b728e443196ea7Elliott Hughes#endif 194