1 /* 2 * Copyright (c) International Business Machines Corp., 2008 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation; either version 2 of the License, or 6 * (at your option) any later version. 7 * This program is distributed in the hope that it will be useful 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 10 * the GNU General Public License for more details. 11 * You should have received a copy of the GNU General Public License 12 * along with this program; if not, write to the Free Software 13 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 14 15 ************************************************************************* 16 * Description: 17 * Testcase tries killing of the parent namespace pid by the container-init. 18 * It also tries killing of non-existent PID, by the container-init. 19 * Returns Success if Unable to kill, and proper error number is set. 20 * else Returns Failure 21 * 22 * Steps: 23 * 1. Parent process clone a process with flag CLONE_NEWPID 24 * 2. The pid of the parent namespace is passed to the container. 25 * 3. Container receieves the PID and passes SIGKILL to this PID. 26 * 4. If kill() is unsuccessful and the errno is set to 'No Such process' 27 * then sets PASS 28 * else, 29 * sets FAIL 30 * 5. It also verifies by passing SIGKILL to FAKE_PID 31 * 6. If kill() is unsuccessful and the errno is set to 'No Such process' 32 * then sets PASS 33 * else, 34 * sets FAIL 35 * 36 *******************************************************************************/ 37 #define _GNU_SOURCE 1 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <sys/wait.h> 41 #include <assert.h> 42 #include <unistd.h> 43 #include <errno.h> 44 #include "test.h" 45 #include <libclone.h> 46 #include <signal.h> 47 #include "pidns_helper.h" 48 49 #define CINIT_PID 1 50 #define PARENT_PID 0 51 #define FAKE_PID -1 52 53 char *TCID = "pidns06"; 54 int TST_TOTAL = 1; 55 56 /* 57 * kill_pid_in_childfun() 58 * Cont-init tries to kill the parent-process using parent's global Pid. 59 * Also checks passing SIGKILL to non existent PID in the container. 60 */ 61 static int kill_pid_in_childfun(void *vtest) 62 { 63 int cpid, ppid, *par_pid; 64 int ret = 0; 65 cpid = getpid(); 66 ppid = getppid(); 67 par_pid = (int *)vtest; 68 69 /* Checking the values to make sure pidns is created correctly */ 70 if (cpid != CINIT_PID || ppid != PARENT_PID) { 71 printf("Unexpected result for Container: init " 72 "pid=%d ppid=%d\n", cpid, ppid); 73 exit(1); 74 } 75 76 /* 77 * While trying kill() of the pid of the parent namespace.. 78 * Check to see if the errno was set to the expected, value of 3 : ESRCH 79 */ 80 ret = kill(*par_pid, SIGKILL); 81 if (ret == -1 && errno == ESRCH) { 82 printf("Container: killing parent pid=%d failed as expected " 83 "with ESRCH\n", *par_pid); 84 } else { 85 printf("Container: killing parent pid=%d, didn't fail as " 86 "expected with ESRCH (%d) and a return value of -1. Got " 87 "%d (\"%s\") and a return value of %d instead.\n", 88 *par_pid, ESRCH, errno, strerror(errno), ret); 89 exit(1); 90 } 91 /* 92 * While killing non-existent pid in the container, 93 * Check to see if the errno was set to the expected, value of 3 : ESRCH 94 */ 95 ret = kill(FAKE_PID, SIGKILL); 96 if (ret == -1 && errno == ESRCH) { 97 printf("Container: killing non-existent pid failed as expected " 98 "with ESRCH\n"); 99 } else { 100 printf("Container: killing non-existent pid, didn't fail as " 101 "expected with ESRCH (%d) and a return value of -1. Got " 102 "%d (\"%s\") and a return value of %d instead.\n", 103 ESRCH, errno, strerror(errno), ret); 104 exit(1); 105 } 106 107 exit(0); 108 } 109 110 static void setup(void) 111 { 112 tst_require_root(); 113 check_newpid(); 114 } 115 116 int main() 117 { 118 int status; 119 120 setup(); 121 122 pid_t pid = getpid(); 123 124 tst_resm(TINFO, "Parent: Passing the pid of the process %d", pid); 125 TEST(do_clone_unshare_test(T_CLONE, CLONE_NEWPID, kill_pid_in_childfun, 126 (void *)&pid)); 127 if (TEST_RETURN == -1) { 128 tst_brkm(TFAIL | TERRNO, NULL, "clone failed"); 129 } else if (wait(&status) == -1) { 130 tst_brkm(TFAIL | TERRNO, NULL, "wait failed"); 131 } 132 133 tst_exit(); 134 } 135