1 /* 2 * This file is part of execveat strace test. 3 * 4 * Copyright (c) 2015-2016 Dmitry V. Levin <ldv (at) altlinux.org> 5 * Copyright (c) 2015-2017 The strace developers. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "tests.h" 32 #include <asm/unistd.h> 33 #include "scno.h" 34 35 #ifdef __NR_execveat 36 37 # include <stdio.h> 38 # include <unistd.h> 39 40 # define FILENAME "test.execveat\nfilename" 41 # define Q_FILENAME "test.execveat\\nfilename" 42 43 static const char * const argv[] = { 44 FILENAME, "first", "second", (const char *) -1L, 45 (const char *) -2L, (const char *) -3L 46 }; 47 static const char * const q_argv[] = { 48 Q_FILENAME, "first", "second" 49 }; 50 51 static const char * const envp[] = { 52 "foobar=1", "foo\nbar=2", (const char *) -1L, 53 (const char *) -2L, (const char *) -3L 54 }; 55 static const char * const q_envp[] = { 56 "foobar=1", "foo\\nbar=2" 57 }; 58 59 int 60 main(void) 61 { 62 const char ** const tail_argv = tail_memdup(argv, sizeof(argv)); 63 const char ** const tail_envp = tail_memdup(envp, sizeof(envp)); 64 65 syscall(__NR_execveat, -100, FILENAME, tail_argv, tail_envp, 0x1100); 66 printf("execveat(AT_FDCWD, \"%s\"" 67 ", [\"%s\", \"%s\", \"%s\", %p, %p, %p, ???]" 68 #if VERBOSE 69 ", [\"%s\", \"%s\", %p, %p, %p, ???]" 70 #else 71 ", %p /* 5 vars, unterminated */" 72 #endif 73 ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 74 Q_FILENAME, q_argv[0], q_argv[1], q_argv[2], 75 argv[3], argv[4], argv[5], 76 #if VERBOSE 77 q_envp[0], q_envp[1], envp[2], envp[3], envp[4], 78 #else 79 tail_envp, 80 #endif 81 errno2name()); 82 83 tail_argv[ARRAY_SIZE(q_argv)] = NULL; 84 tail_envp[ARRAY_SIZE(q_envp)] = NULL; 85 86 syscall(__NR_execveat, -100, FILENAME, tail_argv, tail_envp, 0x1100); 87 printf("execveat(AT_FDCWD, \"%s\", [\"%s\", \"%s\", \"%s\"]" 88 #if VERBOSE 89 ", [\"%s\", \"%s\"]" 90 #else 91 ", %p /* 2 vars */" 92 #endif 93 ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 94 Q_FILENAME, q_argv[0], q_argv[1], q_argv[2], 95 #if VERBOSE 96 q_envp[0], q_envp[1], 97 #else 98 tail_envp, 99 #endif 100 errno2name()); 101 102 syscall(__NR_execveat, -100, FILENAME, tail_argv + 2, tail_envp + 1, 0x1100); 103 printf("execveat(AT_FDCWD, \"%s\", [\"%s\"]" 104 #if VERBOSE 105 ", [\"%s\"]" 106 #else 107 ", %p /* 1 var */" 108 #endif 109 ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 110 Q_FILENAME, q_argv[2], 111 #if VERBOSE 112 q_envp[1], 113 #else 114 tail_envp + 1, 115 #endif 116 errno2name()); 117 118 TAIL_ALLOC_OBJECT_CONST_PTR(char *, empty); 119 char **const efault = empty + 1; 120 *empty = NULL; 121 122 syscall(__NR_execveat, -100, FILENAME, empty, empty, 0x1100); 123 printf("execveat(AT_FDCWD, \"%s\", []" 124 #if VERBOSE 125 ", []" 126 #else 127 ", %p /* 0 vars */" 128 #endif 129 ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 130 Q_FILENAME, 131 #if !VERBOSE 132 empty, 133 #endif 134 errno2name()); 135 136 char *const str_a = tail_alloc(DEFAULT_STRLEN + 2); 137 fill_memory_ex(str_a, DEFAULT_STRLEN + 1, '0', 10); 138 str_a[DEFAULT_STRLEN + 1] = '\0'; 139 140 char *const str_b = tail_alloc(DEFAULT_STRLEN + 2); 141 fill_memory_ex(str_b, DEFAULT_STRLEN + 1, '_', 32); 142 str_b[DEFAULT_STRLEN + 1] = '\0'; 143 144 char **const a = tail_alloc(sizeof(*a) * (DEFAULT_STRLEN + 2)); 145 char **const b = tail_alloc(sizeof(*b) * (DEFAULT_STRLEN + 2)); 146 unsigned int i; 147 for (i = 0; i <= DEFAULT_STRLEN; ++i) { 148 a[i] = &str_a[i]; 149 b[i] = &str_b[i]; 150 } 151 a[i] = b[i] = NULL; 152 153 syscall(__NR_execveat, -100, FILENAME, a, b, 0x1100); 154 printf("execveat(AT_FDCWD, \"%s\", [\"%.*s\"...", Q_FILENAME, DEFAULT_STRLEN, a[0]); 155 for (i = 1; i < DEFAULT_STRLEN; ++i) 156 printf(", \"%s\"", a[i]); 157 #if VERBOSE 158 printf(", \"%s\"", a[i]); 159 #else 160 printf(", ..."); 161 #endif 162 #if VERBOSE 163 printf("], [\"%.*s\"...", DEFAULT_STRLEN, b[0]); 164 for (i = 1; i <= DEFAULT_STRLEN; ++i) 165 printf(", \"%s\"", b[i]); 166 printf("]"); 167 #else 168 printf("], %p /* %u vars */", b, DEFAULT_STRLEN + 1); 169 #endif 170 printf(", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 171 errno2name()); 172 173 syscall(__NR_execveat, -100, FILENAME, a + 1, b + 1, 0x1100); 174 printf("execveat(AT_FDCWD, \"%s\", [\"%s\"", Q_FILENAME, a[1]); 175 for (i = 2; i <= DEFAULT_STRLEN; ++i) 176 printf(", \"%s\"", a[i]); 177 #if VERBOSE 178 printf("], [\"%s\"", b[1]); 179 for (i = 2; i <= DEFAULT_STRLEN; ++i) 180 printf(", \"%s\"", b[i]); 181 printf("]"); 182 #else 183 printf("], %p /* %d vars */", b + 1, DEFAULT_STRLEN); 184 #endif 185 printf(", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 186 errno2name()); 187 188 syscall(__NR_execveat, -100, FILENAME, NULL, efault, 0x1100); 189 printf("execveat(AT_FDCWD, \"%s\", NULL, %p" 190 ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 191 Q_FILENAME, efault, errno2name()); 192 193 syscall(__NR_execveat, -100, FILENAME, efault, NULL, 0x1100); 194 printf("execveat(AT_FDCWD, \"%s\", %p, NULL" 195 ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 196 Q_FILENAME, efault, errno2name()); 197 198 puts("+++ exited with 0 +++"); 199 return 0; 200 } 201 202 #else 203 204 SKIP_MAIN_UNDEFINED("__NR_execveat") 205 206 #endif 207