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-2018 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, ... /* %p */]" 68 #if VERBOSE 69 ", [\"%s\", \"%s\", %p, %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], (char *) tail_argv + sizeof(argv), 76 #if VERBOSE 77 q_envp[0], q_envp[1], envp[2], envp[3], envp[4], 78 (char *) tail_envp + sizeof(envp), 79 #else 80 tail_envp, 81 #endif 82 errno2name()); 83 84 tail_argv[ARRAY_SIZE(q_argv)] = NULL; 85 tail_envp[ARRAY_SIZE(q_envp)] = NULL; 86 (void) q_envp; /* workaround for clang bug #33068 */ 87 88 syscall(__NR_execveat, -100, FILENAME, tail_argv, tail_envp, 0x1100); 89 printf("execveat(AT_FDCWD, \"%s\", [\"%s\", \"%s\", \"%s\"]" 90 #if VERBOSE 91 ", [\"%s\", \"%s\"]" 92 #else 93 ", %p /* 2 vars */" 94 #endif 95 ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 96 Q_FILENAME, q_argv[0], q_argv[1], q_argv[2], 97 #if VERBOSE 98 q_envp[0], q_envp[1], 99 #else 100 tail_envp, 101 #endif 102 errno2name()); 103 104 syscall(__NR_execveat, -100, FILENAME, tail_argv + 2, tail_envp + 1, 0x1100); 105 printf("execveat(AT_FDCWD, \"%s\", [\"%s\"]" 106 #if VERBOSE 107 ", [\"%s\"]" 108 #else 109 ", %p /* 1 var */" 110 #endif 111 ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 112 Q_FILENAME, q_argv[2], 113 #if VERBOSE 114 q_envp[1], 115 #else 116 tail_envp + 1, 117 #endif 118 errno2name()); 119 120 TAIL_ALLOC_OBJECT_CONST_PTR(char *, empty); 121 char **const efault = empty + 1; 122 *empty = NULL; 123 124 syscall(__NR_execveat, -100, FILENAME, empty, empty, 0x1100); 125 printf("execveat(AT_FDCWD, \"%s\", []" 126 #if VERBOSE 127 ", []" 128 #else 129 ", %p /* 0 vars */" 130 #endif 131 ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 132 Q_FILENAME, 133 #if !VERBOSE 134 empty, 135 #endif 136 errno2name()); 137 138 char *const str_a = tail_alloc(DEFAULT_STRLEN + 2); 139 fill_memory_ex(str_a, DEFAULT_STRLEN + 1, '0', 10); 140 str_a[DEFAULT_STRLEN + 1] = '\0'; 141 142 char *const str_b = tail_alloc(DEFAULT_STRLEN + 2); 143 fill_memory_ex(str_b, DEFAULT_STRLEN + 1, '_', 32); 144 str_b[DEFAULT_STRLEN + 1] = '\0'; 145 146 char **const a = tail_alloc(sizeof(*a) * (DEFAULT_STRLEN + 2)); 147 char **const b = tail_alloc(sizeof(*b) * (DEFAULT_STRLEN + 2)); 148 unsigned int i; 149 for (i = 0; i <= DEFAULT_STRLEN; ++i) { 150 a[i] = &str_a[i]; 151 b[i] = &str_b[i]; 152 } 153 a[i] = b[i] = NULL; 154 155 syscall(__NR_execveat, -100, FILENAME, a, b, 0x1100); 156 printf("execveat(AT_FDCWD, \"%s\", [\"%.*s\"...", Q_FILENAME, DEFAULT_STRLEN, a[0]); 157 for (i = 1; i < DEFAULT_STRLEN; ++i) 158 printf(", \"%s\"", a[i]); 159 #if VERBOSE 160 printf(", \"%s\"", a[i]); 161 #else 162 printf(", ..."); 163 #endif 164 #if VERBOSE 165 printf("], [\"%.*s\"...", DEFAULT_STRLEN, b[0]); 166 for (i = 1; i <= DEFAULT_STRLEN; ++i) 167 printf(", \"%s\"", b[i]); 168 printf("]"); 169 #else 170 printf("], %p /* %u vars */", b, DEFAULT_STRLEN + 1); 171 #endif 172 printf(", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 173 errno2name()); 174 175 syscall(__NR_execveat, -100, FILENAME, a + 1, b + 1, 0x1100); 176 printf("execveat(AT_FDCWD, \"%s\", [\"%s\"", Q_FILENAME, a[1]); 177 for (i = 2; i <= DEFAULT_STRLEN; ++i) 178 printf(", \"%s\"", a[i]); 179 #if VERBOSE 180 printf("], [\"%s\"", b[1]); 181 for (i = 2; i <= DEFAULT_STRLEN; ++i) 182 printf(", \"%s\"", b[i]); 183 printf("]"); 184 #else 185 printf("], %p /* %d vars */", b + 1, DEFAULT_STRLEN); 186 #endif 187 printf(", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 188 errno2name()); 189 190 syscall(__NR_execveat, -100, FILENAME, NULL, efault, 0x1100); 191 printf("execveat(AT_FDCWD, \"%s\", NULL, %p" 192 ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 193 Q_FILENAME, efault, errno2name()); 194 195 syscall(__NR_execveat, -100, FILENAME, efault, NULL, 0x1100); 196 printf("execveat(AT_FDCWD, \"%s\", %p, NULL" 197 ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n", 198 Q_FILENAME, efault, errno2name()); 199 200 puts("+++ exited with 0 +++"); 201 return 0; 202 } 203 204 #else 205 206 SKIP_MAIN_UNDEFINED("__NR_execveat") 207 208 #endif 209