(root)/
strace-6.5/
tests-mx32/
execve.c
       1  /*
       2   * This file is part of execve strace test.
       3   *
       4   * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2015-2021 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include <fcntl.h>
      13  #include <stdio.h>
      14  #include <unistd.h>
      15  
      16  #include "secontext.h"
      17  
      18  static const char *errstr;
      19  
      20  static int
      21  call_execve(const char *pathname, char *const *argv, char *const *envp)
      22  {
      23  	int rc = execve(pathname, argv, envp);
      24  	errstr = sprintrc(rc);
      25  	return rc;
      26  }
      27  
      28  #define FILENAME "test.execve\nfilename"
      29  #define Q_FILENAME "test.execve\\nfilename"
      30  
      31  static const char * const argv[] = {
      32  	FILENAME, "first", "second", (const char *) -1L,
      33  	(const char *) -2L, (const char *) -3L
      34  };
      35  static const char * const q_argv[] = {
      36  	Q_FILENAME, "first", "second"
      37  };
      38  
      39  static const char * const envp[] = {
      40  	"foobar=1", "foo\nbar=2", (const char *) -1L,
      41  	(const char *) -2L, (const char *) -3L
      42  };
      43  static const char * const q_envp[] = {
      44  	"foobar=1", "foo\\nbar=2"
      45  };
      46  
      47  int
      48  main(void)
      49  {
      50  	/*
      51  	 * Make sure the current workdir of the tracee
      52  	 * is different from the current workdir of the tracer.
      53  	 */
      54  	create_and_enter_subdir("execve_subdir");
      55  
      56  	char ** const tail_argv = tail_memdup(argv, sizeof(argv));
      57  	char ** const tail_envp = tail_memdup(envp, sizeof(envp));
      58  	char *my_secontext = SECONTEXT_PID_MY();
      59  
      60  	(void) unlink(FILENAME);
      61  	if (open(FILENAME, O_RDONLY | O_CREAT, 0400) < 0)
      62  		perror_msg_and_fail("open");
      63  
      64  	char *FILENAME_secontext = SECONTEXT_FILE(FILENAME);
      65  
      66  	call_execve(FILENAME, tail_argv, tail_envp);
      67  	printf("%s%s(\"%s\"%s"
      68  	       ", [\"%s\", \"%s\", \"%s\", %p, %p, %p, ... /* %p */]"
      69  #if VERBOSE
      70  	       ", [\"%s\", \"%s\", %p, %p, %p, ... /* %p */]"
      71  #else
      72  	       ", %p /* 5 vars, unterminated */"
      73  #endif
      74  	       ") = %s\n",
      75  	       my_secontext, "execve",
      76  	       Q_FILENAME, FILENAME_secontext,
      77  	       q_argv[0], q_argv[1], q_argv[2],
      78  	       argv[3], argv[4], argv[5], (char *) tail_argv + sizeof(argv)
      79  #if VERBOSE
      80  	       , q_envp[0], q_envp[1], envp[2], envp[3], envp[4],
      81  	       (char *) tail_envp + sizeof(envp)
      82  #else
      83  	       , tail_envp
      84  #endif
      85  	       , errstr);
      86  
      87  	tail_argv[ARRAY_SIZE(q_argv)] = NULL;
      88  	tail_envp[ARRAY_SIZE(q_envp)] = NULL;
      89  	(void) q_envp;	/* workaround for clang bug #33068 */
      90  
      91  	call_execve(FILENAME, tail_argv, tail_envp);
      92  	printf("%s%s(\"%s\"%s, [\"%s\", \"%s\", \"%s\"]"
      93  #if VERBOSE
      94  	       ", [\"%s\", \"%s\"]"
      95  #else
      96  	       ", %p /* 2 vars */"
      97  #endif
      98  	       ") = %s\n",
      99  	       my_secontext, "execve",
     100  	       Q_FILENAME, FILENAME_secontext,
     101  	       q_argv[0], q_argv[1], q_argv[2]
     102  #if VERBOSE
     103  	       , q_envp[0], q_envp[1]
     104  #else
     105  	       , tail_envp
     106  #endif
     107  	       , errstr);
     108  
     109  	call_execve(FILENAME, tail_argv + 2, tail_envp + 1);
     110  	printf("%s%s(\"%s\"%s, [\"%s\"]"
     111  #if VERBOSE
     112  	       ", [\"%s\"]"
     113  #else
     114  	       ", %p /* 1 var */"
     115  #endif
     116  	       ") = %s\n",
     117  	       my_secontext, "execve",
     118  	       Q_FILENAME, FILENAME_secontext,
     119  	       q_argv[2]
     120  #if VERBOSE
     121  	       , q_envp[1]
     122  #else
     123  	       , tail_envp + 1
     124  #endif
     125  	       , errstr);
     126  
     127  	TAIL_ALLOC_OBJECT_CONST_PTR(char *, empty);
     128  	char **const efault = empty + 1;
     129  	*empty = NULL;
     130  
     131  	call_execve(FILENAME, empty, empty);
     132  	printf("%s%s(\"%s\"%s, []"
     133  #if VERBOSE
     134  	       ", []"
     135  #else
     136  	       ", %p /* 0 vars */"
     137  #endif
     138  	       ") = %s\n",
     139  	       my_secontext, "execve",
     140  	       Q_FILENAME, FILENAME_secontext
     141  #if !VERBOSE
     142  	       , empty
     143  #endif
     144  	       , errstr);
     145  
     146  	char *const str_a = tail_alloc(DEFAULT_STRLEN + 2);
     147  	fill_memory_ex(str_a, DEFAULT_STRLEN + 1, '0', 10);
     148  	str_a[DEFAULT_STRLEN + 1] = '\0';
     149  
     150  	char *const str_b = tail_alloc(DEFAULT_STRLEN + 2);
     151  	fill_memory_ex(str_b, DEFAULT_STRLEN + 1, '_', 32);
     152  	str_b[DEFAULT_STRLEN + 1] = '\0';
     153  
     154  	char **const a = tail_alloc(sizeof(*a) * (DEFAULT_STRLEN + 2));
     155  	char **const b = tail_alloc(sizeof(*b) * (DEFAULT_STRLEN + 2));
     156  	unsigned int i;
     157  	for (i = 0; i <= DEFAULT_STRLEN; ++i) {
     158  		a[i] = &str_a[i];
     159  		b[i] = &str_b[i];
     160  	}
     161  	a[i] = b[i] = NULL;
     162  
     163  	call_execve(FILENAME, a, b);
     164  	printf("%s%s(\"%s\"%s, [\"%.*s\"...",
     165  	       my_secontext, "execve",
     166  	       Q_FILENAME, FILENAME_secontext,
     167  	       DEFAULT_STRLEN, a[0]);
     168  	for (i = 1; i < DEFAULT_STRLEN; ++i)
     169  		printf(", \"%s\"", a[i]);
     170  #if VERBOSE
     171  	printf(", \"%s\"", a[i]);
     172  #else
     173  	printf(", ...");
     174  #endif
     175  #if VERBOSE
     176  	printf("], [\"%.*s\"...", DEFAULT_STRLEN, b[0]);
     177  	for (i = 1; i <= DEFAULT_STRLEN; ++i)
     178  		printf(", \"%s\"", b[i]);
     179  	printf("]");
     180  #else
     181  	printf("], %p /* %u vars */", b, DEFAULT_STRLEN + 1);
     182  #endif
     183  	printf(") = %s\n", errstr);
     184  
     185  	call_execve(FILENAME, a + 1, b + 1);
     186  	printf("%s%s(\"%s\"%s, [\"%s\"",
     187  	       my_secontext, "execve",
     188  	       Q_FILENAME, FILENAME_secontext,
     189  	       a[1]);
     190  	for (i = 2; i <= DEFAULT_STRLEN; ++i)
     191  		printf(", \"%s\"", a[i]);
     192  #if VERBOSE
     193  	printf("], [\"%s\"", b[1]);
     194  	for (i = 2; i <= DEFAULT_STRLEN; ++i)
     195  		printf(", \"%s\"", b[i]);
     196  	printf("]");
     197  #else
     198  	printf("], %p /* %d vars */", b + 1, DEFAULT_STRLEN);
     199  #endif
     200  	printf(") = %s\n", errstr);
     201  
     202  	if (unlink(FILENAME))
     203  		perror_msg_and_fail("unlink");
     204  
     205  	call_execve(FILENAME, (char **) tail_argv[ARRAY_SIZE(q_argv)], efault);
     206  	printf("%s%s(\"%s\", NULL, %p) = %s\n",
     207  	       my_secontext, "execve",
     208  	       Q_FILENAME, efault, errstr);
     209  
     210  	call_execve(FILENAME, efault, NULL);
     211  	printf("%s%s(\"%s\", %p, NULL) = %s\n",
     212  	       my_secontext, "execve",
     213  	       Q_FILENAME, efault, errstr);
     214  
     215  	leave_and_remove_subdir();
     216  
     217  	return 0;
     218  }