1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */ 3 4 #include <vmlinux.h> 5 #include <string.h> 6 #include <stdbool.h> 7 #include <bpf/bpf_tracing.h> 8 #include "bpf_misc.h" 9 10 char _license[] SEC("license") = "GPL"; 11 12 int err; 13 void *user_ptr; 14 15 SEC("lsm/file_open") 16 __failure 17 __msg("Unreleased reference id=") 18 int on_nanosleep_unreleased_ref(void *ctx) 19 { 20 struct task_struct *task = bpf_get_current_task_btf(); 21 struct file *file = bpf_get_task_exe_file(task); 22 struct bpf_dynptr dynptr; 23 24 if (!file) 25 return 0; 26 27 err = bpf_dynptr_from_file(file, 0, &dynptr); 28 return err ? 1 : 0; 29 } 30 31 SEC("xdp") 32 __failure 33 __msg("Expected a dynptr of type file as R1") 34 int xdp_wrong_dynptr_type(struct xdp_md *xdp) 35 { 36 struct bpf_dynptr dynptr; 37 38 bpf_dynptr_from_xdp(xdp, 0, &dynptr); 39 bpf_dynptr_file_discard(&dynptr); 40 return 0; 41 } 42 43 SEC("xdp") 44 __failure 45 __msg("Expected an initialized dynptr as R1") 46 int xdp_no_dynptr_type(struct xdp_md *xdp) 47 { 48 struct bpf_dynptr dynptr; 49 50 bpf_dynptr_file_discard(&dynptr); 51 return 0; 52 } 53 54 SEC("lsm/file_open") 55 __failure 56 __msg("Leaking reference id={{[0-9]+}} alloc_insn={{[0-9]+}}. Release it first.") 57 int use_file_dynptr_after_put_file(void *ctx) 58 { 59 struct task_struct *task = bpf_get_current_task_btf(); 60 struct file *file = bpf_get_task_exe_file(task); 61 struct bpf_dynptr dynptr; 62 char buf[64]; 63 64 if (!file) 65 return 0; 66 67 if (bpf_dynptr_from_file(file, 0, &dynptr)) 68 goto out; 69 70 /* this should fail - file dynptr should be discarded first to prevent resource leak */ 71 bpf_put_file(file); 72 73 bpf_dynptr_read(buf, sizeof(buf), &dynptr, 0, 0); 74 return 0; 75 76 out: 77 bpf_dynptr_file_discard(&dynptr); 78 bpf_put_file(file); 79 return 0; 80 } 81 82 SEC("lsm/file_open") 83 __failure 84 __msg("Leaking reference id={{[0-9]+}} alloc_insn={{[0-9]+}}. Release it first.") 85 int use_file_dynptr_slice_after_put_file(void *ctx) 86 { 87 struct task_struct *task = bpf_get_current_task_btf(); 88 struct file *file = bpf_get_task_exe_file(task); 89 struct bpf_dynptr dynptr; 90 char *data; 91 92 if (!file) 93 return 0; 94 95 if (bpf_dynptr_from_file(file, 0, &dynptr)) 96 goto out; 97 98 data = bpf_dynptr_data(&dynptr, 0, 1); 99 if (!data) 100 goto out; 101 102 /* this should fail - file dynptr should be discarded first to prevent resource leak */ 103 bpf_put_file(file); 104 105 *data = 'x'; 106 return 0; 107 108 out: 109 bpf_dynptr_file_discard(&dynptr); 110 bpf_put_file(file); 111 return 0; 112 } 113