Add NetBSD syscall hooks in sanitizers
Changes PlannedPublic

Authored by krytarowski on Tue, Dec 26, 3:21 PM.

Details

Summary

Implement the initial set of NetBSD syscall hooks for use with sanitizers.

Add a script that generates the rules to handle syscalls
on NetBSD: generate_netbsd_syscalls.awk. It has been written
in NetBSD awk(1) (patched nawk) and is compatible with gawk.

Generate lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
that is a public header for applications, and included as:
<sanitizer_common/sanitizer_platform_limits_netbsd.h>.

Generate sanitizer_netbsd_syscalls.inc that defines all the
syscall rules for NetBSD. This file is modeled after the Linux
specific file: sanitizer_common_syscalls.inc.

Start recognizing NetBSD syscalls with existing sanitizers:
ASan, ESan, HWASan, TSan, MSan, TSan.

Update the list of platform (NetBSD OS) specific structs
in lib/sanitizer_common/sanitizer_platform_limits_netbsd.

This patch does contain the most wanted structs
and handles the most wanted syscalls as of now, the rest
of them will be implemented in future when needed.

This patch is 815KB, therefore I will restrict the detailed
description to a demo:

$ uname -a
NetBSD chieftec 8.99.9 NetBSD 8.99.9 (GENERIC) #0: Mon Dec 25 12:58:16 CET 2017  root@chieftec:/public/netbsd-root/sys/arch/amd64/compile/GENERIC amd64
$ cat s.cc                                                                                                                   
#include <assert.h>
#include <errno.h>
#include <glob.h>
#include <stdio.h>
#include <string.h>

#include <sanitizer/netbsd_syscall_hooks.h>

int main(int argc, char *argv[]) {
  char buf[1000];
  __sanitizer_syscall_pre_recvmsg(0, buf - 1, 0);
  // CHECK: AddressSanitizer: stack-buffer-{{.*}}erflow
  // CHECK: READ of size {{.*}} at {{.*}} thread T0
  // CHECK: #0 {{.*}} in __sanitizer_syscall{{.*}}recvmsg
  return 0;
}
$ ./a.out   
=================================================================
==18015==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7f7fffe9c2ff at pc 0x000000467798 bp 0x7f7fffe9c2d0 sp 0x7f7fffe9ba90
WRITE of size 48 at 0x7f7fffe9c2ff thread T16777215
    #0 0x467797 in __sanitizer_syscall_pre_impl_recvmsg /public/llvm/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_netbsd_syscalls.inc:394:3
    #1 0x4abeb2 in main (/public/llvm-build/./a.out+0x4abeb2)
    #2 0x419bba in ___start (/public/llvm-build/./a.out+0x419bba)

Address 0x7f7fffe9c2ff is located in stack of thread T0 at offset 31 in frame
    #0 0x4abd7f in main (/public/llvm-build/./a.out+0x4abd7f)

  This frame has 1 object(s):
    [32, 1032) 'buf' <== Memory access at offset 31 partially underflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMAR.Y: AddressSanitizer: stack-buffer-underflow /public/llvm/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_netbsd_syscalls.inc:394:3 in __sanitizer_syscall_pre_impl_recvmsg
Shadow bytes around the buggy address:
  0x4feffffd3800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4feffffd3810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4feffffd3820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4feffffd3830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4feffffd3840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x4feffffd3850: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1[f1]
  0x4feffffd3860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4feffffd3870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4feffffd3880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4feffffd3890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x4feffffd38a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==18015==ABORTING

Sponsored by <The NetBSD Foundation>

Diff Detail

Repository
rL LLVM
krytarowski created this revision.Tue, Dec 26, 3:21 PM
krytarowski edited the summary of this revision. (Show Details)Tue, Dec 26, 3:25 PM
krytarowski edited the summary of this revision. (Show Details)

ping? I've got almost ready a patch for all the NetBSD ioctls.

New Yearly ping.. I've now ~1MB of pending patches for compiler-rt/NetBSD.

I'm working now on the support of the remaining functions from the basesystem libraries (libc, libutil, libkvm, librt, libm, libpthread...) and that code is partially shared with the pending patches.

I can try to split this patch into smaller chunks, like the first patch adding the awk(1) script generating empty (without syscalls) files, etc?

Does it help to get this merged?

krytarowski planned changes to this revision.Sun, Jan 14, 11:22 PM

I've spitted this patch into smaller chunks.