Source file src/crypto/rand/internal/seccomp/seccomp_linux.go

     1  // Copyright 2024 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package seccomp
     6  
     7  /*
     8  #include <sys/prctl.h>
     9  #include <sys/syscall.h>
    10  #include <errno.h>
    11  #include <stddef.h>
    12  #include <unistd.h>
    13  #include <stdint.h>
    14  
    15  // A few definitions copied from linux/filter.h and linux/seccomp.h,
    16  // which might not be available on all systems.
    17  
    18  struct sock_filter {
    19      uint16_t code;
    20      uint8_t jt;
    21      uint8_t jf;
    22      uint32_t k;
    23  };
    24  
    25  struct sock_fprog {
    26      unsigned short len;
    27      struct sock_filter *filter;
    28  };
    29  
    30  #define BPF_LD	0x00
    31  #define BPF_W	0x00
    32  #define BPF_ABS	0x20
    33  #define BPF_JMP	0x05
    34  #define BPF_JEQ	0x10
    35  #define BPF_K	0x00
    36  #define BPF_RET	0x06
    37  
    38  #define BPF_STMT(code, k) { (unsigned short)(code), 0, 0, k }
    39  #define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k }
    40  
    41  struct seccomp_data {
    42  	int nr;
    43  	uint32_t arch;
    44  	uint64_t instruction_pointer;
    45  	uint64_t args[6];
    46  };
    47  
    48  #define SECCOMP_RET_ERRNO 0x00050000U
    49  #define SECCOMP_RET_ALLOW 0x7fff0000U
    50  #define SECCOMP_SET_MODE_FILTER 1
    51  
    52  int disable_getrandom() {
    53      if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
    54          return 1;
    55      }
    56      struct sock_filter filter[] = {
    57          BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
    58          BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SYS_getrandom, 0, 1),
    59          BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | ENOSYS),
    60          BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
    61      };
    62      struct sock_fprog prog = {
    63          .len = sizeof(filter) / sizeof((filter)[0]),
    64          .filter = filter,
    65      };
    66      if (syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog)) {
    67          return 2;
    68      }
    69      return 0;
    70  }
    71  */
    72  import "C"
    73  import "fmt"
    74  
    75  // DisableGetrandom makes future calls to getrandom(2) fail with ENOSYS. It
    76  // applies only to the current thread and to any programs executed from it.
    77  // Callers should use [runtime.LockOSThread] in a dedicated goroutine.
    78  func DisableGetrandom() error {
    79  	if errno := C.disable_getrandom(); errno != 0 {
    80  		return fmt.Errorf("failed to disable getrandom: %v", errno)
    81  	}
    82  	return nil
    83  }
    84  

View as plain text