1 /* 2 * Copyright (c) International Business Machines Corp., 2001 3 * Copyright (c) 2015 Cyril Hrubis <chrubis (at) suse.cz> 4 * 5 * 07/2001 Ported by Wayne Boyer 6 * 21/04/2008 Renaud Lottiaux (Renaud.Lottiaux (at) kerlabs.com) 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 16 * the GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 /* 24 * Attempt to execve(2) an executable owned by root with no execute permissions 25 * for the other users, fails when execve(2) is used as a non-root user, the 26 * errno should be EACCES. 27 */ 28 29 #ifndef _GNU_SOURCE 30 #define _GNU_SOURCE 31 #endif 32 #include <sys/types.h> 33 #include <sys/stat.h> 34 #include <sys/wait.h> 35 #include <errno.h> 36 #include <libgen.h> 37 #include <pwd.h> 38 #include <stdio.h> 39 #include <string.h> 40 #include <unistd.h> 41 42 #include "test.h" 43 #include "safe_macros.h" 44 45 char *TCID = "execve02"; 46 int TST_TOTAL = 1; 47 48 #define TEST_APP "execve_child" 49 #define USER_NAME "nobody" 50 51 static void setup(void); 52 static void cleanup(void); 53 54 static uid_t nobody_uid; 55 56 static void do_child(void) 57 { 58 char *argv[2] = {TEST_APP, NULL}; 59 60 SAFE_SETEUID(NULL, nobody_uid); 61 62 TEST(execve(TEST_APP, argv, NULL)); 63 64 if (!TEST_RETURN) 65 tst_brkm(TFAIL, NULL, "execve() passed unexpectedly"); 66 67 if (TEST_ERRNO != EACCES) { 68 tst_brkm(TFAIL | TTERRNO, NULL, 69 "execve() failed unexpectedly"); 70 } 71 72 tst_resm(TPASS | TTERRNO, "execve() failed expectedly"); 73 tst_exit(); 74 } 75 76 int main(int ac, char **av) 77 { 78 int lc; 79 pid_t pid; 80 81 tst_parse_opts(ac, av, NULL, NULL); 82 83 setup(); 84 85 for (lc = 0; TEST_LOOPING(lc); lc++) { 86 87 if ((pid = FORK_OR_VFORK()) == -1) 88 tst_brkm(TBROK | TERRNO, cleanup, "fork failed"); 89 90 if (pid == 0) 91 do_child(); 92 93 tst_record_childstatus(cleanup, pid); 94 } 95 96 cleanup(); 97 tst_exit(); 98 } 99 100 static void setup(void) 101 { 102 char path[PATH_MAX]; 103 struct passwd *pwd; 104 105 tst_require_root(); 106 107 if (tst_get_path(TEST_APP, path, sizeof(path))) { 108 tst_brkm(TBROK, NULL, 109 "Couldn't found "TEST_APP" binary in $PATH"); 110 } 111 112 tst_tmpdir(); 113 114 SAFE_CP(tst_rmdir, path, "."); 115 SAFE_CHMOD(cleanup, TEST_APP, 0700); 116 117 pwd = SAFE_GETPWNAM(tst_rmdir, USER_NAME); 118 nobody_uid = pwd->pw_uid; 119 } 120 121 void cleanup(void) 122 { 123 tst_rmdir(); 124 } 125