From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ua1-x92c.google.com (mail-ua1-x92c.google.com [IPv6:2607:f8b0:4864:20::92c]) by sourceware.org (Postfix) with ESMTPS id B2AB3385841A for ; Thu, 3 Feb 2022 17:46:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B2AB3385841A Received: by mail-ua1-x92c.google.com with SMTP id p7so6558930uao.6 for ; Thu, 03 Feb 2022 09:46:46 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9oKh6e4UkDEvIJGe7WOJPIhoX89Gk49s9kh5j718lDo=; b=ron5IlrSKnUnYaUpaGJvlruoMTaQNht7uoMAo4mt6RVSoon5wZ2HD/qljgzGwI5AUy Xygw9juhgVejiErNi/sNS8l1sABHHqM0mq67fT5wp5pYqDk+rQ0PmYeuPP0CTmSRtzxF stGlcnuObqDBqUW4i5stJ+J5ZO0mXysveEpKL02QahPc+2q0/yxbtxp94p1A4BNABhiG +5vxdTAknSWQndaIpLqoMg42/KZBu4SRzqyXCCWjrkDV/4Rzr7/z4s5uBCQr6SVQawfo ++d4nZdw5R1sc1LKXCT7Ux3Gii0osksfa4qkEOnMLVsA0TmFP4Nbvn7RsHGKR+jQUwGX +G8g== X-Gm-Message-State: AOAM533iR6bwfGRBJIYxbtF/szhYnnC/jICUfH6ojXdbJTcCX8giUgSJ 8omXJLXF6GlTE6o5ug+RlxtqlN7303q+Pg== X-Google-Smtp-Source: ABdhPJxo0od6qO9yoaU62eOuUF6T2AkSSevVWc6qM7Gu2GYYKHgvyIreeTFsu3NfBwxRvXC/R83/aw== X-Received: by 2002:ab0:3c86:: with SMTP id a6mr17086849uax.6.1643910405994; Thu, 03 Feb 2022 09:46:45 -0800 (PST) Received: from birita.. ([2804:431:c7ca:709a:22aa:9542:591f:6eb9]) by smtp.gmail.com with ESMTPSA id m25sm7294887uaq.3.2022.02.03.09.46.44 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Feb 2022 09:46:45 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 05/15] linux: Add tst-pidfd.c Date: Thu, 3 Feb 2022 14:46:24 -0300 Message-Id: <20220203174634.3474775-6-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220203174634.3474775-1-adhemerval.zanella@linaro.org> References: <20220203174634.3474775-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Feb 2022 17:46:48 -0000 To check for the pidfd functions pidfd_open, pidfd_getfd, pid_send_signal, and waitid with P_PIDFD. Checked on x86_64-linux-gnu and i686-linux-gnu. --- sysdeps/unix/sysv/linux/Makefile | 1 + sysdeps/unix/sysv/linux/tst-pidfd.c | 170 ++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/tst-pidfd.c diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 1c08f0918f..6fefcd8fe7 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -127,6 +127,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ tst-prctl \ tst-scm_rights \ tst-epoll \ + tst-pidfd \ # tests # Test for the symbol version of fcntl that was replaced in glibc 2.28. diff --git a/sysdeps/unix/sysv/linux/tst-pidfd.c b/sysdeps/unix/sysv/linux/tst-pidfd.c new file mode 100644 index 0000000000..267b071af4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-pidfd.c @@ -0,0 +1,170 @@ +/* Basic tests for Linux pidfd interfaces. + Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define REMOTE_PATH "/dev/null" + +/* The pair of sockets used for coordination. The subprocess uses + sockets[1]. */ +static int sockets[2]; + +static pid_t ppid; +static uid_t puid; + +static void +sighandler (int sig) +{ +} + +static void +subprocess (void) +{ + xsignal (SIGUSR1, sighandler); + xsignal (SIGUSR2, sighandler); + + /* Check first pidfd_send_signal with default NULL siginfo_t argument. */ + { + sigset_t set; + sigemptyset (&set); + sigaddset (&set, SIGUSR1); + siginfo_t info; + TEST_COMPARE (sigtimedwait (&set, &info, NULL), SIGUSR1); + TEST_COMPARE (info.si_signo, SIGUSR1); + TEST_COMPARE (info.si_errno, 0); + TEST_COMPARE (info.si_code, SI_USER); + TEST_COMPARE (info.si_pid, ppid); + TEST_COMPARE (info.si_uid, puid); + } + + /* Check second pidfd_send_signal with crafted siginfo_t argument. */ + { + sigset_t set; + sigemptyset (&set); + sigaddset (&set, SIGUSR2); + siginfo_t info; + TEST_COMPARE (sigtimedwait (&set, &info, NULL), SIGUSR2); + TEST_COMPARE (info.si_signo, SIGUSR2); + TEST_COMPARE (info.si_errno, EAGAIN); + TEST_COMPARE (info.si_code, -10); + TEST_COMPARE (info.si_pid, ppid); + TEST_COMPARE (info.si_uid, puid); + } + + /* Send a local file descriptor value to check pidfd_getfd. */ + int remote_fd = xopen (REMOTE_PATH, O_WRONLY | O_CLOEXEC, 0); + xsendto (sockets[1], &remote_fd, sizeof (remote_fd), 0, NULL, 0); + + /* Wait for final pidfd_send_signal. */ + pause (); + + _exit (0); +} + +static int +do_test (void) +{ + { + /* The pidfd_getfd was the last one added on Linux. */ + int r = pidfd_getfd (0, 0, 1); + TEST_VERIFY_EXIT (r == -1); + if (errno == ENOSYS) + FAIL_UNSUPPORTED ("kernel does not support pidfd_open, skipping test"); + } + + ppid = getpid (); + puid = getuid (); + + TEST_COMPARE (socketpair (AF_UNIX, SOCK_STREAM, 0, sockets), 0); + + pid_t pid = xfork (); + if (pid == 0) + { + xclose (sockets[0]); + subprocess (); + } + xclose (sockets[1]); + + TEST_COMPARE (pidfd_open (-1, 0), -1); + TEST_COMPARE (errno, EINVAL); + + int pidfd = pidfd_open (pid, 0); + TEST_VERIFY (pidfd != -1); + + /* Wait for first sigtimedwait. */ + support_process_state_wait (pid, support_process_state_sleeping); + TEST_COMPARE (pidfd_send_signal (pidfd, SIGUSR1, NULL, 0), 0); + + /* Wait for second sigtimedwait. */ + support_process_state_wait (pid, support_process_state_sleeping); + { + siginfo_t info = + { + .si_signo = SIGUSR2, + .si_errno = EAGAIN, + .si_code = -10, + .si_pid = ppid, + .si_uid = puid + }; + TEST_COMPARE (pidfd_send_signal (pidfd, SIGUSR2, &info, 0), 0); + } + + /* Get remote file descriptor to check for pidfd_getfd. */ + { + int remote_fd; + xrecvfrom (sockets[0], &remote_fd, sizeof (remote_fd), 0, NULL, 0); + + int fd = pidfd_getfd (pidfd, remote_fd, 0); + TEST_VERIFY (fd > 0); + + char *path = xasprintf ("/proc/%d/fd/%d", pid, remote_fd); + char *resolved = xreadlink (path); + TEST_COMPARE_STRING (resolved, REMOTE_PATH); + + int remote_fd_mode = fcntl (fd, F_GETFL); + TEST_VERIFY (remote_fd_mode != -1); + TEST_VERIFY (remote_fd_mode & O_WRONLY); + + int remote_fd_flags = fcntl (fd, F_GETFD); + TEST_VERIFY (remote_fd_flags != -1); + TEST_VERIFY (remote_fd_flags & FD_CLOEXEC); + } + + TEST_COMPARE (pidfd_send_signal (pidfd, SIGKILL, NULL, 0), 0); + { + siginfo_t info; + int r = waitid (P_PIDFD, pidfd, &info, WEXITED); + TEST_COMPARE (r, 0); + TEST_COMPARE (info.si_status, SIGKILL); + TEST_COMPARE (info.si_code, CLD_KILLED); + } + + return 0; +} + +#include -- 2.32.0