1 /*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993-1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 2003-2016 Dmitry V. Levin <ldv@strace.io>
7 * Copyright (c) 2014-2021 The strace developers.
8 * All rights reserved.
9 *
10 * SPDX-License-Identifier: LGPL-2.1-or-later
11 */
12
13 #ifdef STRACE_UID_SIZE
14 # if STRACE_UID_SIZE != 16
15 # error invalid STRACE_UID_SIZE
16 # endif
17
18 # define SIZEIFY(x) SIZEIFY_(x, STRACE_UID_SIZE)
19 # define SIZEIFY_(x, size) SIZEIFY__(x, size)
20 # define SIZEIFY__(x, size) x ## size
21
22 # define printuid SIZEIFY(printuid)
23 # define sys_chown SIZEIFY(sys_chown)
24 # define sys_fchown SIZEIFY(sys_fchown)
25 # define sys_getgroups SIZEIFY(sys_getgroups)
26 # define sys_getresuid SIZEIFY(sys_getresuid)
27 # define sys_getuid SIZEIFY(sys_getuid)
28 # define sys_setfsuid SIZEIFY(sys_setfsuid)
29 # define sys_setgroups SIZEIFY(sys_setgroups)
30 # define sys_setresuid SIZEIFY(sys_setresuid)
31 # define sys_setreuid SIZEIFY(sys_setreuid)
32 # define sys_setuid SIZEIFY(sys_setuid)
33 #endif /* STRACE_UID_SIZE */
34
35 #include "defs.h"
36
37 #ifdef STRACE_UID_SIZE
38 # if !HAVE_ARCH_UID16_SYSCALLS
39 # undef STRACE_UID_SIZE
40 # endif
41 #else
42 # define STRACE_UID_SIZE 32
43 #endif
44
45 #ifdef STRACE_UID_SIZE
46
47 # undef uid_t
48 # define uid_t uid_t_(STRACE_UID_SIZE)
49 # define uid_t_(size) uid_t__(size)
50 # define uid_t__(size) uint ## size ## _t
51
52 SYS_FUNC(getuid)
53 {
54 return RVAL_DECODED;
55 }
56
57 SYS_FUNC(setfsuid)
58 {
59 /* fsuid */
60 printuid(tcp->u_arg[0]);
61
62 return RVAL_DECODED;
63 }
64
65 SYS_FUNC(setuid)
66 {
67 /* uid */
68 printuid(tcp->u_arg[0]);
69
70 return RVAL_DECODED;
71 }
72
73 static void
74 get_print_uid(struct tcb *const tcp, const kernel_ulong_t addr)
75 {
76 uid_t uid;
77
78 if (!umove_or_printaddr(tcp, addr, &uid)) {
79 tprint_indirect_begin();
80 printuid(uid);
81 tprint_indirect_end();
82 }
83 }
84
85 SYS_FUNC(getresuid)
86 {
87 if (entering(tcp))
88 return 0;
89
90 /* ruid */
91 get_print_uid(tcp, tcp->u_arg[0]);
92 tprint_arg_next();
93
94 /* euid */
95 get_print_uid(tcp, tcp->u_arg[1]);
96 tprint_arg_next();
97
98 /* suid */
99 get_print_uid(tcp, tcp->u_arg[2]);
100
101 return 0;
102 }
103
104 SYS_FUNC(setreuid)
105 {
106 /* ruid */
107 printuid(tcp->u_arg[0]);
108 tprint_arg_next();
109
110 /* euid */
111 printuid(tcp->u_arg[1]);
112
113 return RVAL_DECODED;
114 }
115
116 SYS_FUNC(setresuid)
117 {
118 /* ruid */
119 printuid(tcp->u_arg[0]);
120 tprint_arg_next();
121
122 /* euid */
123 printuid(tcp->u_arg[1]);
124 tprint_arg_next();
125
126 /* suid */
127 printuid(tcp->u_arg[2]);
128
129 return RVAL_DECODED;
130 }
131
132 SYS_FUNC(chown)
133 {
134 /* pathname */
135 printpath(tcp, tcp->u_arg[0]);
136 tprint_arg_next();
137
138 /* owner */
139 printuid(tcp->u_arg[1]);
140 tprint_arg_next();
141
142 /* group */
143 printuid(tcp->u_arg[2]);
144
145 return RVAL_DECODED;
146 }
147
148 SYS_FUNC(fchown)
149 {
150 /* fd */
151 printfd(tcp, tcp->u_arg[0]);
152 tprint_arg_next();
153
154 /* owner */
155 printuid(tcp->u_arg[1]);
156 tprint_arg_next();
157
158 /* group */
159 printuid(tcp->u_arg[2]);
160
161 return RVAL_DECODED;
162 }
163
164 void
165 printuid(const unsigned int uid)
166 {
167 PRINT_VAL_ID((uid_t) uid);
168 }
169
170 static bool
171 print_gid(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
172 {
173 printuid((*(uid_t *) elem_buf));
174
175 return true;
176 }
177
178 static void
179 print_groups(struct tcb *const tcp, const unsigned int len,
180 const kernel_ulong_t addr)
181 {
182 static unsigned long ngroups_max;
183 if (!ngroups_max)
184 ngroups_max = sysconf(_SC_NGROUPS_MAX);
185
186 if (len > ngroups_max) {
187 printaddr(addr);
188 return;
189 }
190
191 uid_t gid;
192 print_array(tcp, addr, len, &gid, sizeof(gid),
193 tfetch_mem, print_gid, 0);
194 }
195
196 SYS_FUNC(setgroups)
197 {
198 /* size */
199 const int len = tcp->u_arg[0];
200 PRINT_VAL_D(len);
201 tprint_arg_next();
202
203 /* list */
204 print_groups(tcp, len, tcp->u_arg[1]);
205 return RVAL_DECODED;
206 }
207
208 SYS_FUNC(getgroups)
209 {
210 if (entering(tcp)) {
211 /* size */
212 int size = tcp->u_arg[0];
213 PRINT_VAL_D(size);
214 tprint_arg_next();
215 } else {
216 /* list */
217 print_groups(tcp, tcp->u_rval, tcp->u_arg[1]);
218 }
219 return 0;
220 }
221
222 #endif /* STRACE_UID_SIZE */