Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

truss: decode compat32/compat64 arguments #692

Merged
merged 9 commits into from
Jun 25, 2021

Commits on Jun 22, 2021

  1. truss: split counting of syscalls and syscall calling convention

    This change is a refactoring cleanup to improve support for compat32
    syscalls (and compat64 on CHERI systems). Each process ABI now has it's
    own struct sycall instead of using one global list. The list of all
    syscalls is replaced with a list of seen syscalls. Looking up the syscall
    argument passing convention now interates over the fixed-size array instead
    of using a link-list that's populated on startup so we no longer need the
    init_syscall() function.
    The actual functional changes are in D27625.
    
    Reviewed By:	jhb
    Differential Revision: https://reviews.freebsd.org/D27636
    
    (cherry picked from commit 6019514)
    arichardson committed Jun 22, 2021
    Configuration menu
    Copy the full SHA
    f0a3e10 View commit details
    Browse the repository at this point in the history
  2. truss: improved support for decoding compat32 arguments

    Currently running `truss -a -e` does not decode any
    argument values for freebsd32_* syscalls (open/readlink/etc.)
    
    This change checks whether a syscall starts with freebsd{32,64}_ and if
    so strips that prefix when looking up the syscall information. To ensure
    that the truss logs include the real syscall name we create a copy of
    the syscall information struct with the updated.
    
    The other problem is that when reading string array values, truss
    naively iterates over an array of char* and fetches the pointer value.
    This will result in arguments not being loaded if the pointer is not
    aligned to sizeof(void*), which can happens in the compat32 case. If it
    happens to be aligned, we would end up printing every other value.
    To fix this problem, this changes adds a pointer_size member to the
    procabi struct and uses that to correctly read indirect arguments
    as 64/32 bit addresses in the the compat32 case (and also compat64 on
    CheriBSD).
    
    The motivating use-case for this change is using truss for 64-bit
    programs on a CHERI system, but most of the diff also applies to 32-bit
    compat on a 64-bit system, so I'm upstreaming this instead of keeping it
    as a local CheriBSD patch.
    
    Output of `truss -aef ldd32 /usr/bin/ldd32` before:
    39113: freebsd32_mmap(0x0,0x1000,0x3,0x1002,0xffffffff,0x0,0x0) = 543440896 (0x20644000)
    39113: freebsd32_ioctl(0x1,0x402c7413,0xffffd2a0) = 0 (0x0)
    /usr/bin/ldd32:
    39113: write(1,"/usr/bin/ldd32:\n",16)		 = 16 (0x10)
    39113: fork()					 = 39114 (0x98ca)
    39114: <new process>
    39114: freebsd32_execve(0xffffd97e,0xffffd680,0x20634000) EJUSTRETURN
    39114: freebsd32_mmap(0x0,0x20000,0x3,0x1002,0xffffffff,0x0,0x0) = 541237248 (0x2042a000)
    39114: freebsd32_mprotect(0x20427000,0x1000,0x1) = 0 (0x0)
    39114: issetugid()				 = 0 (0x0)
    39114: openat(AT_FDCWD,"/etc/libmap32.conf",O_RDONLY|O_CLOEXEC,00) ERR#2 'No such file or directory'
    39114: openat(AT_FDCWD,"/var/run/ld-elf32.so.hints",O_RDONLY|O_CLOEXEC,00) = 3 (0x3)
    39114: read(3,"Ehnt\^A\0\0\0\M^@\0\0\0#\0\0\0\0"...,128) = 128 (0x80)
    39114: freebsd32_fstat(0x3,0xffffbd98)		 = 0 (0x0)
    39114: freebsd32_pread(0x3,0x2042f000,0x23,0x80,0x0) = 35 (0x23)
    39114: close(3)					 = 0 (0x0)
    39114: openat(AT_FDCWD,"/usr/lib32/libc.so.7",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3)
    39114: freebsd32_fstat(0x3,0xffffc7d0)		 = 0 (0x0)
    39114: freebsd32_mmap(0x0,0x1000,0x1,0x40002,0x3,0x0,0x0) = 541368320 (0x2044a000)
    
    After:
      783: freebsd32_mmap(0x0,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON|MAP_ALIGNED(12),-1,0x0) = 543543296 (0x2065d000)
      783: freebsd32_ioctl(1,TIOCGETA,0xffffd7b0)    = 0 (0x0)
    /usr/bin/ldd32:
      783: write(1,"/usr/bin/ldd32:\n",16)           = 16 (0x10)
      784: <new process>
      783: fork()                                    = 784 (0x310)
      784: freebsd32_execve("/usr/bin/ldd32",[ "(null)" ],[ "LD_32_TRACE_LOADED_OBJECTS_PROGNAME=/usr/bin/ldd32", "LD_TRACE_LOADED_OBJECTS_PROGNAME=/usr/bin/ldd32", "LD_32_TRACE_LOADED_OBJECTS=yes", "LD_TRACE_LOADED_OBJECTS=yes", "USER=root", "LOGNAME=root", "HOME=/root", "SHELL=/bin/csh", "BLOCKSIZE=K", "MAIL=/var/mail/root", "MM_CHARSET=UTF-8", "LANG=C.UTF-8", "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin", "TERM=vt100", "HOSTTYPE=FreeBSD", "VENDOR=amd", "OSTYPE=FreeBSD", "MACHTYPE=x86_64", "SHLVL=1", "PWD=/root", "GROUP=wheel", "HOST=freebsd-amd64", "EDITOR=vi", "PAGER=less" ]) EJUSTRETURN
      784: freebsd32_mmap(0x0,135168,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 541212672 (0x20424000)
      784: freebsd32_mprotect(0x20421000,4096,PROT_READ) = 0 (0x0)
      784: issetugid()                               = 0 (0x0)
      784: sigfastblock(0x1,0x204234fc)              = 0 (0x0)
      784: open("/etc/libmap32.conf",O_RDONLY|O_CLOEXEC,00) ERR#2 'No such file or directory'
      784: open("/var/run/ld-elf32.so.hints",O_RDONLY|O_CLOEXEC,00) = 3 (0x3)
      784: read(3,"Ehnt\^A\0\0\0\M^@\0\0\0\v\0\0\0"...,128) = 128 (0x80)
      784: freebsd32_fstat(3,{ mode=-r--r--r-- ,inode=18680,size=32768,blksize=0 }) = 0 (0x0)
      784: freebsd32_pread(3,"/usr/lib32\0",11,0x80) = 11 (0xb)
    
    Reviewed By:	jhb
    Differential Revision: https://reviews.freebsd.org/D27625
    
    (cherry picked from commit 7daca4e)
    arichardson committed Jun 22, 2021
    Configuration menu
    Copy the full SHA
    cf67357 View commit details
    Browse the repository at this point in the history
  3. truss: Add missing underscore to compat_prefix for FreeBSD32

    I accidentally dropped this in the final version of D27625, so it didn't
    actually work as intended. I found this while testing the MFC to stable/13.
    
    MFC after:	immediately
    Fixes:		7daca4e ("truss: improved support for decoding compat32 arguments")
    
    (cherry picked from commit 3cbad82)
    arichardson committed Jun 22, 2021
    Configuration menu
    Copy the full SHA
    eb33bb4 View commit details
    Browse the repository at this point in the history
  4. Expose clang's alignment builtins and use them for roundup2/rounddown2

    This makes roundup2/rounddown2 type- and const-preserving and allows
    using it on pointer types without casting to uintptr_t first. Not
    performing pointer-to-integer conversions also helps the compiler's
    optimization passes and can therefore result in better code generation.
    When using it with integer values there should be no change other than
    the compiler checking that the alignment value is a valid power-of-two.
    
    I originally implemented these builtins for CHERI a few years ago and
    they have been very useful for CheriBSD. However, they are also useful
    for non-CHERI code so I was able to upstream them for Clang 10.0.
    
    Rationale from the clang documentation:
    Clang provides builtins to support checking and adjusting alignment
    of pointers and integers. These builtins can be used to avoid relying
    on implementation-defined behavior of arithmetic on integers derived
    from pointers. Additionally, these builtins retain type information
    and, unlike bitwise arithmetic, they can perform semantic checking on
    the alignment value.
    
    There is also a feature request for GCC, so GCC may also support it in
    the future: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98641
    
    Reviewed By:	brooks, jhb, imp
    Differential Revision: https://reviews.freebsd.org/D28332
    
    (cherry picked from commit 8fa6abb)
    arichardson committed Jun 22, 2021
    Configuration menu
    Copy the full SHA
    e004712 View commit details
    Browse the repository at this point in the history
  5. truss: fix handling of 64-bit arguments/return values for compat32

    Deciding whether to combine two values to a 64-bit one should be based on
    the process ABI, and not dependent on whether truss is compiled for an
    LP64 ABI. This is a follow-up cleanup for D27625. I found this while
    looking for uses of the `__LP64__` macro (since using this is wrong for
    CHERI systems).
    
    Test Plan: truss still works. Since I tested on AMD64 and all syscalls
    in the trace have their quad argument last there was no difference
    in the output. Should fix output for compat32 on MIPS64 though.
    
    Reviewed By:	jhb
    MFC after:	3 days
    Differential Revision: https://reviews.freebsd.org/D27637
    
    (cherry picked from commit 8ba2e89)
    arichardson committed Jun 22, 2021
    Configuration menu
    Copy the full SHA
    454e081 View commit details
    Browse the repository at this point in the history
  6. truss: minor cleanup and pedantic warning fixes

    Noticed while porting the recent truss compat32 changes to CheriBSD.
    This also fixes i386 tracing by zero-extending user addresses instead
    of sign-extending them.
    
    Reviewed By:	jhb
    MFC after:	3 days
    Differential Revision: https://reviews.freebsd.org/D30211
    
    (cherry picked from commit 31dddc6)
    arichardson committed Jun 22, 2021
    Configuration menu
    Copy the full SHA
    409d1d6 View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    ea7b81c View commit details
    Browse the repository at this point in the history
  8. truss: Use ptraddr_t for Linux pointer_size

    This should allow tracing Linux processes using a purecap truss.
    arichardson committed Jun 22, 2021
    Configuration menu
    Copy the full SHA
    153ed62 View commit details
    Browse the repository at this point in the history
  9. truss: Fix tracing purecap programs with a hybrid truss

    Setting pointer_size to `void * __capability` and updating the list of
    procabis to use __has_feature(capabilities) instead of checking for
    __CHERI_PURE_CAPABILITY__ is sufficient to make this work after the
    latest changes.
    While touching those lines, also GC support for the old non-native
    CheriABI syscall ABI.
    arichardson committed Jun 22, 2021
    Configuration menu
    Copy the full SHA
    e365c62 View commit details
    Browse the repository at this point in the history