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 }