2020-12-03 23:46:26 +03:00
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2020 Facebook */
2021-10-02 04:17:57 +03:00
# include <linux/btf.h>
# include <linux/btf_ids.h>
2020-12-03 23:46:26 +03:00
# include <linux/error-injection.h>
# include <linux/init.h>
# include <linux/module.h>
2021-01-12 10:55:20 +03:00
# include <linux/percpu-defs.h>
2020-12-03 23:46:26 +03:00
# include <linux/sysfs.h>
# include <linux/tracepoint.h>
# include "bpf_testmod.h"
# define CREATE_TRACE_POINTS
# include "bpf_testmod-events.h"
2022-02-04 03:55:19 +03:00
typedef int ( * func_proto_typedef ) ( long ) ;
typedef int ( * func_proto_typedef_nested1 ) ( func_proto_typedef ) ;
typedef int ( * func_proto_typedef_nested2 ) ( func_proto_typedef_nested1 ) ;
2021-01-12 10:55:20 +03:00
DEFINE_PER_CPU ( int , bpf_testmod_ksym_percpu ) = 123 ;
2021-10-02 04:17:57 +03:00
noinline void
bpf_testmod_test_mod_kfunc ( int i )
{
* ( int * ) this_cpu_ptr ( & bpf_testmod_ksym_percpu ) = i ;
}
selftests/bpf: add a selftest with __user tag
Added a selftest with three__user usages: a __user pointer-type argument
in bpf_testmod, a __user pointer-type struct member in bpf_testmod,
and a __user pointer-type struct member in vmlinux. In all cases,
directly accessing the user memory will result verification failure.
$ ./test_progs -v -n 22/3
...
libbpf: prog 'test_user1': BPF program load failed: Permission denied
libbpf: prog 'test_user1': -- BEGIN PROG LOAD LOG --
R1 type=ctx expected=fp
0: R1=ctx(id=0,off=0,imm=0) R10=fp0
; int BPF_PROG(test_user1, struct bpf_testmod_btf_type_tag_1 *arg)
0: (79) r1 = *(u64 *)(r1 +0)
func 'bpf_testmod_test_btf_type_tag_user_1' arg0 has btf_id 136561 type STRUCT 'bpf_testmod_btf_type_tag_1'
1: R1_w=user_ptr_bpf_testmod_btf_type_tag_1(id=0,off=0,imm=0)
; g = arg->a;
1: (61) r1 = *(u32 *)(r1 +0)
R1 invalid mem access 'user_ptr_'
...
#22/3 btf_tag/btf_type_tag_user_mod1:OK
$ ./test_progs -v -n 22/4
...
libbpf: prog 'test_user2': BPF program load failed: Permission denied
libbpf: prog 'test_user2': -- BEGIN PROG LOAD LOG --
R1 type=ctx expected=fp
0: R1=ctx(id=0,off=0,imm=0) R10=fp0
; int BPF_PROG(test_user2, struct bpf_testmod_btf_type_tag_2 *arg)
0: (79) r1 = *(u64 *)(r1 +0)
func 'bpf_testmod_test_btf_type_tag_user_2' arg0 has btf_id 136563 type STRUCT 'bpf_testmod_btf_type_tag_2'
1: R1_w=ptr_bpf_testmod_btf_type_tag_2(id=0,off=0,imm=0)
; g = arg->p->a;
1: (79) r1 = *(u64 *)(r1 +0) ; R1_w=user_ptr_bpf_testmod_btf_type_tag_1(id=0,off=0,imm=0)
; g = arg->p->a;
2: (61) r1 = *(u32 *)(r1 +0)
R1 invalid mem access 'user_ptr_'
...
#22/4 btf_tag/btf_type_tag_user_mod2:OK
$ ./test_progs -v -n 22/5
...
libbpf: prog 'test_sys_getsockname': BPF program load failed: Permission denied
libbpf: prog 'test_sys_getsockname': -- BEGIN PROG LOAD LOG --
R1 type=ctx expected=fp
0: R1=ctx(id=0,off=0,imm=0) R10=fp0
; int BPF_PROG(test_sys_getsockname, int fd, struct sockaddr *usockaddr,
0: (79) r1 = *(u64 *)(r1 +8)
func '__sys_getsockname' arg1 has btf_id 2319 type STRUCT 'sockaddr'
1: R1_w=user_ptr_sockaddr(id=0,off=0,imm=0)
; g = usockaddr->sa_family;
1: (69) r1 = *(u16 *)(r1 +0)
R1 invalid mem access 'user_ptr_'
...
#22/5 btf_tag/btf_type_tag_user_vmlinux:OK
Signed-off-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/r/20220127154616.659314-1-yhs@fb.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2022-01-27 18:46:16 +03:00
struct bpf_testmod_btf_type_tag_1 {
int a ;
} ;
struct bpf_testmod_btf_type_tag_2 {
struct bpf_testmod_btf_type_tag_1 __user * p ;
} ;
2022-03-04 22:16:57 +03:00
struct bpf_testmod_btf_type_tag_3 {
struct bpf_testmod_btf_type_tag_1 __percpu * p ;
} ;
selftests/bpf: add a selftest with __user tag
Added a selftest with three__user usages: a __user pointer-type argument
in bpf_testmod, a __user pointer-type struct member in bpf_testmod,
and a __user pointer-type struct member in vmlinux. In all cases,
directly accessing the user memory will result verification failure.
$ ./test_progs -v -n 22/3
...
libbpf: prog 'test_user1': BPF program load failed: Permission denied
libbpf: prog 'test_user1': -- BEGIN PROG LOAD LOG --
R1 type=ctx expected=fp
0: R1=ctx(id=0,off=0,imm=0) R10=fp0
; int BPF_PROG(test_user1, struct bpf_testmod_btf_type_tag_1 *arg)
0: (79) r1 = *(u64 *)(r1 +0)
func 'bpf_testmod_test_btf_type_tag_user_1' arg0 has btf_id 136561 type STRUCT 'bpf_testmod_btf_type_tag_1'
1: R1_w=user_ptr_bpf_testmod_btf_type_tag_1(id=0,off=0,imm=0)
; g = arg->a;
1: (61) r1 = *(u32 *)(r1 +0)
R1 invalid mem access 'user_ptr_'
...
#22/3 btf_tag/btf_type_tag_user_mod1:OK
$ ./test_progs -v -n 22/4
...
libbpf: prog 'test_user2': BPF program load failed: Permission denied
libbpf: prog 'test_user2': -- BEGIN PROG LOAD LOG --
R1 type=ctx expected=fp
0: R1=ctx(id=0,off=0,imm=0) R10=fp0
; int BPF_PROG(test_user2, struct bpf_testmod_btf_type_tag_2 *arg)
0: (79) r1 = *(u64 *)(r1 +0)
func 'bpf_testmod_test_btf_type_tag_user_2' arg0 has btf_id 136563 type STRUCT 'bpf_testmod_btf_type_tag_2'
1: R1_w=ptr_bpf_testmod_btf_type_tag_2(id=0,off=0,imm=0)
; g = arg->p->a;
1: (79) r1 = *(u64 *)(r1 +0) ; R1_w=user_ptr_bpf_testmod_btf_type_tag_1(id=0,off=0,imm=0)
; g = arg->p->a;
2: (61) r1 = *(u32 *)(r1 +0)
R1 invalid mem access 'user_ptr_'
...
#22/4 btf_tag/btf_type_tag_user_mod2:OK
$ ./test_progs -v -n 22/5
...
libbpf: prog 'test_sys_getsockname': BPF program load failed: Permission denied
libbpf: prog 'test_sys_getsockname': -- BEGIN PROG LOAD LOG --
R1 type=ctx expected=fp
0: R1=ctx(id=0,off=0,imm=0) R10=fp0
; int BPF_PROG(test_sys_getsockname, int fd, struct sockaddr *usockaddr,
0: (79) r1 = *(u64 *)(r1 +8)
func '__sys_getsockname' arg1 has btf_id 2319 type STRUCT 'sockaddr'
1: R1_w=user_ptr_sockaddr(id=0,off=0,imm=0)
; g = usockaddr->sa_family;
1: (69) r1 = *(u16 *)(r1 +0)
R1 invalid mem access 'user_ptr_'
...
#22/5 btf_tag/btf_type_tag_user_vmlinux:OK
Signed-off-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/r/20220127154616.659314-1-yhs@fb.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2022-01-27 18:46:16 +03:00
noinline int
bpf_testmod_test_btf_type_tag_user_1 ( struct bpf_testmod_btf_type_tag_1 __user * arg ) {
2022-02-04 03:55:19 +03:00
BTF_TYPE_EMIT ( func_proto_typedef ) ;
BTF_TYPE_EMIT ( func_proto_typedef_nested1 ) ;
BTF_TYPE_EMIT ( func_proto_typedef_nested2 ) ;
selftests/bpf: add a selftest with __user tag
Added a selftest with three__user usages: a __user pointer-type argument
in bpf_testmod, a __user pointer-type struct member in bpf_testmod,
and a __user pointer-type struct member in vmlinux. In all cases,
directly accessing the user memory will result verification failure.
$ ./test_progs -v -n 22/3
...
libbpf: prog 'test_user1': BPF program load failed: Permission denied
libbpf: prog 'test_user1': -- BEGIN PROG LOAD LOG --
R1 type=ctx expected=fp
0: R1=ctx(id=0,off=0,imm=0) R10=fp0
; int BPF_PROG(test_user1, struct bpf_testmod_btf_type_tag_1 *arg)
0: (79) r1 = *(u64 *)(r1 +0)
func 'bpf_testmod_test_btf_type_tag_user_1' arg0 has btf_id 136561 type STRUCT 'bpf_testmod_btf_type_tag_1'
1: R1_w=user_ptr_bpf_testmod_btf_type_tag_1(id=0,off=0,imm=0)
; g = arg->a;
1: (61) r1 = *(u32 *)(r1 +0)
R1 invalid mem access 'user_ptr_'
...
#22/3 btf_tag/btf_type_tag_user_mod1:OK
$ ./test_progs -v -n 22/4
...
libbpf: prog 'test_user2': BPF program load failed: Permission denied
libbpf: prog 'test_user2': -- BEGIN PROG LOAD LOG --
R1 type=ctx expected=fp
0: R1=ctx(id=0,off=0,imm=0) R10=fp0
; int BPF_PROG(test_user2, struct bpf_testmod_btf_type_tag_2 *arg)
0: (79) r1 = *(u64 *)(r1 +0)
func 'bpf_testmod_test_btf_type_tag_user_2' arg0 has btf_id 136563 type STRUCT 'bpf_testmod_btf_type_tag_2'
1: R1_w=ptr_bpf_testmod_btf_type_tag_2(id=0,off=0,imm=0)
; g = arg->p->a;
1: (79) r1 = *(u64 *)(r1 +0) ; R1_w=user_ptr_bpf_testmod_btf_type_tag_1(id=0,off=0,imm=0)
; g = arg->p->a;
2: (61) r1 = *(u32 *)(r1 +0)
R1 invalid mem access 'user_ptr_'
...
#22/4 btf_tag/btf_type_tag_user_mod2:OK
$ ./test_progs -v -n 22/5
...
libbpf: prog 'test_sys_getsockname': BPF program load failed: Permission denied
libbpf: prog 'test_sys_getsockname': -- BEGIN PROG LOAD LOG --
R1 type=ctx expected=fp
0: R1=ctx(id=0,off=0,imm=0) R10=fp0
; int BPF_PROG(test_sys_getsockname, int fd, struct sockaddr *usockaddr,
0: (79) r1 = *(u64 *)(r1 +8)
func '__sys_getsockname' arg1 has btf_id 2319 type STRUCT 'sockaddr'
1: R1_w=user_ptr_sockaddr(id=0,off=0,imm=0)
; g = usockaddr->sa_family;
1: (69) r1 = *(u16 *)(r1 +0)
R1 invalid mem access 'user_ptr_'
...
#22/5 btf_tag/btf_type_tag_user_vmlinux:OK
Signed-off-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/r/20220127154616.659314-1-yhs@fb.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2022-01-27 18:46:16 +03:00
return arg - > a ;
}
noinline int
bpf_testmod_test_btf_type_tag_user_2 ( struct bpf_testmod_btf_type_tag_2 * arg ) {
return arg - > p - > a ;
}
2022-03-04 22:16:57 +03:00
noinline int
bpf_testmod_test_btf_type_tag_percpu_1 ( struct bpf_testmod_btf_type_tag_1 __percpu * arg ) {
return arg - > a ;
}
noinline int
bpf_testmod_test_btf_type_tag_percpu_2 ( struct bpf_testmod_btf_type_tag_3 * arg ) {
return arg - > p - > a ;
}
2021-09-10 21:33:52 +03:00
noinline int bpf_testmod_loop_test ( int n )
{
int i , sum = 0 ;
/* the primary goal of this test is to test LBR. Create a lot of
* branches in the function , so we can catch it easily .
*/
for ( i = 0 ; i < n ; i + + )
sum + = i ;
return sum ;
}
2021-12-15 23:35:34 +03:00
__weak noinline struct file * bpf_testmod_return_ptr ( int arg )
{
static struct file f = { } ;
switch ( arg ) {
case 1 : return ( void * ) EINVAL ; /* user addr */
case 2 : return ( void * ) 0xcafe4a11 ; /* user addr */
case 3 : return ( void * ) - EINVAL ; /* canonical, but invalid */
case 4 : return ( void * ) ( 1ull < < 60 ) ; /* non-canonical and invalid */
case 5 : return ( void * ) ~ ( 1ull < < 30 ) ; /* trigger extable */
case 6 : return & f ; /* valid addr */
case 7 : return ( void * ) ( ( long ) & f | 1 ) ; /* kernel tricks */
default : return NULL ;
}
}
2020-12-03 23:46:26 +03:00
noinline ssize_t
bpf_testmod_test_read ( struct file * file , struct kobject * kobj ,
struct bin_attribute * bin_attr ,
char * buf , loff_t off , size_t len )
{
struct bpf_testmod_test_read_ctx ctx = {
. buf = buf ,
. off = off ,
. len = len ,
} ;
2021-12-15 23:35:34 +03:00
int i = 1 ;
while ( bpf_testmod_return_ptr ( i ) )
i + + ;
2020-12-03 23:46:26 +03:00
2021-09-10 21:33:52 +03:00
/* This is always true. Use the check to make sure the compiler
* doesn ' t remove bpf_testmod_loop_test .
*/
if ( bpf_testmod_loop_test ( 101 ) > 100 )
trace_bpf_testmod_test_read ( current , & ctx ) ;
2020-12-03 23:46:26 +03:00
2021-10-04 12:48:57 +03:00
/* Magic number to enable writable tp */
if ( len = = 64 ) {
struct bpf_testmod_test_writable_ctx writable = {
. val = 1024 ,
} ;
trace_bpf_testmod_test_writable_bare ( & writable ) ;
if ( writable . early_ret )
return snprintf ( buf , len , " %d \n " , writable . val ) ;
}
2020-12-03 23:46:26 +03:00
return - EIO ; /* always fail */
}
EXPORT_SYMBOL ( bpf_testmod_test_read ) ;
ALLOW_ERROR_INJECTION ( bpf_testmod_test_read , ERRNO ) ;
2021-01-19 15:22:37 +03:00
noinline ssize_t
bpf_testmod_test_write ( struct file * file , struct kobject * kobj ,
struct bin_attribute * bin_attr ,
char * buf , loff_t off , size_t len )
{
struct bpf_testmod_test_write_ctx ctx = {
. buf = buf ,
. off = off ,
. len = len ,
} ;
trace_bpf_testmod_test_write_bare ( current , & ctx ) ;
return - EIO ; /* always fail */
}
EXPORT_SYMBOL ( bpf_testmod_test_write ) ;
ALLOW_ERROR_INJECTION ( bpf_testmod_test_write , ERRNO ) ;
2020-12-03 23:46:26 +03:00
static struct bin_attribute bin_attr_bpf_testmod_file __ro_after_init = {
2021-01-19 15:22:37 +03:00
. attr = { . name = " bpf_testmod " , . mode = 0666 , } ,
2020-12-03 23:46:26 +03:00
. read = bpf_testmod_test_read ,
2021-01-19 15:22:37 +03:00
. write = bpf_testmod_test_write ,
2020-12-03 23:46:26 +03:00
} ;
2022-01-14 19:39:46 +03:00
BTF_SET_START ( bpf_testmod_check_kfunc_ids )
2021-10-02 04:17:57 +03:00
BTF_ID ( func , bpf_testmod_test_mod_kfunc )
2022-01-14 19:39:46 +03:00
BTF_SET_END ( bpf_testmod_check_kfunc_ids )
2021-10-02 04:17:57 +03:00
2022-01-14 19:39:46 +03:00
static const struct btf_kfunc_id_set bpf_testmod_kfunc_set = {
. owner = THIS_MODULE ,
. check_set = & bpf_testmod_check_kfunc_ids ,
} ;
2021-10-02 04:17:57 +03:00
2022-01-14 19:39:53 +03:00
extern int bpf_fentry_test1 ( int a ) ;
2020-12-03 23:46:26 +03:00
static int bpf_testmod_init ( void )
{
2021-10-02 04:17:57 +03:00
int ret ;
2022-01-14 19:39:46 +03:00
ret = register_btf_kfunc_id_set ( BPF_PROG_TYPE_SCHED_CLS , & bpf_testmod_kfunc_set ) ;
if ( ret < 0 )
2021-10-02 04:17:57 +03:00
return ret ;
2022-01-14 19:39:53 +03:00
if ( bpf_fentry_test1 ( 0 ) < 0 )
return - EINVAL ;
2022-01-14 19:39:46 +03:00
return sysfs_create_bin_file ( kernel_kobj , & bin_attr_bpf_testmod_file ) ;
2020-12-03 23:46:26 +03:00
}
static void bpf_testmod_exit ( void )
{
return sysfs_remove_bin_file ( kernel_kobj , & bin_attr_bpf_testmod_file ) ;
}
module_init ( bpf_testmod_init ) ;
module_exit ( bpf_testmod_exit ) ;
MODULE_AUTHOR ( " Andrii Nakryiko " ) ;
MODULE_DESCRIPTION ( " BPF selftests module " ) ;
MODULE_LICENSE ( " Dual BSD/GPL " ) ;