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