1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) 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 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 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 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 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 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 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 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 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 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 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 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 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 401 int sys_capget(struct tcb *tcp) 402 { 403 return printargs(tcp); 404 } 405 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 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 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 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