(root)/
strace-6.5/
tests/
syslog.c
       1  /*
       2   * Check decoding of syslog syscall.
       3   *
       4   * Copyright (c) 2016-2021 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include "tests.h"
      11  #include "scno.h"
      12  
      13  #include <stdio.h>
      14  #include <unistd.h>
      15  
      16  #ifdef RETVAL_INJECTED
      17  # define RET_SFX " (INJECTED)"
      18  #else
      19  # define RET_SFX ""
      20  #endif
      21  
      22  static bool
      23  valid_cmd(int cmd)
      24  {
      25  	return cmd >= 0 && cmd <= 10;
      26  }
      27  
      28  static void
      29  printstr(const char *s, int cmd, long size)
      30  {
      31  	if (size < 0 || !valid_cmd(cmd))
      32  		printf("%p", s);
      33  	else if (size == 0)
      34  		printf("\"\"");
      35  	else if (size <= DEFAULT_STRLEN)
      36  		print_quoted_memory(s, size);
      37  	else {
      38  		print_quoted_memory(s, DEFAULT_STRLEN);
      39  		printf("...");
      40  	}
      41  }
      42  
      43  int
      44  main(void)
      45  {
      46  	static const struct cmd_str {
      47  		unsigned int cmd;
      48  		const char *str;
      49  	} no_args[] = {
      50  		{ 0,  "0 /* SYSLOG_ACTION_CLOSE */" },
      51  		{ 1,  "1 /* SYSLOG_ACTION_OPEN */" },
      52  #ifdef RETVAL_INJECTED
      53  		/* Avoid commands with side effects without syscall injection */
      54  		{ 5,  "5 /* SYSLOG_ACTION_CLEAR */" },
      55  		{ 6,  "6 /* SYSLOG_ACTION_CONSOLE_OFF */" },
      56  		{ 7,  "7 /* SYSLOG_ACTION_CONSOLE_ON */" },
      57  #endif
      58  		{ 9,  "9 /* SYSLOG_ACTION_SIZE_UNREAD */" },
      59  		{ 10, "10 /* SYSLOG_ACTION_SIZE_BUFFER */" },
      60  	};
      61  	static const struct cmd_str two_args[] = {
      62  		{ 0xfeedbeef, "-17973521 /* SYSLOG_ACTION_??? */" },
      63  		{ -1U, "-1 /* SYSLOG_ACTION_??? */" },
      64  #ifdef RETVAL_INJECTED
      65  		/* Avoid commands with side effects without syscall injection */
      66  		{ 2,  "2 /* SYSLOG_ACTION_READ */" },
      67  		{ 3,  "3 /* SYSLOG_ACTION_READ_ALL */" },
      68  		{ 4,  "4 /* SYSLOG_ACTION_READ_CLEAR */" },
      69  #endif
      70  		{ 11, "11 /* SYSLOG_ACTION_??? */" },
      71  		{ (1U << 31) - 1, "2147483647 /* SYSLOG_ACTION_??? */" },
      72  	};
      73  	static const struct cmd_str levels[] = {
      74  		{ 0xfeedbeef, "-17973521 /* LOGLEVEL_??? */" },
      75  		{ -1U, "-1 /* LOGLEVEL_??? */" },
      76  		{ 0, "0 /* LOGLEVEL_EMERG */" },
      77  		{ 7, "7 /* LOGLEVEL_DEBUG */" },
      78  		{ 8, "8 /* LOGLEVEL_DEBUG+1 */" },
      79  		{ 9, "9 /* LOGLEVEL_??? */" },
      80  		{ (1U << 31) - 1, "2147483647 /* LOGLEVEL_??? */" },
      81  	};
      82  	static const kernel_ulong_t high =
      83  		(kernel_ulong_t) 0xbadc0ded00000000ULL;
      84  	static const size_t buf_size = 64;
      85  
      86  	const kernel_ulong_t addr = (kernel_ulong_t) 0xfacefeeddeadbeefULL;
      87  	int rc;
      88  	char *buf = tail_alloc(buf_size);
      89  
      90  	fill_memory(buf, buf_size);
      91  
      92  	for (size_t i = 0; i < ARRAY_SIZE(no_args); i++) {
      93  		rc = syscall(__NR_syslog, high | no_args[i].cmd, addr, -1);
      94  		printf("syslog(%s) = %s" RET_SFX "\n",
      95  		no_args[i].str, sprintrc(rc));
      96  	}
      97  
      98  	for (size_t i = 0; i < ARRAY_SIZE(two_args); i++) {
      99  		rc = syscall(__NR_syslog, high | two_args[i].cmd, NULL, -1);
     100  		printf("syslog(%s, NULL, -1) = %s" RET_SFX "\n",
     101  		       two_args[i].str, sprintrc(rc));
     102  
     103  #ifdef RETVAL_INJECTED
     104  		/* Avoid valid commands with a bogus address */
     105  		if (!valid_cmd(two_args[i].cmd))
     106  #endif
     107  		{
     108  			rc = syscall(__NR_syslog, high | two_args[i].cmd, addr,
     109  				     -1);
     110  			printf("syslog(%s, %#llx, -1) = %s" RET_SFX "\n",
     111  			       two_args[i].str, (unsigned long long) addr,
     112  			       sprintrc(rc));
     113  
     114  			rc = syscall(__NR_syslog, two_args[i].cmd, addr, 0);
     115  
     116  			printf("syslog(%s, %s, 0) = %s" RET_SFX "\n",
     117  			       two_args[i].str,
     118  			       !rc && valid_cmd(two_args[i].cmd)
     119  				   && (sizeof(kernel_ulong_t) == sizeof(void *))
     120  				      ? "\"\""
     121  				      : (sizeof(addr) == 8)
     122  					? "0xfacefeeddeadbeef" : "0xdeadbeef",
     123  			       sprintrc(rc));
     124  		}
     125  
     126  		rc = syscall(__NR_syslog, two_args[i].cmd, buf, buf_size);
     127  		const char *errstr = sprintrc(rc);
     128  
     129  		printf("syslog(%s, ", two_args[i].str);
     130  		if (rc >= 0 && valid_cmd(two_args[i].cmd))
     131  			printstr(buf, two_args[i].cmd, rc);
     132  		else
     133  			printf("%p", buf);
     134  		printf(", %zu) = %s" RET_SFX "\n", buf_size, errstr);
     135  	}
     136  
     137  	for (size_t i = 0; i < ARRAY_SIZE(levels); i++) {
     138  		rc = syscall(__NR_syslog, high | 8, addr, levels[i].cmd);
     139  		printf("syslog(8 /* SYSLOG_ACTION_CONSOLE_LEVEL */, %#llx, %s)"
     140  		       " = %s" RET_SFX "\n",
     141  		       (unsigned long long) addr, levels[i].str, sprintrc(rc));
     142  	}
     143  
     144  	puts("+++ exited with 0 +++");
     145  	return 0;
     146  }