Skip to content

Commit f8cb518

Browse files
ameryhungKernel Patches Daemon
authored andcommitted
selftests/bpf: Test using file dynptr after the reference on file is dropped
File dynptr and slice should be invalidated when the parent file's reference is dropped in the program. Without the verifier tracking dyntpr's parent referenced object, the dynptr would continute to be incorrectly used even if the underlying file is being tear down or gone. Signed-off-by: Amery Hung <ameryhung@gmail.com>
1 parent 0164db0 commit f8cb518

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

tools/testing/selftests/bpf/progs/file_reader_fail.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,63 @@ int xdp_no_dynptr_type(struct xdp_md *xdp)
5050
bpf_dynptr_file_discard(&dynptr);
5151
return 0;
5252
}
53+
54+
SEC("lsm/file_open")
55+
__failure
56+
__msg("Expected an initialized dynptr as arg #2")
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+
bpf_put_file(file);
71+
72+
/* this should fail - dynptr is invalid after file ref is dropped */
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("invalid mem access 'scalar'")
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+
bpf_put_file(file);
103+
104+
/* this should fail - data slice is invalid after file ref is dropped */
105+
*data = 'x';
106+
return 0;
107+
108+
out:
109+
bpf_dynptr_file_discard(&dynptr);
110+
bpf_put_file(file);
111+
return 0;
112+
}

0 commit comments

Comments
 (0)