Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/src/exec_ptrace.c
1532 views
1
/*
2
* Copyright (c) 2022 Todd C. Miller <[email protected]>
3
*
4
* Permission to use, copy, modify, and distribute this software for any
5
* purpose with or without fee is hereby granted, provided that the above
6
* copyright notice and this permission notice appear in all copies.
7
*
8
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
*/
16
17
#include <config.h>
18
19
#include <sys/stat.h>
20
#include <sys/types.h>
21
#include <sys/uio.h>
22
#include <sys/wait.h>
23
24
#include <ctype.h>
25
#include <errno.h>
26
#include <fcntl.h>
27
#include <limits.h>
28
#include <signal.h>
29
#if defined(HAVE_STDINT_H)
30
# include <stdint.h>
31
#elif defined(HAVE_INTTYPES_H)
32
# include <inttypes.h>
33
#endif
34
#include <stddef.h>
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <string.h>
38
#include <unistd.h>
39
#if defined(HAVE_ENDIAN_H)
40
# include <endian.h>
41
#elif defined(HAVE_SYS_ENDIAN_H)
42
# include <sys/endian.h>
43
#elif defined(HAVE_MACHINE_ENDIAN_H)
44
# include <machine/endian.h>
45
#else
46
# include <compat/endian.h>
47
#endif
48
49
#include <sudo.h>
50
#include <sudo_exec.h>
51
52
#ifdef HAVE_PTRACE_INTERCEPT
53
# include <exec_intercept.h>
54
# include <exec_ptrace.h>
55
56
/* We need to take care when ptracing 32-bit binaries on 64-bit kernels. */
57
# ifdef __LP64__
58
# define COMPAT_FLAG 0x01
59
# else
60
# define COMPAT_FLAG 0x00
61
# endif
62
63
/* SECCOMP_RET_KILL_PROCESS was added in Linux 4.14. */
64
# ifndef SECCOMP_RET_KILL_PROCESS
65
# define SECCOMP_RET_KILL_PROCESS SECCOMP_RET_KILL
66
# endif
67
68
static int seccomp_trap_supported = -1;
69
# ifdef HAVE_PROCESS_VM_READV
70
static size_t page_size;
71
# endif
72
static size_t arg_max;
73
74
/* Register getters and setters. */
75
# ifdef SECCOMP_AUDIT_ARCH_COMPAT
76
static inline unsigned long
77
get_stack_pointer(struct sudo_ptrace_regs *regs)
78
{
79
if (regs->compat) {
80
return compat_reg_sp(regs->u.compat);
81
} else {
82
return reg_sp(regs->u.native);
83
}
84
}
85
86
static inline void
87
set_sc_retval(struct sudo_ptrace_regs *regs, int retval)
88
{
89
if (regs->compat) {
90
compat_reg_set_retval(regs->u.compat, retval);
91
} else {
92
reg_set_retval(regs->u.native, retval);
93
}
94
}
95
96
static inline int
97
get_syscallno(struct sudo_ptrace_regs *regs)
98
{
99
if (regs->compat) {
100
return compat_reg_syscall(regs->u.compat);
101
} else {
102
return reg_syscall(regs->u.native);
103
}
104
}
105
106
static inline void
107
set_syscallno(pid_t pid, struct sudo_ptrace_regs *regs, int syscallno)
108
{
109
if (regs->compat) {
110
compat_reg_set_syscall(regs->u.compat, syscallno);
111
} else {
112
reg_set_syscall(regs->u.native, syscallno);
113
}
114
}
115
116
static inline unsigned long
117
get_sc_arg1(struct sudo_ptrace_regs *regs)
118
{
119
if (regs->compat) {
120
return compat_reg_arg1(regs->u.compat);
121
} else {
122
return reg_arg1(regs->u.native);
123
}
124
}
125
126
static inline void
127
set_sc_arg1(struct sudo_ptrace_regs *regs, unsigned long addr)
128
{
129
if (regs->compat) {
130
compat_reg_set_arg1(regs->u.compat, addr);
131
} else {
132
reg_set_arg1(regs->u.native, addr);
133
}
134
}
135
136
static inline unsigned long
137
get_sc_arg2(struct sudo_ptrace_regs *regs)
138
{
139
if (regs->compat) {
140
return compat_reg_arg2(regs->u.compat);
141
} else {
142
return reg_arg2(regs->u.native);
143
}
144
}
145
146
static inline void
147
set_sc_arg2(struct sudo_ptrace_regs *regs, unsigned long addr)
148
{
149
if (regs->compat) {
150
compat_reg_set_arg2(regs->u.compat, addr);
151
} else {
152
reg_set_arg2(regs->u.native, addr);
153
}
154
}
155
156
static inline unsigned long
157
get_sc_arg3(struct sudo_ptrace_regs *regs)
158
{
159
if (regs->compat) {
160
return compat_reg_arg3(regs->u.compat);
161
} else {
162
return reg_arg3(regs->u.native);
163
}
164
}
165
166
# ifdef notyet
167
static inline void
168
set_sc_arg3(struct sudo_ptrace_regs *regs, unsigned long addr)
169
{
170
if (regs->compat) {
171
compat_reg_set_arg3(regs->u.compat, addr);
172
} else {
173
reg_set_arg3(regs->u.native, addr);
174
}
175
}
176
177
static inline unsigned long
178
get_sc_arg4(struct sudo_ptrace_regs *regs)
179
{
180
if (regs->compat) {
181
return compat_reg_arg4(regs->u.compat);
182
} else {
183
return reg_arg4(regs->u.native);
184
}
185
}
186
187
static inline void
188
set_sc_arg4(struct sudo_ptrace_regs *regs, unsigned long addr)
189
{
190
if (regs->compat) {
191
compat_reg_set_arg4(regs->u.compat, addr);
192
} else {
193
reg_set_arg4(regs->u.native, addr);
194
}
195
}
196
# endif /* notyet */
197
198
# else /* SECCOMP_AUDIT_ARCH_COMPAT */
199
200
static inline unsigned long
201
get_stack_pointer(struct sudo_ptrace_regs *regs)
202
{
203
return reg_sp(regs->u.native);
204
}
205
206
static inline void
207
set_sc_retval(struct sudo_ptrace_regs *regs, int retval)
208
{
209
reg_set_retval(regs->u.native, retval);
210
}
211
212
static inline int
213
get_syscallno(struct sudo_ptrace_regs *regs)
214
{
215
return reg_syscall(regs->u.native);
216
}
217
218
static inline void
219
set_syscallno(pid_t pid, struct sudo_ptrace_regs *regs, int syscallno)
220
{
221
reg_set_syscall(regs->u.native, syscallno);
222
}
223
224
static inline unsigned long
225
get_sc_arg1(struct sudo_ptrace_regs *regs)
226
{
227
return reg_arg1(regs->u.native);
228
}
229
230
static inline void
231
set_sc_arg1(struct sudo_ptrace_regs *regs, unsigned long addr)
232
{
233
reg_set_arg1(regs->u.native, addr);
234
}
235
236
static inline unsigned long
237
get_sc_arg2(struct sudo_ptrace_regs *regs)
238
{
239
return reg_arg2(regs->u.native);
240
}
241
242
static inline void
243
set_sc_arg2(struct sudo_ptrace_regs *regs, unsigned long addr)
244
{
245
reg_set_arg2(regs->u.native, addr);
246
}
247
248
static inline unsigned long
249
get_sc_arg3(struct sudo_ptrace_regs *regs)
250
{
251
return reg_arg3(regs->u.native);
252
}
253
254
# ifdef notyet
255
static inline void
256
set_sc_arg3(struct sudo_ptrace_regs *regs, unsigned long addr)
257
{
258
reg_set_arg3(regs->u.native, addr);
259
}
260
261
static inline unsigned long
262
get_sc_arg4(struct sudo_ptrace_regs *regs)
263
{
264
return reg_arg4(regs->u.native);
265
}
266
267
static inline void
268
set_sc_arg4(struct sudo_ptrace_regs *regs, unsigned long addr)
269
{
270
reg_set_arg4(regs->u.native, addr);
271
}
272
# endif /* notyet */
273
# endif /* SECCOMP_AUDIT_ARCH_COMPAT */
274
275
/*
276
* Get the registers for the given process and store in regs, which
277
* must be large enough. If the compat flag is set, pid is expected
278
* to refer to a 32-bit process and the md parameters will be filled
279
* in accordingly.
280
* Returns true on success, else false.
281
*/
282
static bool
283
ptrace_getregs(int pid, struct sudo_ptrace_regs *regs, int compat)
284
{
285
struct iovec iov;
286
debug_decl(ptrace_getregs, SUDO_DEBUG_EXEC);
287
288
iov.iov_base = &regs->u;
289
iov.iov_len = sizeof(regs->u);
290
291
# ifdef __mips__
292
/* PTRACE_GETREGSET has bugs with the MIPS o32 ABI at least. */
293
if (ptrace(PTRACE_GETREGS, pid, NULL, iov.iov_base) == -1)
294
debug_return_bool(false);
295
# else
296
if (ptrace(PTRACE_GETREGSET, pid, (void *)NT_PRSTATUS, &iov) == -1)
297
debug_return_bool(false);
298
# endif /* __mips__ */
299
if (compat == -1) {
300
# ifdef SECCOMP_AUDIT_ARCH_COMPAT
301
if (sizeof(regs->u.native) != sizeof(regs->u.compat)) {
302
/* Guess compat based on size of register struct returned. */
303
compat = iov.iov_len != sizeof(regs->u.native);
304
} else {
305
/* Assume a 64-bit executable will have a 64-bit stack pointer. */
306
compat = reg_sp(regs->u.native) < 0xffffffff;
307
}
308
# else
309
compat = false;
310
# endif /* SECCOMP_AUDIT_ARCH_COMPAT */
311
}
312
313
/* Machine-dependent parameters to support compat binaries. */
314
if (compat) {
315
regs->compat = true;
316
regs->wordsize = sizeof(int);
317
} else {
318
regs->compat = false;
319
regs->wordsize = sizeof(long);
320
}
321
322
debug_return_bool(true);
323
}
324
325
/*
326
* Set the registers, specified by regs, for the given process.
327
* Returns true on success, else false.
328
*/
329
static bool
330
ptrace_setregs(int pid, struct sudo_ptrace_regs *regs)
331
{
332
debug_decl(ptrace_setregs, SUDO_DEBUG_EXEC);
333
334
# ifdef __mips__
335
/* PTRACE_SETREGSET has bugs with the MIPS o32 ABI at least. */
336
if (ptrace(PTRACE_SETREGS, pid, NULL, &regs->u) == -1)
337
debug_return_bool(false);
338
# else
339
struct iovec iov;
340
iov.iov_base = &regs->u;
341
iov.iov_len = sizeof(regs->u);
342
if (ptrace(PTRACE_SETREGSET, pid, (void *)NT_PRSTATUS, &iov) == -1)
343
debug_return_bool(false);
344
# endif /* __mips__ */
345
346
debug_return_bool(true);
347
}
348
349
#ifdef HAVE_PROCESS_VM_READV
350
/*
351
* Read the string at addr and store in buf using process_vm_readv(2).
352
* Returns the number of bytes stored, including the NUL.
353
*/
354
static ssize_t
355
ptrace_readv_string(pid_t pid, unsigned long addr, char *buf, size_t bufsize)
356
{
357
const char *cp, *buf0 = buf;
358
struct iovec local, remote;
359
ssize_t nread;
360
debug_decl(ptrace_read_string, SUDO_DEBUG_EXEC);
361
362
/*
363
* Read the string via process_vm_readv(2) one page at a time.
364
* We could do larger reads but since we don't know the length
365
* of the string, going one page at a time is simplest.
366
*/
367
for (;;) {
368
if (bufsize == 0) {
369
sudo_debug_printf(SUDO_DEBUG_ERROR,
370
"%s: %d: out of space reading string", __func__, (int)pid);
371
errno = ENOSPC;
372
debug_return_ssize_t(-1);
373
}
374
375
local.iov_base = buf;
376
local.iov_len = bufsize;
377
remote.iov_base = (void *)addr;
378
remote.iov_len = MIN(bufsize, page_size);
379
380
nread = process_vm_readv(pid, &local, 1, &remote, 1, 0);
381
switch (nread) {
382
case -1:
383
sudo_debug_printf(
384
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
385
"process_vm_readv(%d, [0x%lx, %zu], 1, [0x%lx, %zu], 1, 0)",
386
(int)pid, (unsigned long)local.iov_base, local.iov_len,
387
(unsigned long)remote.iov_base, remote.iov_len);
388
debug_return_ssize_t(-1);
389
case 0:
390
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
391
"process_vm_readv(%d, [0x%lx, %zu], 1, [0x%lx, %zu], 1, 0): %s",
392
(int)pid, (unsigned long)local.iov_base, local.iov_len,
393
(unsigned long)remote.iov_base, remote.iov_len, "premature EOF");
394
debug_return_ssize_t(-1);
395
default:
396
/* Check for NUL terminator in page. */
397
cp = memchr(buf, '\0', (size_t)nread);
398
if (cp != NULL)
399
debug_return_ssize_t((cp - buf0) + 1); /* includes NUL */
400
/* No NUL terminator, we should have a full page. */
401
if ((size_t)nread != page_size) {
402
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
403
"process_vm_readv(%d, [0x%lx, %zu], 1, [0x%lx, %zu], 1, 0)"
404
" -> %zd",
405
(int)pid, (unsigned long)local.iov_base, local.iov_len,
406
(unsigned long)remote.iov_base, remote.iov_len, nread);
407
}
408
buf += nread;
409
bufsize -= (size_t)nread;
410
addr += (size_t)nread;
411
break;
412
}
413
}
414
debug_return_ssize_t(-1);
415
}
416
#endif /* HAVE_PROCESS_VM_READV */
417
418
/*
419
* Read the string at addr and store in buf using ptrace(2).
420
* Returns the number of bytes stored, including the NUL.
421
*/
422
static ssize_t
423
ptrace_read_string(pid_t pid, unsigned long addr, char *buf, size_t bufsize)
424
{
425
const char *cp, *buf0 = buf;
426
unsigned long word;
427
size_t i;
428
debug_decl(ptrace_read_string, SUDO_DEBUG_EXEC);
429
430
#ifdef HAVE_PROCESS_VM_READV
431
ssize_t nread = ptrace_readv_string(pid, addr, buf, bufsize);
432
if (nread != -1 || errno != ENOSYS)
433
debug_return_ssize_t(nread);
434
#endif /* HAVE_PROCESS_VM_READV */
435
436
/*
437
* Read the string via ptrace(2) one (native) word at a time.
438
* We use the native word size even in compat mode because that
439
* is the unit ptrace(2) uses.
440
*/
441
for (;;) {
442
word = ptrace(PTRACE_PEEKDATA, pid, addr, NULL);
443
if (word == (unsigned long)-1) {
444
sudo_debug_printf(
445
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
446
"ptrace(PTRACE_PEEKDATA, %d, 0x%lx, NULL)", (int)pid, addr);
447
debug_return_ssize_t(-1);
448
}
449
450
cp = (char *)&word;
451
for (i = 0; i < sizeof(unsigned long); i++) {
452
if (bufsize == 0) {
453
sudo_debug_printf(SUDO_DEBUG_ERROR,
454
"%s: %d: out of space reading string", __func__, (int)pid);
455
errno = ENOSPC;
456
debug_return_ssize_t(-1);
457
}
458
*buf = cp[i];
459
if (*buf++ == '\0')
460
debug_return_ssize_t(buf - buf0);
461
bufsize--;
462
}
463
addr += sizeof(unsigned long);
464
}
465
}
466
467
/*
468
* Expand buf by doubling its size.
469
* Updates bufp and bufsizep and recalculates curp and remp if non-NULL.
470
* Returns true on success, else false.
471
*/
472
static bool
473
growbuf(char **bufp, size_t *bufsizep, char **curp, size_t *remp)
474
{
475
const size_t oldsize = *bufsizep;
476
char *newbuf;
477
debug_decl(growbuf, SUDO_DEBUG_EXEC);
478
479
/* Double the size of the buffer. */
480
newbuf = reallocarray(*bufp, 2, oldsize);
481
if (newbuf == NULL) {
482
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
483
debug_return_bool(false);
484
}
485
if (curp != NULL)
486
*curp = newbuf + (*curp - *bufp);
487
if (remp != NULL)
488
*remp += oldsize;
489
*bufp = newbuf;
490
*bufsizep = 2 * oldsize;
491
debug_return_bool(true);
492
}
493
494
/*
495
* Build a NULL-terminated string vector from a string table.
496
* On success, returns number of bytes used for the vector and sets
497
* vecp to the start of the vector and countp to the number of elements
498
* (not including the NULL). The buffer is resized as needed.
499
* Both vecp and its elements are stored as offsets into buf, not pointers.
500
* However, NULL is still stored as NULL.
501
* Returns (size_t)-1 on failure.
502
*/
503
static ssize_t
504
strtab_to_vec(char *strtab, size_t strtab_len, int *countp, char ***vecp,
505
char **bufp, size_t *bufsizep, size_t remainder)
506
{
507
char *strend = strtab + strtab_len;
508
char **vec, **vp;
509
int count = 0;
510
debug_decl(strtab_to_vec, SUDO_DEBUG_EXEC);
511
512
/* Store vector in buf after string table and make it aligned. */
513
while (remainder < 2 * sizeof(char *)) {
514
if (!growbuf(bufp, bufsizep, &strtab, &remainder))
515
debug_return_ssize_t(-1);
516
strend = strtab + strtab_len;
517
}
518
vec = (char **)LONGALIGN(strend);
519
remainder -= (size_t)((char *)vec - strend);
520
521
/* Fill in vector with the strings we read. */
522
for (vp = vec; strtab < strend; ) {
523
while (remainder < 2 * sizeof(char *)) {
524
if (!growbuf(bufp, bufsizep, &strtab, &remainder))
525
debug_return_ssize_t(-1);
526
strend = strtab + strtab_len;
527
vec = (char **)LONGALIGN(strend);
528
vp = vec + count;
529
}
530
/* Store offset into buf (not a pointer) in case of realloc(). */
531
*vp++ = (char *)(strtab - *bufp);
532
remainder -= sizeof(char *);
533
strtab = memchr(strtab, '\0', (size_t)(strend - strtab));
534
if (strtab == NULL)
535
break;
536
strtab++;
537
count++;
538
}
539
*vp++ = NULL; /* we always leave room for NULL */
540
541
*countp = count;
542
*vecp = (char **)((char *)vec - *bufp);
543
544
debug_return_ssize_t((char *)vp - strend);
545
}
546
547
/*
548
* Read the string vector at addr and store it in bufp, which
549
* is reallocated as needed. The actual vector is returned in vecp.
550
* The count stored in countp does not include the terminating NULL pointer.
551
* The vecp and its contents are _offsets_, not pointers, in case the buffer
552
* gets reallocated later. The caller is responsible for converting the
553
* offsets into pointers based on the buffer before using.
554
* Returns the number of bytes in buf consumed (including NULs).
555
*/
556
static ssize_t
557
ptrace_read_vec(pid_t pid, struct sudo_ptrace_regs *regs, unsigned long addr,
558
int *countp, char ***vecp, char **bufp, size_t *bufsizep, size_t off)
559
{
560
# ifdef SECCOMP_AUDIT_ARCH_COMPAT
561
unsigned long next_word = (unsigned long)-1;
562
# endif
563
size_t strtab_len, remainder = *bufsizep - off;
564
char *strtab = *bufp + off;
565
unsigned long word;
566
ssize_t len;
567
debug_decl(ptrace_read_vec, SUDO_DEBUG_EXEC);
568
569
/* Treat a NULL vector as empty, thanks Linux. */
570
if (addr == 0) {
571
char **vp;
572
573
while (remainder < 2 * sizeof(char *)) {
574
if (!growbuf(bufp, bufsizep, &strtab, &remainder))
575
debug_return_ssize_t(-1);
576
}
577
vp = (char **)LONGALIGN(strtab);
578
*vecp = (char **)((char *)vp - *bufp);
579
*countp = 0;
580
*vp++ = NULL;
581
debug_return_ssize_t((char *)vp - strtab);
582
}
583
584
/* Fill in string table. */
585
do {
586
# ifdef SECCOMP_AUDIT_ARCH_COMPAT
587
if (next_word == (unsigned long)-1) {
588
word = ptrace(PTRACE_PEEKDATA, pid, addr, NULL);
589
if (regs->compat) {
590
/* Stash the next compat word in next_word. */
591
# if BYTE_ORDER == BIG_ENDIAN
592
next_word = word & 0xffffffffU;
593
word >>= 32;
594
# else
595
next_word = word >> 32;
596
word &= 0xffffffffU;
597
# endif
598
}
599
} else {
600
/* Use the stashed value of the next word. */
601
word = next_word;
602
next_word = (unsigned long)-1;
603
}
604
# else /* SECCOMP_AUDIT_ARCH_COMPAT */
605
word = ptrace(PTRACE_PEEKDATA, pid, addr, NULL);
606
# endif /* SECCOMP_AUDIT_ARCH_COMPAT */
607
switch (word) {
608
case -1:
609
sudo_warn("%s: ptrace(PTRACE_PEEKDATA, %d, 0x%lx, NULL)",
610
__func__, (int)pid, addr);
611
debug_return_ssize_t(-1);
612
case 0:
613
/* NULL terminator */
614
break;
615
default:
616
for (;;) {
617
len = ptrace_read_string(pid, word, strtab, remainder);
618
if (len != -1)
619
break;
620
if (errno != ENOSPC)
621
debug_return_ssize_t(-1);
622
if (!growbuf(bufp, bufsizep, &strtab, &remainder))
623
debug_return_ssize_t(-1);
624
}
625
strtab += len;
626
remainder -= (size_t)len;
627
addr += regs->wordsize;
628
continue;
629
}
630
} while (word != 0);
631
632
/* Store strings in a vector after the string table. */
633
strtab_len = (size_t)(strtab - (*bufp + off));
634
strtab = *bufp + off;
635
len = strtab_to_vec(strtab, strtab_len, countp, vecp, bufp, bufsizep,
636
remainder);
637
if (len == -1)
638
debug_return_ssize_t(-1);
639
640
debug_return_ssize_t((ssize_t)strtab_len + len);
641
}
642
643
#ifdef HAVE_PROCESS_VM_READV
644
/*
645
* Write the NUL-terminated string str to addr in the tracee using
646
* process_vm_writev(2).
647
* Returns the number of bytes written, including trailing NUL.
648
*/
649
static ssize_t
650
ptrace_writev_string(pid_t pid, unsigned long addr, const char *str0)
651
{
652
const char *str = str0;
653
size_t len = strlen(str) + 1;
654
debug_decl(ptrace_writev_string, SUDO_DEBUG_EXEC);
655
656
/*
657
* Write the string via process_vm_writev(2), handling partial writes.
658
*/
659
for (;;) {
660
struct iovec local, remote;
661
ssize_t nwritten;
662
663
local.iov_base = (void *)str;
664
local.iov_len = len;
665
remote.iov_base = (void *)addr;
666
remote.iov_len = len;
667
668
nwritten = process_vm_writev(pid, &local, 1, &remote, 1, 0);
669
switch (nwritten) {
670
case -1:
671
sudo_debug_printf(
672
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
673
"process_vm_writev(%d, [0x%lx, %zu], 1, [0x%lx, %zu], 1, 0)",
674
(int)pid, (unsigned long)local.iov_base, local.iov_len,
675
(unsigned long)remote.iov_base, remote.iov_len);
676
debug_return_ssize_t(-1);
677
case 0:
678
/* Should not be possible. */
679
sudo_debug_printf(
680
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
681
"process_vm_writev(%d, [0x%lx, %zu], 1, [0x%lx, %zu], 1, 0): %s",
682
(int)pid, (unsigned long)local.iov_base, local.iov_len,
683
(unsigned long)remote.iov_base, remote.iov_len,
684
"zero bytes written");
685
debug_return_ssize_t(-1);
686
default:
687
str += nwritten;
688
len -= (size_t)nwritten;
689
addr += (size_t)nwritten;
690
if (len == 0)
691
debug_return_ssize_t(str - str0); /* includes NUL */
692
break;
693
}
694
}
695
debug_return_ssize_t(-1);
696
}
697
#endif /* HAVE_PROCESS_VM_READV */
698
699
/*
700
* Write the NUL-terminated string str to addr in the tracee using ptrace(2).
701
* Returns the number of bytes written, including trailing NUL.
702
*/
703
static ssize_t
704
ptrace_write_string(pid_t pid, unsigned long addr, const char *str)
705
{
706
const char *str0 = str;
707
size_t i;
708
union {
709
unsigned long word;
710
char buf[sizeof(unsigned long)];
711
} u;
712
debug_decl(ptrace_write_string, SUDO_DEBUG_EXEC);
713
714
#ifdef HAVE_PROCESS_VM_READV
715
ssize_t nwritten = ptrace_writev_string(pid, addr, str);
716
if (nwritten != -1 || errno != ENOSYS)
717
debug_return_ssize_t(nwritten);
718
#endif /* HAVE_PROCESS_VM_READV */
719
720
/*
721
* Write the string via ptrace(2) one (native) word at a time.
722
* We use the native word size even in compat mode because that
723
* is the unit ptrace(2) writes in terms of.
724
*/
725
for (;;) {
726
for (i = 0; i < sizeof(u.buf); i++) {
727
if (*str == '\0') {
728
/* NUL-pad buf to sizeof(unsigned long). */
729
u.buf[i] = '\0';
730
continue;
731
}
732
u.buf[i] = *str++;
733
}
734
if (ptrace(PTRACE_POKEDATA, pid, addr, u.word) == -1) {
735
sudo_warn("%s: ptrace(PTRACE_POKEDATA, %d, 0x%lx, %.*s)",
736
__func__, (int)pid, addr, (int)sizeof(u.buf), u.buf);
737
debug_return_ssize_t(-1);
738
}
739
if ((u.word & 0xff) == 0) {
740
/* If the last byte we wrote is a NUL we are done. */
741
debug_return_ssize_t(str - str0 + 1);
742
}
743
addr += sizeof(unsigned long);
744
}
745
}
746
747
#ifdef HAVE_PROCESS_VM_READV
748
/*
749
* Write the string vector vec to addr in the tracee which must have
750
* sufficient space. Strings are written to strtab.
751
* Returns the number of bytes used in strtab (including NULs).
752
* process_vm_writev() version.
753
*/
754
static ssize_t
755
ptrace_writev_vec(pid_t pid, struct sudo_ptrace_regs *regs, char **vec,
756
unsigned long addr, unsigned long strtab)
757
{
758
const unsigned long addr0 = addr;
759
const unsigned long strtab0 = strtab;
760
unsigned long *addrbuf = NULL;
761
struct iovec *local, *remote;
762
struct iovec local_addrs, remote_addrs;
763
size_t i, j, len, off = 0;
764
ssize_t expected = -1, nwritten, total_written = 0;
765
debug_decl(ptrace_writev_vec, SUDO_DEBUG_EXEC);
766
767
/* Build up local and remote iovecs for process_vm_writev(2). */
768
for (len = 0; vec[len] != NULL; len++)
769
continue;
770
local = reallocarray(NULL, len, sizeof(struct iovec));
771
remote = reallocarray(NULL, len, sizeof(struct iovec));
772
j = regs->compat && (len & 1) != 0; /* pad for final NULL in compat */
773
addrbuf = reallocarray(NULL, len + 1 + j, regs->wordsize);
774
if (local == NULL || remote == NULL || addrbuf == NULL) {
775
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
776
goto done;
777
}
778
for (i = 0, j = 0; i < len; i++) {
779
unsigned long word = strtab;
780
781
/* Store remote string. */
782
const size_t size = strlen(vec[i]) + 1;
783
local[i].iov_base = vec[i];
784
local[i].iov_len = size;
785
remote[i].iov_base = (void *)strtab;
786
remote[i].iov_len = size;
787
strtab += size;
788
789
/* Store address of remote string. */
790
# ifdef SECCOMP_AUDIT_ARCH_COMPAT
791
if (regs->compat) {
792
/*
793
* For compat binaries we need to pack two 32-bit string addresses
794
* into a single 64-bit word. If this is the last string, NULL
795
* will be written as the second 32-bit address.
796
*/
797
if ((i & 1) == 1) {
798
/* Wrote this string address last iteration. */
799
continue;
800
}
801
# if BYTE_ORDER == BIG_ENDIAN
802
word <<= 32;
803
if (vec[i + 1] != NULL)
804
word |= strtab;
805
# else
806
if (vec[i + 1] != NULL)
807
word |= strtab << 32;
808
# endif
809
}
810
# endif
811
addrbuf[j++] = word;
812
addr += sizeof(unsigned long);
813
}
814
if (!regs->compat || (len & 1) == 0) {
815
addrbuf[j] = 0;
816
}
817
818
/* Write strings addresses to addr0 on remote. */
819
local_addrs.iov_base = addrbuf;
820
local_addrs.iov_len = (len + 1) * regs->wordsize;
821
remote_addrs.iov_base = (void *)addr0;
822
remote_addrs.iov_len = local_addrs.iov_len;
823
if (process_vm_writev(pid, &local_addrs, 1, &remote_addrs, 1, 0) == -1)
824
goto done;
825
826
/* Copy the strings to the (remote) string table. */
827
expected = (ssize_t)(strtab - strtab0);
828
for (;;) {
829
nwritten = process_vm_writev(pid, local + off, len - off,
830
remote + off, len - off, 0);
831
switch (nwritten) {
832
case -1:
833
sudo_debug_printf(
834
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
835
"process_vm_writev(%d, 0x%lx, %zu, 0x%lx, %zu, 0)",
836
(int)pid, (unsigned long)local + off, len - off,
837
(unsigned long)remote + off, len - off);
838
goto done;
839
case 0:
840
sudo_debug_printf(
841
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
842
"process_vm_writev(%d, 0x%lx, %zu, 0x%lx, %zu, 0): %s",
843
(int)pid, (unsigned long)local + off, len - off,
844
(unsigned long)remote + off, len - off,
845
"zero bytes written");
846
goto done;
847
default:
848
total_written += nwritten;
849
if (total_written >= expected)
850
goto done;
851
852
/* Adjust offset for partial write (doesn't cross iov boundary). */
853
while (off < len) {
854
nwritten -= (ssize_t)local[off].iov_len;
855
off++;
856
if (nwritten <= 0)
857
break;
858
}
859
if (off == len) {
860
sudo_debug_printf(
861
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
862
"overflow while resuming process_vm_writev()");
863
goto done;
864
}
865
break;
866
}
867
}
868
done:
869
free(local);
870
free(remote);
871
free(addrbuf);
872
if (total_written == expected)
873
debug_return_ssize_t(total_written);
874
debug_return_ssize_t(-1);
875
}
876
#endif /* HAVE_PROCESS_VM_READV */
877
878
/*
879
* Write the string vector vec to addr in the tracee which must have
880
* sufficient space. Strings are written to strtab.
881
* Returns the number of bytes used in strtab (including NULs).
882
*/
883
static ssize_t
884
ptrace_write_vec(pid_t pid, struct sudo_ptrace_regs *regs, char **vec,
885
unsigned long addr, unsigned long strtab)
886
{
887
const unsigned long strtab0 = strtab;
888
ssize_t nwritten;
889
size_t i;
890
debug_decl(ptrace_write_vec, SUDO_DEBUG_EXEC);
891
892
#ifdef HAVE_PROCESS_VM_READV
893
nwritten = ptrace_writev_vec(pid, regs, vec, addr, strtab);
894
if (nwritten != -1 || errno != ENOSYS)
895
debug_return_ssize_t(nwritten);
896
#endif /* HAVE_PROCESS_VM_READV */
897
898
/* Copy string vector into tracee one word at a time. */
899
for (i = 0; vec[i] != NULL; i++) {
900
unsigned long word = strtab;
901
902
/* First write the actual string to tracee's string table. */
903
nwritten = ptrace_write_string(pid, strtab, vec[i]);
904
if (nwritten == -1)
905
debug_return_ssize_t(-1);
906
strtab += (size_t)nwritten;
907
908
# ifdef SECCOMP_AUDIT_ARCH_COMPAT
909
if (regs->compat) {
910
/*
911
* For compat binaries we need to pack two 32-bit string addresses
912
* into a single 64-bit word. If this is the last string, NULL
913
* will be written as the second 32-bit address.
914
*/
915
if ((i & 1) == 1) {
916
/* Wrote this string address last iteration. */
917
continue;
918
}
919
# if BYTE_ORDER == BIG_ENDIAN
920
word <<= 32;
921
if (vec[i + 1] != NULL)
922
word |= strtab;
923
# else
924
if (vec[i + 1] != NULL)
925
word |= strtab << 32;
926
# endif
927
}
928
# endif
929
/* Next write the string address to tracee at addr. */
930
if (ptrace(PTRACE_POKEDATA, pid, addr, word) == -1) {
931
sudo_warn("%s: ptrace(PTRACE_POKEDATA, %d, 0x%lx, 0x%lx)",
932
__func__, (int)pid, addr, word);
933
debug_return_ssize_t(-1);
934
}
935
addr += sizeof(unsigned long);
936
}
937
938
/* Finally, write the terminating NULL to tracee if needed. */
939
if (!regs->compat || (i & 1) == 0) {
940
if (ptrace(PTRACE_POKEDATA, pid, addr, NULL) == -1) {
941
sudo_warn("%s: ptrace(PTRACE_POKEDATA, %d, 0x%lx, NULL)",
942
__func__, (int)pid, addr);
943
debug_return_ssize_t(-1);
944
}
945
}
946
947
debug_return_ssize_t((ssize_t)(strtab - strtab0));
948
}
949
950
/*
951
* Read a link from /proc/PID and store the result in buf.
952
* Used to read the cwd and exe links in /proc/PID.
953
* Returns true on success, else false.
954
*/
955
static bool
956
proc_read_link(pid_t pid, const char *name, char *buf, size_t bufsize)
957
{
958
ssize_t len;
959
char path[PATH_MAX];
960
debug_decl(proc_read_link, SUDO_DEBUG_EXEC);
961
962
len = snprintf(path, sizeof(path), "/proc/%d/%s", (int)pid, name);
963
if (len > 0 && len < ssizeof(path)) {
964
len = readlink(path, buf, bufsize - 1);
965
if (len != -1) {
966
/* readlink(2) does not add the NUL for us. */
967
buf[len] = '\0';
968
debug_return_bool(true);
969
}
970
}
971
debug_return_bool(false);
972
}
973
974
/*
975
* Read the filename, argv and envp of the execve(2) system call.
976
* Returns a dynamically allocated buffer the parent is responsible for.
977
*/
978
static char *
979
get_execve_info(pid_t pid, struct sudo_ptrace_regs *regs, char **pathname_out,
980
int *argc_out, char ***argv_out, int *envc_out, char ***envp_out)
981
{
982
char *argbuf, **argv, **envp, *pathname = NULL;
983
unsigned long argv_addr, envp_addr, path_addr;
984
size_t bufsize, off = 0;
985
int i, argc, envc = 0;
986
ssize_t nread;
987
debug_decl(get_execve_info, SUDO_DEBUG_EXEC);
988
989
bufsize = PATH_MAX + arg_max;
990
argbuf = malloc(bufsize);
991
if (argbuf == NULL) {
992
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
993
goto bad;
994
}
995
996
/* execve(2) takes three arguments: pathname, argv, envp. */
997
path_addr = get_sc_arg1(regs);
998
argv_addr = get_sc_arg2(regs);
999
envp_addr = get_sc_arg3(regs);
1000
sudo_debug_printf(SUDO_DEBUG_INFO,
1001
"%s: %d: path 0x%lx, argv 0x%lx, envp 0x%lx", __func__,
1002
(int)pid, path_addr, argv_addr, envp_addr);
1003
1004
/* Read the pathname, if not NULL. */
1005
if (path_addr != 0) {
1006
nread = ptrace_read_string(pid, path_addr, argbuf, bufsize);
1007
if (nread == -1) {
1008
sudo_debug_printf(
1009
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
1010
"unable to read execve pathname for process %d", (int)pid);
1011
goto bad;
1012
}
1013
/* Defer setting pathname until after all reallocations are done. */
1014
off = (size_t)nread;
1015
}
1016
1017
/* Read argv */
1018
nread = ptrace_read_vec(pid, regs, argv_addr, &argc, &argv, &argbuf,
1019
&bufsize, off);
1020
if (nread == -1) {
1021
sudo_debug_printf(
1022
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
1023
"unable to read execve argv for process %d", (int)pid);
1024
goto bad;
1025
}
1026
off += (size_t)nread;
1027
1028
if (argc == 0) {
1029
/* Reserve an extra slot so we can store argv[0]. */
1030
while (bufsize - off < sizeof(char *)) {
1031
if (!growbuf(&argbuf, &bufsize, NULL, NULL))
1032
goto bad;
1033
}
1034
off += sizeof(char *);
1035
}
1036
1037
/* Read envp */
1038
nread = ptrace_read_vec(pid, regs, envp_addr, &envc, &envp, &argbuf,
1039
&bufsize, off);
1040
if (nread == -1) {
1041
sudo_debug_printf(
1042
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
1043
"unable to read execve envp for process %d", (int)pid);
1044
goto bad;
1045
}
1046
1047
/* Set pathname now that argbuf has been fully allocated. */
1048
if (path_addr != 0)
1049
pathname = argbuf;
1050
1051
/* Convert offsets in argv and envp to pointers. */
1052
argv = (char **)(argbuf + (unsigned long)argv);
1053
for (i = 0; i < argc; i++) {
1054
argv[i] = argbuf + (unsigned long)argv[i];
1055
}
1056
envp = (char **)(argbuf + (unsigned long)envp);
1057
for (i = 0; i < envc; i++) {
1058
envp[i] = argbuf + (unsigned long)envp[i];
1059
}
1060
1061
sudo_debug_execve(SUDO_DEBUG_DIAG, pathname, argv, envp);
1062
1063
*pathname_out = pathname;
1064
*argc_out = argc;
1065
*argv_out = argv;
1066
*envc_out = envc;
1067
*envp_out = envp;
1068
1069
debug_return_ptr(argbuf);
1070
bad:
1071
free(argbuf);
1072
debug_return_ptr(NULL);
1073
}
1074
1075
/*
1076
* Cause the current syscall to fail and set the error value to ecode.
1077
*/
1078
static bool
1079
ptrace_fail_syscall(pid_t pid, struct sudo_ptrace_regs *regs, int ecode)
1080
{
1081
sigset_t chldmask;
1082
bool ret = false;
1083
int status;
1084
debug_decl(ptrace_fail_syscall, SUDO_DEBUG_EXEC);
1085
1086
/* Cause the syscall to fail by changing its number to -1. */
1087
set_syscallno(pid, regs, -1);
1088
if (!ptrace_setregs(pid, regs)) {
1089
sudo_warn(U_("unable to set registers for process %d"), (int)pid);
1090
debug_return_bool(false);
1091
}
1092
1093
/* Block SIGCHLD for the critical section (waitpid). */
1094
sigemptyset(&chldmask);
1095
sigaddset(&chldmask, SIGCHLD);
1096
sigprocmask(SIG_BLOCK, &chldmask, NULL);
1097
1098
/* Allow the syscall to continue and change return value to ecode. */
1099
ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
1100
for (;;) {
1101
if (waitpid(pid, &status, __WALL) != -1)
1102
break;
1103
if (errno == EINTR)
1104
continue;
1105
sudo_warn(U_("%s: %s"), __func__, "waitpid");
1106
goto done;
1107
}
1108
if (!WIFSTOPPED(status)) {
1109
sudo_warnx(U_("process %d exited unexpectedly"), (int)pid);
1110
goto done;
1111
}
1112
set_sc_retval(regs, -ecode);
1113
if (!ptrace_setregs(pid, regs)) {
1114
sudo_warn(U_("unable to set registers for process %d"), (int)pid);
1115
goto done;
1116
}
1117
1118
ret = true;
1119
1120
done:
1121
sigprocmask(SIG_UNBLOCK, &chldmask, NULL);
1122
1123
debug_return_bool(ret);
1124
}
1125
1126
/*
1127
* Check whether seccomp(2) filtering supports ptrace(2) traps.
1128
* Only supported by Linux 4.14 and higher.
1129
*/
1130
static bool
1131
have_seccomp_action(const char *action)
1132
{
1133
char line[LINE_MAX];
1134
bool ret = false;
1135
FILE *fp;
1136
debug_decl(have_seccomp_action, SUDO_DEBUG_EXEC);
1137
1138
fp = fopen("/proc/sys/kernel/seccomp/actions_avail", "r");
1139
if (fp != NULL) {
1140
if (fgets(line, sizeof(line), fp) != NULL) {
1141
char *cp, *last;
1142
1143
for ((cp = strtok_r(line, " \t\n", &last)); cp != NULL;
1144
(cp = strtok_r(NULL, " \t\n", &last))) {
1145
if (strcmp(cp, action) == 0) {
1146
ret = true;
1147
break;
1148
}
1149
}
1150
}
1151
fclose(fp);
1152
}
1153
debug_return_bool(ret);
1154
}
1155
1156
/*
1157
* Intercept execve(2) and execveat(2) using seccomp(2) and ptrace(2).
1158
* If no tracer is present, execve(2) and execveat(2) will fail with ENOSYS.
1159
* Must be called with CAP_SYS_ADMIN, before privs are dropped.
1160
*/
1161
bool
1162
set_exec_filter(void)
1163
{
1164
struct sock_filter exec_filter[] = {
1165
/* Load architecture value (AUDIT_ARCH_*) into the accumulator. */
1166
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, arch)),
1167
# ifdef SECCOMP_AUDIT_ARCH_COMPAT2
1168
/* Match on the compat2 architecture or jump to the compat check. */
1169
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECCOMP_AUDIT_ARCH_COMPAT2, 0, 4),
1170
/* Load syscall number into the accumulator. */
1171
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
1172
/* Jump to trace for compat2 execve(2)/execveat(2), else allow. */
1173
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, COMPAT2_execve, 1, 0),
1174
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, COMPAT2_execveat, 0, 13),
1175
/* Trace execve(2)/execveat(2) syscalls (w/ compat flag) */
1176
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRACE | COMPAT_FLAG),
1177
# endif /* SECCOMP_AUDIT_ARCH_COMPAT2 */
1178
# ifdef SECCOMP_AUDIT_ARCH_COMPAT
1179
/* Match on the compat architecture or jump to the native arch check. */
1180
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECCOMP_AUDIT_ARCH_COMPAT, 0, 4),
1181
/* Load syscall number into the accumulator. */
1182
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
1183
/* Jump to trace for compat execve(2)/execveat(2), else allow. */
1184
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, COMPAT_execve, 1, 0),
1185
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, COMPAT_execveat, 0, 8),
1186
/* Trace execve(2)/execveat(2) syscalls (w/ compat flag) */
1187
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRACE | COMPAT_FLAG),
1188
# endif /* SECCOMP_AUDIT_ARCH_COMPAT */
1189
/* Kill the process unless the (native) architecture matches. */
1190
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECCOMP_AUDIT_ARCH, 1, 0),
1191
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS),
1192
/* Load syscall number into the accumulator. */
1193
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
1194
/* Jump to trace for execve(2)/execveat(2), else allow. */
1195
# ifdef X32_execve
1196
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, X32_execve, 3, 0),
1197
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, X32_execveat, 2, 0),
1198
# else
1199
/* No x32 support, check native system call numbers. */
1200
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execve, 3, 0),
1201
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execveat, 2, 3),
1202
# endif /* X32_execve */
1203
/* If no x32 support, these two instructions are never reached. */
1204
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execve, 1, 0),
1205
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execveat, 0, 1),
1206
/* Trace execve(2)/execveat(2) syscalls */
1207
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRACE),
1208
/* Allow non-matching syscalls */
1209
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
1210
};
1211
const struct sock_fprog exec_fprog = {
1212
nitems(exec_filter),
1213
exec_filter
1214
};
1215
debug_decl(set_exec_filter, SUDO_DEBUG_EXEC);
1216
1217
/* We must set SECCOMP_MODE_FILTER before dropping privileges. */
1218
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &exec_fprog) == -1) {
1219
sudo_warn("%s", U_("unable to set seccomp filter"));
1220
debug_return_bool(false);
1221
}
1222
debug_return_bool(true);
1223
}
1224
1225
/*
1226
* Seize control of the specified child process which must be in
1227
* ptrace wait. Returns true on success, false if child is already
1228
* being traced and -1 on error.
1229
*/
1230
int
1231
exec_ptrace_seize(pid_t child)
1232
{
1233
const long ptrace_opts = PTRACE_O_TRACESECCOMP|PTRACE_O_TRACECLONE|
1234
PTRACE_O_TRACEFORK|PTRACE_O_TRACEVFORK|
1235
PTRACE_O_TRACEEXEC;
1236
int ret = -1;
1237
int status;
1238
debug_decl(exec_ptrace_seize, SUDO_DEBUG_EXEC);
1239
1240
#ifdef HAVE_PROCESS_VM_READV
1241
page_size = (size_t)sysconf(_SC_PAGESIZE);
1242
if (page_size == (size_t)-1)
1243
page_size = 4096;
1244
#endif
1245
arg_max = (size_t)sysconf(_SC_ARG_MAX);
1246
if (arg_max == (size_t)-1)
1247
arg_max = 128 * 1024;
1248
1249
/* Seize control of the child process. */
1250
if (ptrace(PTRACE_SEIZE, child, NULL, ptrace_opts) == -1) {
1251
/*
1252
* If the process is already being traced, we will get EPERM.
1253
* We don't treat that as a fatal error since we want it to be
1254
* possible to run sudo inside a sudo shell with intercept enabled.
1255
*/
1256
if (errno != EPERM) {
1257
sudo_warn("%s: ptrace(PTRACE_SEIZE, %d, NULL, 0x%lx)",
1258
__func__, (int)child, ptrace_opts);
1259
goto done;
1260
}
1261
sudo_debug_printf(SUDO_DEBUG_WARN,
1262
"%s: unable to trace process %d, already being traced?",
1263
__func__, (int)child);
1264
ret = false;
1265
}
1266
1267
/* The child is suspended waiting for SIGUSR1, wake it up. */
1268
if (kill(child, SIGUSR1) == -1) {
1269
sudo_warn("kill(%d, SIGUSR1)", (int)child);
1270
goto done;
1271
}
1272
if (!ret)
1273
goto done;
1274
1275
/* Wait for the child to enter trace stop and continue it. */
1276
for (;;) {
1277
if (waitpid(child, &status, __WALL) != -1)
1278
break;
1279
if (errno == EINTR)
1280
continue;
1281
sudo_warn(U_("%s: %s"), __func__, "waitpid");
1282
goto done;
1283
}
1284
if (!WIFSTOPPED(status)) {
1285
sudo_warnx(U_("process %d exited unexpectedly"), (int)child);
1286
goto done;
1287
}
1288
if (ptrace(PTRACE_CONT, child, NULL, (void *)SIGUSR1) == -1) {
1289
sudo_warn("%s: ptrace(PTRACE_CONT, %d, NULL, SIGUSR1)",
1290
__func__, (int)child);
1291
goto done;
1292
}
1293
1294
ret = true;
1295
1296
done:
1297
debug_return_int(ret);
1298
}
1299
1300
/*
1301
* Compare two pathnames. If do_stat is true, fall back to stat(2)ing
1302
* the paths for a dev/inode match if the strings don't match.
1303
* Returns true on match, else false.
1304
*/
1305
static bool
1306
pathname_matches(const char *path1, const char *path2, bool do_stat)
1307
{
1308
struct stat sb1, sb2;
1309
debug_decl(pathname_matches, SUDO_DEBUG_EXEC);
1310
1311
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: compare %s to %s", __func__,
1312
path1 ? path1 : "(NULL)", path2 ? path2 : "(NULL)");
1313
1314
if (path1 == NULL || path2 == NULL)
1315
debug_return_bool(false);
1316
1317
if (strcmp(path1, path2) == 0)
1318
debug_return_bool(true);
1319
1320
if (do_stat && stat(path1, &sb1) == 0 && stat(path2, &sb2) == 0) {
1321
if (sb1.st_dev == sb2.st_dev && sb1.st_ino == sb2.st_ino)
1322
debug_return_bool(true);
1323
}
1324
1325
debug_return_bool(false);
1326
}
1327
1328
/*
1329
* Open script and check for '#!' magic number followed by an interpreter.
1330
* If present, check the interpreter against execpath, and argument string
1331
* (if any) against argv[1].
1332
* Returns number of argv entries to skip on success, else 0.
1333
*/
1334
static int
1335
script_matches(const char *script, const char *execpath, int argc,
1336
char * const *argv)
1337
{
1338
char * const *orig_argv = argv;
1339
size_t linesize = 0;
1340
char *interp, *interp_args, *line = NULL;
1341
char magic[2];
1342
int count;
1343
FILE *fp = NULL;
1344
ssize_t len;
1345
debug_decl(get_interpreter, SUDO_DEBUG_EXEC);
1346
1347
/* Linux allows up to 4 nested interpreters. */
1348
for (count = 0; count < 4; count++) {
1349
if (fp != NULL)
1350
fclose(fp);
1351
fp = fopen(script, "r");
1352
if (fp == NULL) {
1353
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO,
1354
"%s: unable to open %s for reading", __func__, script);
1355
goto done;
1356
}
1357
1358
if (fread(magic, 1, 2, fp) != 2 || memcmp(magic, "#!", 2) != 0) {
1359
sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: %s: not a script",
1360
__func__, script);
1361
goto done;
1362
}
1363
1364
/* Check interpreter, skipping the shebang and trim trailing space. */
1365
len = getdelim(&line, &linesize, '\n', fp);
1366
if (len == -1) {
1367
sudo_debug_printf(SUDO_DEBUG_ERROR, "%s: %s: can't get interpreter",
1368
__func__, script);
1369
goto done;
1370
}
1371
while (len > 0 && isspace((unsigned char)line[len - 1])) {
1372
len--;
1373
line[len] = '\0';
1374
}
1375
sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: %s: shebang line \"%s\"",
1376
__func__, script, line);
1377
1378
/*
1379
* Split line into interpreter and args.
1380
* Whitespace is not supported in the interpreter path.
1381
*/
1382
for (interp = line; isspace((unsigned char)*interp); interp++)
1383
continue;
1384
interp_args = strpbrk(interp, " \t");
1385
if (interp_args != NULL) {
1386
*interp_args++ = '\0';
1387
while (isspace((unsigned char)*interp_args))
1388
interp_args++;
1389
}
1390
1391
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: interpreter %s, args \"%s\"",
1392
__func__, interp, interp_args ? interp_args : "");
1393
1394
/* Match interpreter. */
1395
if (!pathname_matches(execpath, interp, true)) {
1396
/* It is possible for the interpreter to be a script too. */
1397
if (argc > 0 && strcmp(interp, argv[1]) == 0) {
1398
/* Interpreter args must match for *this* interpreter. */
1399
if (interp_args == NULL ||
1400
(argc > 1 && strcmp(interp_args, argv[2]) == 0)) {
1401
script = interp;
1402
argv++;
1403
argc--;
1404
if (interp_args != NULL) {
1405
argv++;
1406
argc--;
1407
}
1408
/* Check whether interp is itself a script. */
1409
continue;
1410
}
1411
}
1412
}
1413
if (argc > 0 && interp_args != NULL) {
1414
if (strcmp(interp_args, argv[1]) != 0) {
1415
sudo_warnx(
1416
U_("interpreter argument , expected \"%s\", got \"%s\""),
1417
interp_args, argc > 1 ? argv[1] : "(NULL)");
1418
goto done;
1419
}
1420
argv++;
1421
}
1422
argv++;
1423
break;
1424
}
1425
1426
done:
1427
free(line);
1428
if (fp != NULL)
1429
fclose(fp);
1430
debug_return_int((int)(argv - orig_argv));
1431
}
1432
1433
static ssize_t
1434
proc_read_vec(pid_t pid, const char *name, int *countp, char ***vecp,
1435
char **bufp, size_t *bufsizep, size_t off)
1436
{
1437
size_t strtab_len, remainder = *bufsizep - off;
1438
char path[PATH_MAX], *strtab = *bufp + off;
1439
ssize_t len, nread;
1440
int fd;
1441
debug_decl(proc_read_vec, SUDO_DEBUG_EXEC);
1442
1443
len = snprintf(path, sizeof(path), "/proc/%d/%s", (int)pid, name);
1444
if (len >= ssizeof(path))
1445
debug_return_ssize_t(-1);
1446
1447
fd = open(path, O_RDONLY);
1448
if (fd == -1)
1449
debug_return_ssize_t(-1);
1450
1451
/* Read in strings until EOF. */
1452
do {
1453
nread = read(fd, strtab, remainder);
1454
if (nread < 0) {
1455
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
1456
"%s: unable to read %s", __func__, path);
1457
close(fd);
1458
debug_return_ssize_t(-1);
1459
}
1460
strtab += nread;
1461
remainder -= (size_t)nread;
1462
if (remainder < sizeof(char *)) {
1463
while (!growbuf(bufp, bufsizep, &strtab, &remainder)) {
1464
close(fd);
1465
debug_return_ssize_t(-1);
1466
}
1467
}
1468
} while (nread != 0);
1469
close(fd);
1470
1471
/* Trim off the extra NUL byte at the end of the string table. */
1472
if (strtab - *bufp >= 2 && strtab[-1] == '\0' && strtab[-2] == '\0') {
1473
strtab--;
1474
remainder++;
1475
}
1476
1477
/* Store strings in a vector after the string table. */
1478
strtab_len = (size_t)(strtab - (*bufp + off));
1479
strtab = *bufp + off;
1480
len = strtab_to_vec(strtab, strtab_len, countp, vecp, bufp, bufsizep,
1481
remainder);
1482
if (len == -1)
1483
debug_return_ssize_t(-1);
1484
1485
debug_return_ssize_t((ssize_t)strtab_len + len);
1486
}
1487
1488
/*
1489
* Check if the execve(2) arguments match the contents of closure.
1490
* Returns true if they match, else false.
1491
*/
1492
static bool
1493
execve_args_match(const char *pathname, int argc, char * const *argv,
1494
int envc, char * const *envp, bool do_stat,
1495
struct intercept_closure *closure)
1496
{
1497
bool ret = true;
1498
int i;
1499
debug_decl(execve_args_match, SUDO_DEBUG_EXEC);
1500
1501
if (!pathname_matches(pathname, closure->command, do_stat)) {
1502
/* For scripts, pathname will refer to the interpreter instead. */
1503
if (do_stat) {
1504
int skip = script_matches(closure->command, pathname,
1505
argc, argv);
1506
if (skip != 0) {
1507
/* Skip interpreter (and args) in argv. */
1508
argv += skip;
1509
argc -= skip;
1510
goto check_argv;
1511
}
1512
}
1513
sudo_warnx(
1514
U_("pathname mismatch, expected \"%s\", got \"%s\""),
1515
closure->command, pathname ? pathname : "(NULL)");
1516
ret = false;
1517
}
1518
check_argv:
1519
for (i = 0; i < argc; i++) {
1520
if (closure->run_argv[i] == NULL) {
1521
ret = false;
1522
sudo_warnx(
1523
U_("%s[%d] mismatch, expected \"%s\", got \"%s\""),
1524
"argv", i, "(NULL)", argv[i] ? argv[i] : "(NULL)");
1525
break;
1526
}
1527
if (argv[i] == NULL) {
1528
ret = false;
1529
sudo_warnx(
1530
U_("%s[%d] mismatch, expected \"%s\", got \"%s\""),
1531
"argv", i, closure->run_argv[i], "(NULL)");
1532
break;
1533
}
1534
if (strcmp(argv[i], closure->run_argv[i]) != 0) {
1535
if (i == 0) {
1536
/* Special case for argv[0] which may contain the basename. */
1537
const char *base;
1538
if (argv[0][0] == '/') {
1539
if (closure->run_argv[0][0] != '/') {
1540
base = sudo_basename(argv[0]);
1541
if (strcmp(base, closure->run_argv[0]) == 0)
1542
continue;
1543
}
1544
} else {
1545
if (closure->run_argv[0][0] == '/') {
1546
base = sudo_basename(closure->run_argv[0]);
1547
if (strcmp(argv[0], base) == 0)
1548
continue;
1549
}
1550
}
1551
}
1552
ret = false;
1553
sudo_warnx(
1554
U_("%s[%d] mismatch, expected \"%s\", got \"%s\""),
1555
"argv", i, closure->run_argv[i], argv[i]);
1556
}
1557
}
1558
for (i = 0; i < envc; i++) {
1559
if (closure->run_envp[i] == NULL) {
1560
ret = false;
1561
sudo_warnx(
1562
U_("%s[%d] mismatch, expected \"%s\", got \"%s\""),
1563
"envp", i, "(NULL)", envp[i] ? envp[i] : "(NULL)");
1564
break;
1565
} else if (envp[i] == NULL) {
1566
ret = false;
1567
sudo_warnx(
1568
U_("%s[%d] mismatch, expected \"%s\", got \"%s\""),
1569
"envp", i, closure->run_envp[i], "(NULL)");
1570
break;
1571
} else if (strcmp(envp[i], closure->run_envp[i]) != 0) {
1572
ret = false;
1573
sudo_warnx(
1574
U_("%s[%d] mismatch, expected \"%s\", got \"%s\""),
1575
"envp", i, closure->run_envp[i], envp[i]);
1576
}
1577
}
1578
1579
debug_return_bool(ret);
1580
}
1581
1582
/*
1583
* Verify that the execve(2) argument we wrote match the contents of closure.
1584
* Returns true if they match, else false.
1585
*/
1586
static bool
1587
verify_execve_args(pid_t pid, struct sudo_ptrace_regs *regs,
1588
struct intercept_closure *closure)
1589
{
1590
char *pathname, **argv, **envp, *buf;
1591
int argc, envc;
1592
bool ret = false;
1593
debug_decl(verify_execve_args, SUDO_DEBUG_EXEC);
1594
1595
buf = get_execve_info(pid, regs, &pathname, &argc, &argv,
1596
&envc, &envp);
1597
if (buf != NULL) {
1598
ret = execve_args_match(pathname, argc, argv, envc, envp, false, closure);
1599
free(buf);
1600
}
1601
1602
debug_return_bool(ret);
1603
}
1604
1605
/*
1606
* Verify that the command executed matches the arguments we checked.
1607
* Returns true on success and false on error.
1608
*/
1609
static bool
1610
ptrace_verify_post_exec(pid_t pid, struct sudo_ptrace_regs *regs,
1611
struct intercept_closure *closure)
1612
{
1613
char **argv, **envp, *argbuf = NULL;
1614
char pathname[PATH_MAX];
1615
sigset_t chldmask;
1616
bool ret = false;
1617
int argc, envc, i, status;
1618
size_t bufsize;
1619
ssize_t len;
1620
debug_decl(ptrace_verify_post_exec, SUDO_DEBUG_EXEC);
1621
1622
/* Block SIGCHLD for the critical section (waitpid). */
1623
sigemptyset(&chldmask);
1624
sigaddset(&chldmask, SIGCHLD);
1625
sigprocmask(SIG_BLOCK, &chldmask, NULL);
1626
1627
/* Allow execve(2) to continue and wait for PTRACE_EVENT_EXEC. */
1628
ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
1629
for (;;) {
1630
if (waitpid(pid, &status, __WALL) != -1)
1631
break;
1632
if (errno == EINTR)
1633
continue;
1634
sudo_warn(U_("%s: %s"), __func__, "waitpid");
1635
goto done;
1636
}
1637
if (!WIFSTOPPED(status)) {
1638
sudo_warnx(U_("process %d exited unexpectedly"), (int)pid);
1639
goto done;
1640
}
1641
if (status >> 8 != (SIGTRAP | (PTRACE_EVENT_EXEC << 8))) {
1642
sudo_warnx(U_("process %d unexpected status 0x%x"), (int)pid, status);
1643
goto done;
1644
}
1645
1646
/* Get the executable path. */
1647
if (!proc_read_link(pid, "exe", pathname, sizeof(pathname))) {
1648
/* Missing /proc file system is not a fatal error. */
1649
sudo_debug_printf(SUDO_DEBUG_ERROR, "%s: unable to read /proc/%d/exe",
1650
__func__, (int)pid);
1651
ret = true;
1652
goto done;
1653
}
1654
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %d: verify %s", __func__,
1655
(int)pid, pathname);
1656
1657
/* Allocate a single buffer for argv, envp and their strings. */
1658
bufsize = arg_max;
1659
argbuf = malloc(bufsize);
1660
if (argbuf == NULL) {
1661
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1662
goto done;
1663
}
1664
1665
len = proc_read_vec(pid, "cmdline", &argc, &argv, &argbuf, &bufsize, 0);
1666
if (len == -1) {
1667
sudo_debug_printf(
1668
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
1669
"unable to read execve argv for process %d", (int)pid);
1670
goto done;
1671
}
1672
1673
len = proc_read_vec(pid, "environ", &envc, &envp, &argbuf, &bufsize,
1674
(size_t)len);
1675
if (len == -1) {
1676
sudo_debug_printf(
1677
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
1678
"unable to read execve envp for process %d", (int)pid);
1679
goto done;
1680
}
1681
1682
/* Convert offsets in argv and envp to pointers. */
1683
argv = (char **)(argbuf + (unsigned long)argv);
1684
for (i = 0; i < argc; i++) {
1685
argv[i] = argbuf + (unsigned long)argv[i];
1686
}
1687
envp = (char **)(argbuf + (unsigned long)envp);
1688
for (i = 0; i < envc; i++) {
1689
envp[i] = argbuf + (unsigned long)envp[i];
1690
}
1691
1692
ret = execve_args_match(pathname, argc, argv, envc, envp, true, closure);
1693
if (!ret) {
1694
sudo_debug_printf(SUDO_DEBUG_ERROR,
1695
"%s: %d new execve args don't match closure", __func__, (int)pid);
1696
}
1697
1698
done:
1699
free(argbuf);
1700
sigprocmask(SIG_UNBLOCK, &chldmask, NULL);
1701
1702
debug_return_bool(ret);
1703
}
1704
1705
/*
1706
* Intercept execve(2) and perform a policy check.
1707
* Reads current registers and execve(2) arguments.
1708
* If the command is not allowed by policy, fail with EACCES.
1709
* If the command is allowed, update argv if needed before continuing.
1710
* Returns true on success and false on error.
1711
*/
1712
static bool
1713
ptrace_intercept_execve(pid_t pid, struct intercept_closure *closure)
1714
{
1715
char *pathname, **argv, **envp, *buf;
1716
const unsigned int flags = closure->details->flags;
1717
int argc, envc, syscallno;
1718
struct sudo_ptrace_regs regs;
1719
bool path_mismatch = false;
1720
bool argv_mismatch = false;
1721
char cwd[PATH_MAX], *orig_argv0;
1722
unsigned long msg;
1723
bool ret = false;
1724
int i, oldcwd = -1;
1725
debug_decl(ptrace_intercept_execve, SUDO_DEBUG_EXEC);
1726
1727
/* Do not check the policy if we are executing the initial command. */
1728
if (closure->initial_command != 0) {
1729
closure->initial_command--;
1730
debug_return_bool(true);
1731
}
1732
1733
/* Get compat flag. */
1734
if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, &msg) == -1) {
1735
sudo_warn(U_("unable to get event message for process %d"), (int)pid);
1736
debug_return_bool(false);
1737
}
1738
1739
/* Get the registers. */
1740
memset(&regs, 0, sizeof(regs));
1741
if (!ptrace_getregs(pid, &regs, msg)) {
1742
sudo_warn(U_("unable to get registers for process %d"), (int)pid);
1743
debug_return_bool(false);
1744
}
1745
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %d: compat: %s, wordsize: %u",
1746
__func__, (int)pid, regs.compat ? "true" : "false", regs.wordsize);
1747
1748
# ifdef SECCOMP_AUDIT_ARCH_COMPAT
1749
if (regs.compat) {
1750
syscallno = get_syscallno(&regs);
1751
switch (syscallno) {
1752
case COMPAT_execve:
1753
/* Handled below. */
1754
break;
1755
case COMPAT_execveat:
1756
/* We don't currently check execveat(2). */
1757
debug_return_bool(true);
1758
break;
1759
default:
1760
sudo_warnx("%s: unexpected compat system call %d",
1761
__func__, syscallno);
1762
debug_return_bool(false);
1763
}
1764
} else
1765
# endif /* SECCOMP_AUDIT_ARCH_COMPAT */
1766
{
1767
syscallno = get_syscallno(&regs);
1768
switch (syscallno) {
1769
# ifdef X32_execve
1770
case X32_execve:
1771
# endif
1772
case __NR_execve:
1773
/* Handled below. */
1774
break;
1775
# ifdef X32_execveat
1776
case X32_execveat:
1777
# endif
1778
case __NR_execveat:
1779
/* We don't currently check execveat(2). */
1780
debug_return_bool(true);
1781
break;
1782
default:
1783
sudo_warnx("%s: unexpected system call %d", __func__, syscallno);
1784
debug_return_bool(false);
1785
}
1786
}
1787
1788
/* Get the current working directory and execve info. */
1789
if (!proc_read_link(pid, "cwd", cwd, sizeof(cwd)))
1790
(void)strlcpy(cwd, "unknown", sizeof(cwd));
1791
buf = get_execve_info(pid, &regs, &pathname, &argc, &argv,
1792
&envc, &envp);
1793
if (buf == NULL) {
1794
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
1795
"%s: %d: unable to get execve info", __func__, (int)pid);
1796
/* EIO from ptrace is like EFAULT from the kernel. */
1797
if (errno == EIO)
1798
errno = EFAULT;
1799
ptrace_fail_syscall(pid, &regs, errno);
1800
goto done;
1801
}
1802
1803
/* Must have a pathname. */
1804
if (pathname == NULL) {
1805
ptrace_fail_syscall(pid, &regs, EINVAL);
1806
goto done;
1807
}
1808
1809
/* We can only pass the pathname to execute via argv[0] (plugin API). */
1810
orig_argv0 = argv[0] ? argv[0] : (char *)"";
1811
argv[0] = pathname;
1812
if (argc == 0) {
1813
/* Rewrite an empty argv[] with the path to execute. */
1814
argv[1] = NULL;
1815
argc = 1;
1816
argv_mismatch = true;
1817
}
1818
1819
/* Perform a policy check. */
1820
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %d: checking policy for %s",
1821
__func__, (int)pid, pathname);
1822
if (!intercept_check_policy(pathname, argc, argv, envc, envp, cwd,
1823
&oldcwd, closure)) {
1824
if (closure->errstr != NULL)
1825
sudo_warnx("%s", U_(closure->errstr));
1826
}
1827
1828
switch (closure->state) {
1829
case POLICY_TEST:
1830
path_mismatch = true;
1831
argv_mismatch = true;
1832
if (closure->command == NULL)
1833
closure->command = pathname;
1834
if (closure->run_argv == NULL)
1835
closure->run_argv = argv;
1836
if (closure->run_envp == NULL)
1837
closure->run_envp = envp;
1838
FALLTHROUGH;
1839
case POLICY_ACCEPT:
1840
/*
1841
* Update pathname and argv if the policy modified it.
1842
* We don't currently ever modify envp.
1843
*/
1844
if (strcmp(pathname, closure->command) != 0)
1845
path_mismatch = true;
1846
if (!path_mismatch) {
1847
/* Path unchanged, restore original argv[0]. */
1848
if (strcmp(argv[0], orig_argv0) != 0) {
1849
argv[0] = orig_argv0;
1850
free(closure->run_argv[0]);
1851
closure->run_argv[0] = strdup(orig_argv0);
1852
if (closure->run_argv[0] == NULL) {
1853
sudo_warnx(U_("%s: %s"), __func__,
1854
U_("unable to allocate memory"));
1855
}
1856
}
1857
}
1858
for (i = 0; closure->run_argv[i] != NULL && argv[i] != NULL; i++) {
1859
if (strcmp(closure->run_argv[i], argv[i]) != 0) {
1860
argv_mismatch = true;
1861
break;
1862
}
1863
}
1864
if (closure->run_argv[i] != NULL || argv[i] != NULL)
1865
argv_mismatch = true;
1866
1867
if (path_mismatch || argv_mismatch) {
1868
/*
1869
* Need to rewrite pathname and/or argv.
1870
* We can use space below the stack pointer to store the data.
1871
* On amd64 there is a 128 byte red zone that must be avoided.
1872
* Note: on pa-risc the stack grows up, not down.
1873
*/
1874
unsigned long sp = get_stack_pointer(&regs) - 128;
1875
unsigned long strtab;
1876
size_t space = 0;
1877
ssize_t nwritten;
1878
1879
sudo_debug_execve(SUDO_DEBUG_DIAG, closure->command,
1880
closure->run_argv, envp);
1881
1882
/*
1883
* Calculate the amount of space required for pointers + strings.
1884
* Since ptrace(2) always writes in sizeof(long) increments we
1885
* need to be careful to avoid overwriting what we have already
1886
* written for compat binaries (where the word size doesn't match).
1887
*
1888
* This is mostly a problem for the string table since we do
1889
* interleaved writes of the argument vector pointers and the
1890
* strings they refer to. For native binaries, it is sufficient
1891
* to align the string table on a word boundary. For compat
1892
* binaries, if argc is odd, writing the last pointer will overlap
1893
* the first string so leave an extra word in between them.
1894
*/
1895
if (argv_mismatch) {
1896
/* argv pointers */
1897
space += ((size_t)argc + 1 + regs.compat) * regs.wordsize;
1898
1899
/* argv strings */
1900
for (argc = 0; closure->run_argv[argc] != NULL; argc++) {
1901
space += strlen(closure->run_argv[argc]) + 1;
1902
}
1903
}
1904
if (path_mismatch) {
1905
/* pathname string */
1906
space += strlen(closure->command) + 1;
1907
}
1908
1909
/* Reserve stack space for path, argv (w/ NULL) and its strings. */
1910
sp -= WORDALIGN(space, regs);
1911
strtab = sp;
1912
1913
if (argv_mismatch) {
1914
/* Update argv address in the tracee to our new value. */
1915
set_sc_arg2(&regs, sp);
1916
1917
/* Skip over argv pointers (plus NULL) for string table. */
1918
strtab += ((size_t)argc + 1 + regs.compat) * regs.wordsize;
1919
1920
nwritten = ptrace_write_vec(pid, &regs, closure->run_argv,
1921
sp, strtab);
1922
if (nwritten == -1)
1923
goto done;
1924
strtab += (unsigned long)nwritten;
1925
}
1926
if (path_mismatch) {
1927
/* Update pathname address in the tracee to our new value. */
1928
set_sc_arg1(&regs, strtab);
1929
1930
/* Write pathname to the string table. */
1931
nwritten = ptrace_write_string(pid, strtab, closure->command);
1932
if (nwritten == -1)
1933
goto done;
1934
}
1935
1936
/* Update args in the tracee to the new values. */
1937
if (!ptrace_setregs(pid, &regs)) {
1938
sudo_warn(U_("unable to set registers for process %d"),
1939
(int)pid);
1940
goto done;
1941
}
1942
1943
if (closure->state == POLICY_TEST) {
1944
/* Verify the contents of what we just wrote. */
1945
if (!verify_execve_args(pid, &regs, closure)) {
1946
sudo_debug_printf(SUDO_DEBUG_ERROR,
1947
"%s: new execve args don't match closure", __func__);
1948
}
1949
}
1950
}
1951
if (closure->state == POLICY_ACCEPT && ISSET(flags, CD_INTERCEPT)) {
1952
if (ISSET(flags, CD_INTERCEPT_VERIFY)) {
1953
/* Verify execve(2) args post-exec. */
1954
if (!ptrace_verify_post_exec(pid, &regs, closure)) {
1955
if (errno != ESRCH)
1956
kill(pid, SIGKILL);
1957
}
1958
}
1959
}
1960
break;
1961
case POLICY_REJECT:
1962
/* If rejected, fake the syscall and set return to EACCES */
1963
errno = EACCES;
1964
FALLTHROUGH;
1965
default:
1966
ptrace_fail_syscall(pid, &regs, errno);
1967
break;
1968
}
1969
1970
ret = true;
1971
1972
done:
1973
if (oldcwd != -1) {
1974
if (fchdir(oldcwd) == -1) {
1975
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
1976
"%s: unable to restore saved cwd", __func__);
1977
}
1978
close(oldcwd);
1979
}
1980
free(buf);
1981
intercept_closure_reset(closure);
1982
1983
debug_return_bool(ret);
1984
}
1985
1986
/*
1987
* Handle a process stopped due to ptrace.
1988
* Restarts the tracee with PTRACE_LISTEN (for a group-stop)
1989
* or PTRACE_CONT (for signal-delivery-stop).
1990
* Returns true if stopped by a group-stop, else false.
1991
*/
1992
bool
1993
exec_ptrace_stopped(pid_t pid, int status, void *intercept)
1994
{
1995
struct intercept_closure *closure = intercept;
1996
const int stopsig = WSTOPSIG(status);
1997
const int sigtrap = status >> 8;
1998
long signo = 0;
1999
bool group_stop = false;
2000
debug_decl(exec_ptrace_stopped, SUDO_DEBUG_EXEC);
2001
2002
if (sigtrap == (SIGTRAP | (PTRACE_EVENT_SECCOMP << 8))) {
2003
if (!ptrace_intercept_execve(pid, closure)) {
2004
sudo_debug_printf(SUDO_DEBUG_ERROR,
2005
"%s: %d failed to intercept execve", __func__, (int)pid);
2006
}
2007
} else if (sigtrap == (SIGTRAP | (PTRACE_EVENT_EXEC << 8))) {
2008
sudo_debug_printf(SUDO_DEBUG_ERROR,
2009
"%s: %d PTRACE_EVENT_EXEC", __func__, (int)pid);
2010
} else if (sigtrap == (SIGTRAP | (PTRACE_EVENT_CLONE << 8)) ||
2011
sigtrap == (SIGTRAP | (PTRACE_EVENT_VFORK << 8)) ||
2012
sigtrap == (SIGTRAP | (PTRACE_EVENT_FORK << 8))) {
2013
unsigned long new_pid;
2014
2015
/* New child process, it will inherit the parent's trace flags. */
2016
if (sudo_debug_needed(SUDO_DEBUG_INFO)) {
2017
if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, &new_pid) != -1) {
2018
sudo_debug_printf(SUDO_DEBUG_INFO,
2019
"%s: %d forked new child %lu", __func__, (int)pid, new_pid);
2020
} else {
2021
sudo_debug_printf(
2022
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
2023
"ptrace(PTRACE_GETEVENTMSG, %d, NULL, %p)", (int)pid,
2024
&new_pid);
2025
}
2026
}
2027
} else {
2028
switch (stopsig) {
2029
case SIGSTOP:
2030
case SIGTSTP:
2031
case SIGTTIN:
2032
case SIGTTOU:
2033
/* Is this a group-stop? */
2034
if (status >> 16 == PTRACE_EVENT_STOP) {
2035
/* Group-stop, do not deliver signal. */
2036
sudo_debug_printf(SUDO_DEBUG_INFO,
2037
"%s: %d: group-stop signal %d",
2038
__func__, (int)pid, stopsig);
2039
group_stop = true;
2040
break;
2041
}
2042
FALLTHROUGH;
2043
default:
2044
/* Signal-delivery-stop, deliver signal. */
2045
sudo_debug_printf(SUDO_DEBUG_INFO,
2046
"%s: %d: signal-delivery-stop signal %d",
2047
__func__, (int)pid, stopsig);
2048
signo = stopsig;
2049
break;
2050
}
2051
}
2052
2053
if (group_stop) {
2054
/*
2055
* Restart child but prevent it from executing
2056
* until SIGCONT is received (simulate SIGSTOP, etc).
2057
*/
2058
if (ptrace(PTRACE_LISTEN, pid, NULL, 0L) == -1 && errno != ESRCH)
2059
sudo_warn("%s: ptrace(PTRACE_LISTEN, %d, NULL, 0L)",
2060
__func__, (int)pid);
2061
} else {
2062
/* Restart child immediately. */
2063
if (ptrace(PTRACE_CONT, pid, NULL, signo) == -1 && errno != ESRCH)
2064
sudo_warn("%s: ptrace(PTRACE_CONT, %d, NULL, %ld)",
2065
__func__, (int)pid, signo);
2066
}
2067
2068
debug_return_bool(group_stop);
2069
}
2070
2071
bool
2072
exec_ptrace_intercept_supported(void)
2073
{
2074
# ifdef __mips__
2075
/* MIPS doesn't support changing the syscall return value. */
2076
return false;
2077
# else
2078
if (seccomp_trap_supported == -1)
2079
seccomp_trap_supported = have_seccomp_action("trap");
2080
2081
return seccomp_trap_supported == true;
2082
# endif
2083
}
2084
2085
bool
2086
exec_ptrace_subcmds_supported(void)
2087
{
2088
if (seccomp_trap_supported == -1)
2089
seccomp_trap_supported = have_seccomp_action("trap");
2090
2091
return seccomp_trap_supported == true;
2092
}
2093
#else
2094
/* STUB */
2095
bool
2096
exec_ptrace_stopped(pid_t pid, int status, void *intercept)
2097
{
2098
return true;
2099
}
2100
2101
/* STUB */
2102
int
2103
exec_ptrace_seize(pid_t child)
2104
{
2105
return true;
2106
}
2107
2108
/* STUB */
2109
bool
2110
exec_ptrace_intercept_supported(void)
2111
{
2112
return false;
2113
}
2114
2115
/* STUB */
2116
bool
2117
exec_ptrace_subcmds_supported(void)
2118
{
2119
return false;
2120
}
2121
#endif /* HAVE_PTRACE_INTERCEPT */
2122
2123
/*
2124
* Adjust flags based on the availability of ptrace support.
2125
*/
2126
void
2127
exec_ptrace_fix_flags(struct command_details *details)
2128
{
2129
debug_decl(exec_ptrace_fix_flags, SUDO_DEBUG_EXEC);
2130
2131
if (ISSET(details->flags, CD_USE_PTRACE)) {
2132
/* If both CD_INTERCEPT and CD_LOG_SUBCMDS set, CD_INTERCEPT wins. */
2133
if (ISSET(details->flags, CD_INTERCEPT)) {
2134
if (!exec_ptrace_intercept_supported())
2135
CLR(details->flags, CD_USE_PTRACE);
2136
} else if (ISSET(details->flags, CD_LOG_SUBCMDS)) {
2137
if (!exec_ptrace_subcmds_supported())
2138
CLR(details->flags, CD_USE_PTRACE);
2139
} else {
2140
CLR(details->flags, CD_USE_PTRACE);
2141
}
2142
}
2143
debug_return;
2144
}
2145
2146