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 <signal.h> 45 #include "pidns_helper.h" 46 #include "test.h" 47 48 #define CINIT_PID 1 49 #define PARENT_PID 0 50 #define FAKE_PID -1 51 52 char *TCID = "pidns06"; 53 int TST_TOTAL = 1; 54 55 /* 56 * kill_pid_in_childfun() 57 * Cont-init tries to kill the parent-process using parent's global Pid. 58 * Also checks passing SIGKILL to non existent PID in the container. 59 */ 60 static int kill_pid_in_childfun(void *vtest) 61 { 62 int cpid, ppid, *par_pid; 63 int ret = 0; 64 cpid = getpid(); 65 ppid = getppid(); 66 par_pid = (int *)vtest; 67 68 /* Checking the values to make sure pidns is created correctly */ 69 if (cpid != CINIT_PID || ppid != PARENT_PID) { 70 printf("Unexpected result for Container: init " 71 "pid=%d ppid=%d\n", cpid, ppid); 72 exit(1); 73 } 74 75 /* 76 * While trying kill() of the pid of the parent namespace.. 77 * Check to see if the errno was set to the expected, value of 3 : ESRCH 78 */ 79 ret = kill(*par_pid, SIGKILL); 80 if (ret == -1 && errno == ESRCH) { 81 printf("Container: killing parent pid=%d failed as expected " 82 "with ESRCH\n", *par_pid); 83 } else { 84 printf("Container: killing parent pid=%d, didn't fail as " 85 "expected with ESRCH (%d) and a return value of -1. Got " 86 "%d (\"%s\") and a return value of %d instead.\n", 87 *par_pid, ESRCH, errno, strerror(errno), ret); 88 exit(1); 89 } 90 /* 91 * While killing non-existent pid in the container, 92 * Check to see if the errno was set to the expected, value of 3 : ESRCH 93 */ 94 ret = kill(FAKE_PID, SIGKILL); 95 if (ret == -1 && errno == ESRCH) { 96 printf("Container: killing non-existent pid failed as expected " 97 "with ESRCH\n"); 98 } else { 99 printf("Container: killing non-existent pid, didn't fail as " 100 "expected with ESRCH (%d) and a return value of -1. Got " 101 "%d (\"%s\") and a return value of %d instead.\n", 102 ESRCH, errno, strerror(errno), ret); 103 exit(1); 104 } 105 106 exit(0); 107 } 108 109 static void setup(void) 110 { 111 tst_require_root(); 112 check_newpid(); 113 } 114 115 int main() 116 { 117 int status; 118 119 setup(); 120 121 pid_t pid = getpid(); 122 123 tst_resm(TINFO, "Parent: Passing the pid of the process %d", pid); 124 TEST(do_clone_unshare_test(T_CLONE, CLONE_NEWPID, kill_pid_in_childfun, 125 (void *)&pid)); 126 if (TEST_RETURN == -1) { 127 tst_brkm(TFAIL | TERRNO, NULL, "clone failed"); 128 } else if (wait(&status) == -1) { 129 tst_brkm(TFAIL | TERRNO, NULL, "wait failed"); 130 } 131 132 tst_exit(); 133 } 134