101481e67SEduard Zingerman // SPDX-License-Identifier: GPL-2.0
201481e67SEduard Zingerman /* Converted from tools/testing/selftests/bpf/verifier/int_ptr.c */
301481e67SEduard Zingerman 
401481e67SEduard Zingerman #include <linux/bpf.h>
501481e67SEduard Zingerman #include <bpf/bpf_helpers.h>
601481e67SEduard Zingerman #include "bpf_misc.h"
701481e67SEduard Zingerman 
8*0954982dSAndrei Matei SEC("socket")
901481e67SEduard Zingerman __description("ARG_PTR_TO_LONG uninitialized")
10*0954982dSAndrei Matei __success
11*0954982dSAndrei Matei __failure_unpriv __msg_unpriv("invalid indirect read from stack R4 off -16+0 size 8")
arg_ptr_to_long_uninitialized(void)1201481e67SEduard Zingerman __naked void arg_ptr_to_long_uninitialized(void)
1301481e67SEduard Zingerman {
1401481e67SEduard Zingerman 	asm volatile ("					\
1501481e67SEduard Zingerman 	/* bpf_strtoul arg1 (buf) */			\
1601481e67SEduard Zingerman 	r7 = r10;					\
1701481e67SEduard Zingerman 	r7 += -8;					\
1801481e67SEduard Zingerman 	r0 = 0x00303036;				\
1901481e67SEduard Zingerman 	*(u64*)(r7 + 0) = r0;				\
2001481e67SEduard Zingerman 	r1 = r7;					\
2101481e67SEduard Zingerman 	/* bpf_strtoul arg2 (buf_len) */		\
2201481e67SEduard Zingerman 	r2 = 4;						\
2301481e67SEduard Zingerman 	/* bpf_strtoul arg3 (flags) */			\
2401481e67SEduard Zingerman 	r3 = 0;						\
2501481e67SEduard Zingerman 	/* bpf_strtoul arg4 (res) */			\
2601481e67SEduard Zingerman 	r7 += -8;					\
2701481e67SEduard Zingerman 	r4 = r7;					\
2801481e67SEduard Zingerman 	/* bpf_strtoul() */				\
2901481e67SEduard Zingerman 	call %[bpf_strtoul];				\
3001481e67SEduard Zingerman 	r0 = 1;						\
3101481e67SEduard Zingerman 	exit;						\
3201481e67SEduard Zingerman "	:
3301481e67SEduard Zingerman 	: __imm(bpf_strtoul)
3401481e67SEduard Zingerman 	: __clobber_all);
3501481e67SEduard Zingerman }
3601481e67SEduard Zingerman 
3701481e67SEduard Zingerman SEC("socket")
3801481e67SEduard Zingerman __description("ARG_PTR_TO_LONG half-uninitialized")
3901481e67SEduard Zingerman /* in privileged mode reads from uninitialized stack locations are permitted */
4001481e67SEduard Zingerman __success __failure_unpriv
4101481e67SEduard Zingerman __msg_unpriv("invalid indirect read from stack R4 off -16+4 size 8")
4201481e67SEduard Zingerman __retval(0)
ptr_to_long_half_uninitialized(void)4301481e67SEduard Zingerman __naked void ptr_to_long_half_uninitialized(void)
4401481e67SEduard Zingerman {
4501481e67SEduard Zingerman 	asm volatile ("					\
4601481e67SEduard Zingerman 	/* bpf_strtoul arg1 (buf) */			\
4701481e67SEduard Zingerman 	r7 = r10;					\
4801481e67SEduard Zingerman 	r7 += -8;					\
4901481e67SEduard Zingerman 	r0 = 0x00303036;				\
5001481e67SEduard Zingerman 	*(u64*)(r7 + 0) = r0;				\
5101481e67SEduard Zingerman 	r1 = r7;					\
5201481e67SEduard Zingerman 	/* bpf_strtoul arg2 (buf_len) */		\
5301481e67SEduard Zingerman 	r2 = 4;						\
5401481e67SEduard Zingerman 	/* bpf_strtoul arg3 (flags) */			\
5501481e67SEduard Zingerman 	r3 = 0;						\
5601481e67SEduard Zingerman 	/* bpf_strtoul arg4 (res) */			\
5701481e67SEduard Zingerman 	r7 += -8;					\
5801481e67SEduard Zingerman 	*(u32*)(r7 + 0) = r0;				\
5901481e67SEduard Zingerman 	r4 = r7;					\
6001481e67SEduard Zingerman 	/* bpf_strtoul() */				\
6101481e67SEduard Zingerman 	call %[bpf_strtoul];				\
6201481e67SEduard Zingerman 	r0 = 0;						\
6301481e67SEduard Zingerman 	exit;						\
6401481e67SEduard Zingerman "	:
6501481e67SEduard Zingerman 	: __imm(bpf_strtoul)
6601481e67SEduard Zingerman 	: __clobber_all);
6701481e67SEduard Zingerman }
6801481e67SEduard Zingerman 
6901481e67SEduard Zingerman SEC("cgroup/sysctl")
7001481e67SEduard Zingerman __description("ARG_PTR_TO_LONG misaligned")
7101481e67SEduard Zingerman __failure __msg("misaligned stack access off (0x0; 0x0)+-20+0 size 8")
arg_ptr_to_long_misaligned(void)7201481e67SEduard Zingerman __naked void arg_ptr_to_long_misaligned(void)
7301481e67SEduard Zingerman {
7401481e67SEduard Zingerman 	asm volatile ("					\
7501481e67SEduard Zingerman 	/* bpf_strtoul arg1 (buf) */			\
7601481e67SEduard Zingerman 	r7 = r10;					\
7701481e67SEduard Zingerman 	r7 += -8;					\
7801481e67SEduard Zingerman 	r0 = 0x00303036;				\
7901481e67SEduard Zingerman 	*(u64*)(r7 + 0) = r0;				\
8001481e67SEduard Zingerman 	r1 = r7;					\
8101481e67SEduard Zingerman 	/* bpf_strtoul arg2 (buf_len) */		\
8201481e67SEduard Zingerman 	r2 = 4;						\
8301481e67SEduard Zingerman 	/* bpf_strtoul arg3 (flags) */			\
8401481e67SEduard Zingerman 	r3 = 0;						\
8501481e67SEduard Zingerman 	/* bpf_strtoul arg4 (res) */			\
8601481e67SEduard Zingerman 	r7 += -12;					\
8701481e67SEduard Zingerman 	r0 = 0;						\
8801481e67SEduard Zingerman 	*(u32*)(r7 + 0) = r0;				\
8901481e67SEduard Zingerman 	*(u64*)(r7 + 4) = r0;				\
9001481e67SEduard Zingerman 	r4 = r7;					\
9101481e67SEduard Zingerman 	/* bpf_strtoul() */				\
9201481e67SEduard Zingerman 	call %[bpf_strtoul];				\
9301481e67SEduard Zingerman 	r0 = 1;						\
9401481e67SEduard Zingerman 	exit;						\
9501481e67SEduard Zingerman "	:
9601481e67SEduard Zingerman 	: __imm(bpf_strtoul)
9701481e67SEduard Zingerman 	: __clobber_all);
9801481e67SEduard Zingerman }
9901481e67SEduard Zingerman 
10001481e67SEduard Zingerman SEC("cgroup/sysctl")
10101481e67SEduard Zingerman __description("ARG_PTR_TO_LONG size < sizeof(long)")
10201481e67SEduard Zingerman __failure __msg("invalid indirect access to stack R4 off=-4 size=8")
to_long_size_sizeof_long(void)10301481e67SEduard Zingerman __naked void to_long_size_sizeof_long(void)
10401481e67SEduard Zingerman {
10501481e67SEduard Zingerman 	asm volatile ("					\
10601481e67SEduard Zingerman 	/* bpf_strtoul arg1 (buf) */			\
10701481e67SEduard Zingerman 	r7 = r10;					\
10801481e67SEduard Zingerman 	r7 += -16;					\
10901481e67SEduard Zingerman 	r0 = 0x00303036;				\
11001481e67SEduard Zingerman 	*(u64*)(r7 + 0) = r0;				\
11101481e67SEduard Zingerman 	r1 = r7;					\
11201481e67SEduard Zingerman 	/* bpf_strtoul arg2 (buf_len) */		\
11301481e67SEduard Zingerman 	r2 = 4;						\
11401481e67SEduard Zingerman 	/* bpf_strtoul arg3 (flags) */			\
11501481e67SEduard Zingerman 	r3 = 0;						\
11601481e67SEduard Zingerman 	/* bpf_strtoul arg4 (res) */			\
11701481e67SEduard Zingerman 	r7 += 12;					\
11801481e67SEduard Zingerman 	*(u32*)(r7 + 0) = r0;				\
11901481e67SEduard Zingerman 	r4 = r7;					\
12001481e67SEduard Zingerman 	/* bpf_strtoul() */				\
12101481e67SEduard Zingerman 	call %[bpf_strtoul];				\
12201481e67SEduard Zingerman 	r0 = 1;						\
12301481e67SEduard Zingerman 	exit;						\
12401481e67SEduard Zingerman "	:
12501481e67SEduard Zingerman 	: __imm(bpf_strtoul)
12601481e67SEduard Zingerman 	: __clobber_all);
12701481e67SEduard Zingerman }
12801481e67SEduard Zingerman 
12901481e67SEduard Zingerman SEC("cgroup/sysctl")
13001481e67SEduard Zingerman __description("ARG_PTR_TO_LONG initialized")
13101481e67SEduard Zingerman __success
arg_ptr_to_long_initialized(void)13201481e67SEduard Zingerman __naked void arg_ptr_to_long_initialized(void)
13301481e67SEduard Zingerman {
13401481e67SEduard Zingerman 	asm volatile ("					\
13501481e67SEduard Zingerman 	/* bpf_strtoul arg1 (buf) */			\
13601481e67SEduard Zingerman 	r7 = r10;					\
13701481e67SEduard Zingerman 	r7 += -8;					\
13801481e67SEduard Zingerman 	r0 = 0x00303036;				\
13901481e67SEduard Zingerman 	*(u64*)(r7 + 0) = r0;				\
14001481e67SEduard Zingerman 	r1 = r7;					\
14101481e67SEduard Zingerman 	/* bpf_strtoul arg2 (buf_len) */		\
14201481e67SEduard Zingerman 	r2 = 4;						\
14301481e67SEduard Zingerman 	/* bpf_strtoul arg3 (flags) */			\
14401481e67SEduard Zingerman 	r3 = 0;						\
14501481e67SEduard Zingerman 	/* bpf_strtoul arg4 (res) */			\
14601481e67SEduard Zingerman 	r7 += -8;					\
14701481e67SEduard Zingerman 	*(u64*)(r7 + 0) = r0;				\
14801481e67SEduard Zingerman 	r4 = r7;					\
14901481e67SEduard Zingerman 	/* bpf_strtoul() */				\
15001481e67SEduard Zingerman 	call %[bpf_strtoul];				\
15101481e67SEduard Zingerman 	r0 = 1;						\
15201481e67SEduard Zingerman 	exit;						\
15301481e67SEduard Zingerman "	:
15401481e67SEduard Zingerman 	: __imm(bpf_strtoul)
15501481e67SEduard Zingerman 	: __clobber_all);
15601481e67SEduard Zingerman }
15701481e67SEduard Zingerman 
15801481e67SEduard Zingerman char _license[] SEC("license") = "GPL";
159