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, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "defs.h"
32
33 #define _LINUX_SOCKET_H
34 #define _LINUX_FS_H
35
36 #define MS_RDONLY 1 /* Mount read-only */
37 #define MS_NOSUID 2 /* Ignore suid and sgid bits */
38 #define MS_NODEV 4 /* Disallow access to device special files */
39 #define MS_NOEXEC 8 /* Disallow program execution */
40 #define MS_SYNCHRONOUS 16 /* Writes are synced at once */
41 #define MS_REMOUNT 32 /* Alter flags of a mounted FS */
42 #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
43 #define MS_DIRSYNC 128 /* Directory modifications are synchronous */
44 #define MS_NOATIME 1024 /* Do not update access times. */
45 #define MS_NODIRATIME 2048 /* Do not update directory access times */
46 #define MS_BIND 4096
47 #define MS_MOVE 8192
48 #define MS_REC 16384
49 #define MS_SILENT 32768
50 #define MS_POSIXACL (1<<16) /* VFS does not apply the umask */
51 #define MS_UNBINDABLE (1<<17) /* change to unbindable */
52 #define MS_PRIVATE (1<<18) /* change to private */
53 #define MS_SLAVE (1<<19) /* change to slave */
54 #define MS_SHARED (1<<20) /* change to shared */
55 #define MS_RELATIME (1<<21)
56 #define MS_KERNMOUNT (1<<22)
57 #define MS_I_VERSION (1<<23)
58 #define MS_STRICTATIME (1<<24)
59 #define MS_NOSEC (1<<28)
60 #define MS_BORN (1<<29)
61 #define MS_ACTIVE (1<<30)
62 #define MS_NOUSER (1<<31)
63 #define MS_MGC_VAL 0xc0ed0000 /* Magic flag number */
64 #define MS_MGC_MSK 0xffff0000 /* Magic flag mask */
65
66 #include <sys/socket.h>
67 #include <netinet/in.h>
68 #include <arpa/inet.h>
69 #ifdef HAVE_LINUX_CAPABILITY_H
70 # include <linux/capability.h>
71 #endif
72 #ifdef HAVE_ASM_CACHECTL_H
73 # include <asm/cachectl.h>
74 #endif
75 #ifdef HAVE_LINUX_USTNAME_H
76 # include <linux/utsname.h>
77 #endif
78 #ifdef HAVE_ASM_SYSMIPS_H
79 # include <asm/sysmips.h>
80 #endif
81 #include <linux/sysctl.h>
82 #include <linux/personality.h>
83
84 #include "xlat/mount_flags.h"
85
86 int
sys_mount(struct tcb * tcp)87 sys_mount(struct tcb *tcp)
88 {
89 if (entering(tcp)) {
90 int ignore_type = 0, ignore_data = 0;
91 unsigned long flags = tcp->u_arg[3];
92
93 /* Discard magic */
94 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
95 flags &= ~MS_MGC_MSK;
96
97 if (flags & MS_REMOUNT)
98 ignore_type = 1;
99 else if (flags & (MS_BIND | MS_MOVE))
100 ignore_type = ignore_data = 1;
101
102 printpath(tcp, tcp->u_arg[0]);
103 tprints(", ");
104
105 printpath(tcp, tcp->u_arg[1]);
106 tprints(", ");
107
108 if (ignore_type && tcp->u_arg[2])
109 tprintf("%#lx", tcp->u_arg[2]);
110 else
111 printstr(tcp, tcp->u_arg[2], -1);
112 tprints(", ");
113
114 printflags(mount_flags, tcp->u_arg[3], "MS_???");
115 tprints(", ");
116
117 if (ignore_data && tcp->u_arg[4])
118 tprintf("%#lx", tcp->u_arg[4]);
119 else
120 printstr(tcp, tcp->u_arg[4], -1);
121 }
122 return 0;
123 }
124
125 #define MNT_FORCE 0x00000001 /* Attempt to forcibily umount */
126 #define MNT_DETACH 0x00000002 /* Just detach from the tree */
127 #define MNT_EXPIRE 0x00000004 /* Mark for expiry */
128
129 #include "xlat/umount_flags.h"
130
131 int
sys_umount2(struct tcb * tcp)132 sys_umount2(struct tcb *tcp)
133 {
134 if (entering(tcp)) {
135 printstr(tcp, tcp->u_arg[0], -1);
136 tprints(", ");
137 printflags(umount_flags, tcp->u_arg[1], "MNT_???");
138 }
139 return 0;
140 }
141
142 /* These are not macros, but enums. We just copy the values by hand
143 from Linux 2.6.9 here. */
144 #include "xlat/personality_options.h"
145
146 int
sys_personality(struct tcb * tcp)147 sys_personality(struct tcb *tcp)
148 {
149 if (entering(tcp))
150 printxval(personality_options, tcp->u_arg[0], "PER_???");
151 return 0;
152 }
153
154 enum {
155 SYSLOG_ACTION_CLOSE = 0,
156 SYSLOG_ACTION_OPEN,
157 SYSLOG_ACTION_READ,
158 SYSLOG_ACTION_READ_ALL,
159 SYSLOG_ACTION_READ_CLEAR,
160 SYSLOG_ACTION_CLEAR,
161 SYSLOG_ACTION_CONSOLE_OFF,
162 SYSLOG_ACTION_CONSOLE_ON,
163 SYSLOG_ACTION_CONSOLE_LEVEL,
164 SYSLOG_ACTION_SIZE_UNREAD,
165 SYSLOG_ACTION_SIZE_BUFFER
166 };
167
168 #include "xlat/syslog_action_type.h"
169
170 int
sys_syslog(struct tcb * tcp)171 sys_syslog(struct tcb *tcp)
172 {
173 int type = tcp->u_arg[0];
174
175 if (entering(tcp)) {
176 /* type */
177 printxval(syslog_action_type, type, "SYSLOG_ACTION_???");
178 tprints(", ");
179 }
180
181 switch (type) {
182 case SYSLOG_ACTION_READ:
183 case SYSLOG_ACTION_READ_ALL:
184 case SYSLOG_ACTION_READ_CLEAR:
185 if (entering(tcp))
186 return 0;
187 break;
188 default:
189 if (entering(tcp)) {
190 tprintf("%#lx, %lu",
191 tcp->u_arg[1], tcp->u_arg[2]);
192 }
193 return 0;
194 }
195
196 /* bufp */
197 if (syserror(tcp))
198 tprintf("%#lx", tcp->u_arg[1]);
199 else
200 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
201 /* len */
202 tprintf(", %d", (int) tcp->u_arg[2]);
203
204 return 0;
205 }
206
207 #ifdef M68K
208 #include "xlat/cacheflush_scope.h"
209
210 static const struct xlat cacheflush_flags[] = {
211 #ifdef FLUSH_CACHE_BOTH
212 XLAT(FLUSH_CACHE_BOTH),
213 #endif
214 #ifdef FLUSH_CACHE_DATA
215 XLAT(FLUSH_CACHE_DATA),
216 #endif
217 #ifdef FLUSH_CACHE_INSN
218 XLAT(FLUSH_CACHE_INSN),
219 #endif
220 XLAT_END
221 };
222
223 int
sys_cacheflush(struct tcb * tcp)224 sys_cacheflush(struct tcb *tcp)
225 {
226 if (entering(tcp)) {
227 /* addr */
228 tprintf("%#lx, ", tcp->u_arg[0]);
229 /* scope */
230 printxval(cacheflush_scope, tcp->u_arg[1], "FLUSH_SCOPE_???");
231 tprints(", ");
232 /* flags */
233 printflags(cacheflush_flags, tcp->u_arg[2], "FLUSH_CACHE_???");
234 /* len */
235 tprintf(", %lu", tcp->u_arg[3]);
236 }
237 return 0;
238 }
239 #endif /* M68K */
240
241 #ifdef BFIN
242
243 #include <bfin_sram.h>
244
245 #include "xlat/sram_alloc_flags.h"
246
247 int
sys_sram_alloc(struct tcb * tcp)248 sys_sram_alloc(struct tcb *tcp)
249 {
250 if (entering(tcp)) {
251 /* size */
252 tprintf("%lu, ", tcp->u_arg[0]);
253 /* flags */
254 printflags(sram_alloc_flags, tcp->u_arg[1], "???_SRAM");
255 }
256 return 1;
257 }
258
259 #include <asm/cachectl.h>
260
261 static const struct xlat cacheflush_flags[] = {
262 XLAT(ICACHE),
263 XLAT(DCACHE),
264 XLAT(BCACHE),
265 XLAT_END
266 };
267
268 int
sys_cacheflush(struct tcb * tcp)269 sys_cacheflush(struct tcb *tcp)
270 {
271 if (entering(tcp)) {
272 /* start addr */
273 tprintf("%#lx, ", tcp->u_arg[0]);
274 /* length */
275 tprintf("%ld, ", tcp->u_arg[1]);
276 /* flags */
277 printxval(cacheflush_flags, tcp->u_arg[1], "?CACHE");
278 }
279 return 0;
280 }
281
282 #endif
283
284 #ifdef SH
285 static const struct xlat cacheflush_flags[] = {
286 #ifdef CACHEFLUSH_D_INVAL
287 XLAT(CACHEFLUSH_D_INVAL),
288 #endif
289 #ifdef CACHEFLUSH_D_WB
290 XLAT(CACHEFLUSH_D_WB),
291 #endif
292 #ifdef CACHEFLUSH_D_PURGE
293 XLAT(CACHEFLUSH_D_PURGE),
294 #endif
295 #ifdef CACHEFLUSH_I
296 XLAT(CACHEFLUSH_I),
297 #endif
298 XLAT_END
299 };
300
301 int
sys_cacheflush(struct tcb * tcp)302 sys_cacheflush(struct tcb *tcp)
303 {
304 if (entering(tcp)) {
305 /* addr */
306 tprintf("%#lx, ", tcp->u_arg[0]);
307 /* len */
308 tprintf("%lu, ", tcp->u_arg[1]);
309 /* flags */
310 printflags(cacheflush_flags, tcp->u_arg[2], "CACHEFLUSH_???");
311 }
312 return 0;
313 }
314 #endif /* SH */
315
316 #ifdef SYS_capget
317
318 #include "xlat/capabilities.h"
319
320 #ifndef _LINUX_CAPABILITY_VERSION_1
321 # define _LINUX_CAPABILITY_VERSION_1 0x19980330
322 #endif
323 #ifndef _LINUX_CAPABILITY_VERSION_2
324 # define _LINUX_CAPABILITY_VERSION_2 0x20071026
325 #endif
326 #ifndef _LINUX_CAPABILITY_VERSION_3
327 # define _LINUX_CAPABILITY_VERSION_3 0x20080522
328 #endif
329
330 #include "xlat/cap_version.h"
331
332 static void
print_cap_header(struct tcb * tcp,unsigned long addr)333 print_cap_header(struct tcb *tcp, unsigned long addr)
334 {
335 union { cap_user_header_t p; long *a; char *c; } arg;
336 long a[sizeof(*arg.p) / sizeof(long) + 1];
337 arg.a = a;
338
339 if (!addr)
340 tprints("NULL");
341 else if (!verbose(tcp) ||
342 umoven(tcp, addr, sizeof(*arg.p), arg.c) < 0)
343 tprintf("%#lx", addr);
344 else {
345 tprints("{");
346 printxval(cap_version, arg.p->version,
347 "_LINUX_CAPABILITY_VERSION_???");
348 tprintf(", %d}", arg.p->pid);
349 }
350 }
351
352 static void
print_cap_data(struct tcb * tcp,unsigned long addr)353 print_cap_data(struct tcb *tcp, unsigned long addr)
354 {
355 union { cap_user_data_t p; long *a; char *c; } arg;
356 long a[sizeof(*arg.p) / sizeof(long) + 1];
357 arg.a = a;
358
359 if (!addr)
360 tprints("NULL");
361 else if (!verbose(tcp) ||
362 (exiting(tcp) && syserror(tcp)) ||
363 umoven(tcp, addr, sizeof(*arg.p), arg.c) < 0)
364 tprintf("%#lx", addr);
365 else {
366 tprints("{");
367 printflags(capabilities, arg.p->effective, "CAP_???");
368 tprints(", ");
369 printflags(capabilities, arg.p->permitted, "CAP_???");
370 tprints(", ");
371 printflags(capabilities, arg.p->inheritable, "CAP_???");
372 tprints("}");
373 }
374 }
375
376 int
sys_capget(struct tcb * tcp)377 sys_capget(struct tcb *tcp)
378 {
379 if (entering(tcp)) {
380 print_cap_header(tcp, tcp->u_arg[0]);
381 tprints(", ");
382 } else {
383 print_cap_data(tcp, tcp->u_arg[1]);
384 }
385 return 0;
386 }
387
388 int
sys_capset(struct tcb * tcp)389 sys_capset(struct tcb *tcp)
390 {
391 if (entering(tcp)) {
392 print_cap_header(tcp, tcp->u_arg[0]);
393 tprints(", ");
394 print_cap_data(tcp, tcp->u_arg[1]);
395 }
396 return 0;
397 }
398
399 #else
400
sys_capget(struct tcb * tcp)401 int sys_capget(struct tcb *tcp)
402 {
403 return printargs(tcp);
404 }
405
sys_capset(struct tcb * tcp)406 int sys_capset(struct tcb *tcp)
407 {
408 return printargs(tcp);
409 }
410
411 #endif
412
413 #include "xlat/sysctl_root.h"
414 #include "xlat/sysctl_kern.h"
415 #include "xlat/sysctl_vm.h"
416 #include "xlat/sysctl_net.h"
417 #include "xlat/sysctl_net_core.h"
418 #include "xlat/sysctl_net_unix.h"
419 #include "xlat/sysctl_net_ipv4.h"
420 #include "xlat/sysctl_net_ipv4_route.h"
421 #include "xlat/sysctl_net_ipv4_conf.h"
422 #include "xlat/sysctl_net_ipv6.h"
423 #include "xlat/sysctl_net_ipv6_route.h"
424
425 int
sys_sysctl(struct tcb * tcp)426 sys_sysctl(struct tcb *tcp)
427 {
428 struct __sysctl_args info;
429 int *name;
430 unsigned long size;
431
432 if (umove(tcp, tcp->u_arg[0], &info) < 0)
433 return printargs(tcp);
434
435 size = sizeof(int) * (unsigned long) info.nlen;
436 name = (size / sizeof(int) != info.nlen) ? NULL : malloc(size);
437 if (name == NULL ||
438 umoven(tcp, (unsigned long) info.name, size, (char *) name) < 0) {
439 free(name);
440 if (entering(tcp))
441 tprintf("{%p, %d, %p, %p, %p, %lu}",
442 info.name, info.nlen, info.oldval,
443 info.oldlenp, info.newval, (unsigned long)info.newlen);
444 return 0;
445 }
446
447 if (entering(tcp)) {
448 int cnt = 0, max_cnt;
449
450 tprints("{{");
451
452 if (info.nlen == 0)
453 goto out;
454 printxval(sysctl_root, name[0], "CTL_???");
455 ++cnt;
456
457 if (info.nlen == 1)
458 goto out;
459 switch (name[0]) {
460 case CTL_KERN:
461 tprints(", ");
462 printxval(sysctl_kern, name[1], "KERN_???");
463 ++cnt;
464 break;
465 case CTL_VM:
466 tprints(", ");
467 printxval(sysctl_vm, name[1], "VM_???");
468 ++cnt;
469 break;
470 case CTL_NET:
471 tprints(", ");
472 printxval(sysctl_net, name[1], "NET_???");
473 ++cnt;
474
475 if (info.nlen == 2)
476 goto out;
477 switch (name[1]) {
478 case NET_CORE:
479 tprints(", ");
480 printxval(sysctl_net_core, name[2],
481 "NET_CORE_???");
482 break;
483 case NET_UNIX:
484 tprints(", ");
485 printxval(sysctl_net_unix, name[2],
486 "NET_UNIX_???");
487 break;
488 case NET_IPV4:
489 tprints(", ");
490 printxval(sysctl_net_ipv4, name[2],
491 "NET_IPV4_???");
492
493 if (info.nlen == 3)
494 goto out;
495 switch (name[2]) {
496 case NET_IPV4_ROUTE:
497 tprints(", ");
498 printxval(sysctl_net_ipv4_route,
499 name[3],
500 "NET_IPV4_ROUTE_???");
501 break;
502 case NET_IPV4_CONF:
503 tprints(", ");
504 printxval(sysctl_net_ipv4_conf,
505 name[3],
506 "NET_IPV4_CONF_???");
507 break;
508 default:
509 goto out;
510 }
511 break;
512 case NET_IPV6:
513 tprints(", ");
514 printxval(sysctl_net_ipv6, name[2],
515 "NET_IPV6_???");
516
517 if (info.nlen == 3)
518 goto out;
519 switch (name[2]) {
520 case NET_IPV6_ROUTE:
521 tprints(", ");
522 printxval(sysctl_net_ipv6_route,
523 name[3],
524 "NET_IPV6_ROUTE_???");
525 break;
526 default:
527 goto out;
528 }
529 break;
530 default:
531 goto out;
532 }
533 break;
534 default:
535 goto out;
536 }
537 out:
538 max_cnt = info.nlen;
539 if (abbrev(tcp) && max_cnt > max_strlen)
540 max_cnt = max_strlen;
541 while (cnt < max_cnt)
542 tprintf(", %x", name[cnt++]);
543 if (cnt < info.nlen)
544 tprints(", ...");
545 tprintf("}, %d, ", info.nlen);
546 } else {
547 size_t oldlen = 0;
548 if (info.oldval == NULL) {
549 tprints("NULL");
550 } else if (umove(tcp, (long)info.oldlenp, &oldlen) >= 0
551 && info.nlen >= 2
552 && ((name[0] == CTL_KERN
553 && (name[1] == KERN_OSRELEASE
554 || name[1] == KERN_OSTYPE
555 #ifdef KERN_JAVA_INTERPRETER
556 || name[1] == KERN_JAVA_INTERPRETER
557 #endif
558 #ifdef KERN_JAVA_APPLETVIEWER
559 || name[1] == KERN_JAVA_APPLETVIEWER
560 #endif
561 )))) {
562 printpath(tcp, (size_t)info.oldval);
563 } else {
564 tprintf("%p", info.oldval);
565 }
566 tprintf(", %lu, ", (unsigned long)oldlen);
567 if (info.newval == NULL)
568 tprints("NULL");
569 else if (syserror(tcp))
570 tprintf("%p", info.newval);
571 else
572 printpath(tcp, (size_t)info.newval);
573 tprintf(", %lu", (unsigned long)info.newlen);
574 }
575
576 free(name);
577 return 0;
578 }
579
580 #ifdef MIPS
581
582 #ifndef __NEW_UTS_LEN
583 #define __NEW_UTS_LEN 64
584 #endif
585
586 #include "xlat/sysmips_operations.h"
587
sys_sysmips(struct tcb * tcp)588 int sys_sysmips(struct tcb *tcp)
589 {
590 if (entering(tcp)) {
591 printxval(sysmips_operations, tcp->u_arg[0], "???");
592 if (!verbose(tcp)) {
593 tprintf("%ld, %ld, %ld", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
594 } else if (tcp->u_arg[0] == SETNAME) {
595 char nodename[__NEW_UTS_LEN + 1];
596 if (umovestr(tcp, tcp->u_arg[1], (__NEW_UTS_LEN + 1), nodename) < 0)
597 tprintf(", %#lx", tcp->u_arg[1]);
598 else
599 tprintf(", \"%.*s\"", (int)(__NEW_UTS_LEN + 1), nodename);
600 } else if (tcp->u_arg[0] == MIPS_ATOMIC_SET) {
601 tprintf(", %#lx, 0x%lx", tcp->u_arg[1], tcp->u_arg[2]);
602 } else if (tcp->u_arg[0] == MIPS_FIXADE) {
603 tprintf(", 0x%lx", tcp->u_arg[1]);
604 } else {
605 tprintf("%ld, %ld, %ld", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
606 }
607 }
608
609 return 0;
610 }
611
612 #endif /* MIPS */
613
614 #ifdef OR1K
615 #define OR1K_ATOMIC_SWAP 1
616 #define OR1K_ATOMIC_CMPXCHG 2
617 #define OR1K_ATOMIC_XCHG 3
618 #define OR1K_ATOMIC_ADD 4
619 #define OR1K_ATOMIC_DECPOS 5
620 #define OR1K_ATOMIC_AND 6
621 #define OR1K_ATOMIC_OR 7
622 #define OR1K_ATOMIC_UMAX 8
623 #define OR1K_ATOMIC_UMIN 9
624
625 #include "xlat/atomic_ops.h"
626
sys_or1k_atomic(struct tcb * tcp)627 int sys_or1k_atomic(struct tcb *tcp)
628 {
629 if (entering(tcp)) {
630 printxval(atomic_ops, tcp->u_arg[0], "???");
631 switch(tcp->u_arg[0]) {
632 case OR1K_ATOMIC_SWAP:
633 tprintf(", 0x%lx, 0x%lx", tcp->u_arg[1], tcp->u_arg[2]);
634 break;
635 case OR1K_ATOMIC_CMPXCHG:
636 tprintf(", 0x%lx, %#lx, %#lx", tcp->u_arg[1], tcp->u_arg[2],
637 tcp->u_arg[3]);
638 break;
639
640 case OR1K_ATOMIC_XCHG:
641 case OR1K_ATOMIC_ADD:
642 case OR1K_ATOMIC_AND:
643 case OR1K_ATOMIC_OR:
644 case OR1K_ATOMIC_UMAX:
645 case OR1K_ATOMIC_UMIN:
646 tprintf(", 0x%lx, %#lx", tcp->u_arg[1], tcp->u_arg[2]);
647 break;
648
649 case OR1K_ATOMIC_DECPOS:
650 tprintf(", 0x%lx", tcp->u_arg[1]);
651 break;
652
653 default:
654 break;
655 }
656 }
657
658 return RVAL_HEX;
659 }
660
661 #endif /* OR1K */
662