1*898cbca4SMartin KaFai Lau // SPDX-License-Identifier: GPL-2.0 2*898cbca4SMartin KaFai Lau /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3*898cbca4SMartin KaFai Lau 4*898cbca4SMartin KaFai Lau #include <vmlinux.h> 5*898cbca4SMartin KaFai Lau #include <bpf/bpf_helpers.h> 6*898cbca4SMartin KaFai Lau #include "bpf_experimental.h" 7*898cbca4SMartin KaFai Lau #include "bpf_misc.h" 8*898cbca4SMartin KaFai Lau #include "uptr_test_common.h" 9*898cbca4SMartin KaFai Lau 10*898cbca4SMartin KaFai Lau struct { 11*898cbca4SMartin KaFai Lau __uint(type, BPF_MAP_TYPE_TASK_STORAGE); 12*898cbca4SMartin KaFai Lau __uint(map_flags, BPF_F_NO_PREALLOC); 13*898cbca4SMartin KaFai Lau __type(key, int); 14*898cbca4SMartin KaFai Lau __type(value, struct value_type); 15*898cbca4SMartin KaFai Lau } datamap SEC(".maps"); 16*898cbca4SMartin KaFai Lau 17*898cbca4SMartin KaFai Lau SEC("?syscall") 18*898cbca4SMartin KaFai Lau __failure __msg("store to uptr disallowed") 19*898cbca4SMartin KaFai Lau int uptr_write(const void *ctx) 20*898cbca4SMartin KaFai Lau { 21*898cbca4SMartin KaFai Lau struct task_struct *task; 22*898cbca4SMartin KaFai Lau struct value_type *v; 23*898cbca4SMartin KaFai Lau 24*898cbca4SMartin KaFai Lau task = bpf_get_current_task_btf(); 25*898cbca4SMartin KaFai Lau v = bpf_task_storage_get(&datamap, task, 0, 26*898cbca4SMartin KaFai Lau BPF_LOCAL_STORAGE_GET_F_CREATE); 27*898cbca4SMartin KaFai Lau if (!v) 28*898cbca4SMartin KaFai Lau return 0; 29*898cbca4SMartin KaFai Lau 30*898cbca4SMartin KaFai Lau v->udata = NULL; 31*898cbca4SMartin KaFai Lau return 0; 32*898cbca4SMartin KaFai Lau } 33*898cbca4SMartin KaFai Lau 34*898cbca4SMartin KaFai Lau SEC("?syscall") 35*898cbca4SMartin KaFai Lau __failure __msg("store to uptr disallowed") 36*898cbca4SMartin KaFai Lau int uptr_write_nested(const void *ctx) 37*898cbca4SMartin KaFai Lau { 38*898cbca4SMartin KaFai Lau struct task_struct *task; 39*898cbca4SMartin KaFai Lau struct value_type *v; 40*898cbca4SMartin KaFai Lau 41*898cbca4SMartin KaFai Lau task = bpf_get_current_task_btf(); 42*898cbca4SMartin KaFai Lau v = bpf_task_storage_get(&datamap, task, 0, 43*898cbca4SMartin KaFai Lau BPF_LOCAL_STORAGE_GET_F_CREATE); 44*898cbca4SMartin KaFai Lau if (!v) 45*898cbca4SMartin KaFai Lau return 0; 46*898cbca4SMartin KaFai Lau 47*898cbca4SMartin KaFai Lau v->nested.udata = NULL; 48*898cbca4SMartin KaFai Lau return 0; 49*898cbca4SMartin KaFai Lau } 50*898cbca4SMartin KaFai Lau 51*898cbca4SMartin KaFai Lau SEC("?syscall") 52*898cbca4SMartin KaFai Lau __failure __msg("R1 invalid mem access 'mem_or_null'") 53*898cbca4SMartin KaFai Lau int uptr_no_null_check(const void *ctx) 54*898cbca4SMartin KaFai Lau { 55*898cbca4SMartin KaFai Lau struct task_struct *task; 56*898cbca4SMartin KaFai Lau struct value_type *v; 57*898cbca4SMartin KaFai Lau 58*898cbca4SMartin KaFai Lau task = bpf_get_current_task_btf(); 59*898cbca4SMartin KaFai Lau v = bpf_task_storage_get(&datamap, task, 0, 60*898cbca4SMartin KaFai Lau BPF_LOCAL_STORAGE_GET_F_CREATE); 61*898cbca4SMartin KaFai Lau if (!v) 62*898cbca4SMartin KaFai Lau return 0; 63*898cbca4SMartin KaFai Lau 64*898cbca4SMartin KaFai Lau v->udata->result = 0; 65*898cbca4SMartin KaFai Lau 66*898cbca4SMartin KaFai Lau return 0; 67*898cbca4SMartin KaFai Lau } 68*898cbca4SMartin KaFai Lau 69*898cbca4SMartin KaFai Lau SEC("?syscall") 70*898cbca4SMartin KaFai Lau __failure __msg("doesn't point to kptr") 71*898cbca4SMartin KaFai Lau int uptr_kptr_xchg(const void *ctx) 72*898cbca4SMartin KaFai Lau { 73*898cbca4SMartin KaFai Lau struct task_struct *task; 74*898cbca4SMartin KaFai Lau struct value_type *v; 75*898cbca4SMartin KaFai Lau 76*898cbca4SMartin KaFai Lau task = bpf_get_current_task_btf(); 77*898cbca4SMartin KaFai Lau v = bpf_task_storage_get(&datamap, task, 0, 78*898cbca4SMartin KaFai Lau BPF_LOCAL_STORAGE_GET_F_CREATE); 79*898cbca4SMartin KaFai Lau if (!v) 80*898cbca4SMartin KaFai Lau return 0; 81*898cbca4SMartin KaFai Lau 82*898cbca4SMartin KaFai Lau bpf_kptr_xchg(&v->udata, NULL); 83*898cbca4SMartin KaFai Lau 84*898cbca4SMartin KaFai Lau return 0; 85*898cbca4SMartin KaFai Lau } 86*898cbca4SMartin KaFai Lau 87*898cbca4SMartin KaFai Lau SEC("?syscall") 88*898cbca4SMartin KaFai Lau __failure __msg("invalid mem access 'scalar'") 89*898cbca4SMartin KaFai Lau int uptr_obj_new(const void *ctx) 90*898cbca4SMartin KaFai Lau { 91*898cbca4SMartin KaFai Lau struct value_type *v; 92*898cbca4SMartin KaFai Lau 93*898cbca4SMartin KaFai Lau v = bpf_obj_new(typeof(*v)); 94*898cbca4SMartin KaFai Lau if (!v) 95*898cbca4SMartin KaFai Lau return 0; 96*898cbca4SMartin KaFai Lau 97*898cbca4SMartin KaFai Lau if (v->udata) 98*898cbca4SMartin KaFai Lau v->udata->result = 0; 99*898cbca4SMartin KaFai Lau 100*898cbca4SMartin KaFai Lau bpf_obj_drop(v); 101*898cbca4SMartin KaFai Lau 102*898cbca4SMartin KaFai Lau return 0; 103*898cbca4SMartin KaFai Lau } 104*898cbca4SMartin KaFai Lau 105*898cbca4SMartin KaFai Lau char _license[] SEC("license") = "GPL"; 106