linux/tools/testing/selftests/bpf/progs/lsm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2
   3/*
   4 * Copyright 2020 Google LLC.
   5 */
   6
   7#include "vmlinux.h"
   8#include <bpf/bpf_helpers.h>
   9#include <bpf/bpf_tracing.h>
  10#include  <errno.h>
  11
  12struct {
  13        __uint(type, BPF_MAP_TYPE_ARRAY);
  14        __uint(max_entries, 1);
  15        __type(key, __u32);
  16        __type(value, __u64);
  17} array SEC(".maps");
  18
  19struct {
  20        __uint(type, BPF_MAP_TYPE_HASH);
  21        __uint(max_entries, 1);
  22        __type(key, __u32);
  23        __type(value, __u64);
  24} hash SEC(".maps");
  25
  26struct {
  27        __uint(type, BPF_MAP_TYPE_LRU_HASH);
  28        __uint(max_entries, 1);
  29        __type(key, __u32);
  30        __type(value, __u64);
  31} lru_hash SEC(".maps");
  32
  33struct {
  34        __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
  35        __uint(max_entries, 1);
  36        __type(key, __u32);
  37        __type(value, __u64);
  38} percpu_array SEC(".maps");
  39
  40struct {
  41        __uint(type, BPF_MAP_TYPE_PERCPU_HASH);
  42        __uint(max_entries, 1);
  43        __type(key, __u32);
  44        __type(value, __u64);
  45} percpu_hash SEC(".maps");
  46
  47struct {
  48        __uint(type, BPF_MAP_TYPE_LRU_PERCPU_HASH);
  49        __uint(max_entries, 1);
  50        __type(key, __u32);
  51        __type(value, __u64);
  52} lru_percpu_hash SEC(".maps");
  53
  54struct inner_map {
  55        __uint(type, BPF_MAP_TYPE_ARRAY);
  56        __uint(max_entries, 1);
  57        __type(key, int);
  58        __type(value, __u64);
  59} inner_map SEC(".maps");
  60
  61struct outer_arr {
  62        __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
  63        __uint(max_entries, 1);
  64        __uint(key_size, sizeof(int));
  65        __uint(value_size, sizeof(int));
  66        __array(values, struct inner_map);
  67} outer_arr SEC(".maps") = {
  68        .values = { [0] = &inner_map },
  69};
  70
  71struct outer_hash {
  72        __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
  73        __uint(max_entries, 1);
  74        __uint(key_size, sizeof(int));
  75        __array(values, struct inner_map);
  76} outer_hash SEC(".maps") = {
  77        .values = { [0] = &inner_map },
  78};
  79
  80char _license[] SEC("license") = "GPL";
  81
  82int monitored_pid = 0;
  83int mprotect_count = 0;
  84int bprm_count = 0;
  85
  86SEC("lsm/file_mprotect")
  87int BPF_PROG(test_int_hook, struct vm_area_struct *vma,
  88             unsigned long reqprot, unsigned long prot, int ret)
  89{
  90        if (ret != 0)
  91                return ret;
  92
  93        __u32 pid = bpf_get_current_pid_tgid() >> 32;
  94        int is_stack = 0;
  95
  96        is_stack = (vma->vm_start <= vma->vm_mm->start_stack &&
  97                    vma->vm_end >= vma->vm_mm->start_stack);
  98
  99        if (is_stack && monitored_pid == pid) {
 100                mprotect_count++;
 101                ret = -EPERM;
 102        }
 103
 104        return ret;
 105}
 106
 107SEC("lsm.s/bprm_committed_creds")
 108int BPF_PROG(test_void_hook, struct linux_binprm *bprm)
 109{
 110        __u32 pid = bpf_get_current_pid_tgid() >> 32;
 111        struct inner_map *inner_map;
 112        char args[64];
 113        __u32 key = 0;
 114        __u64 *value;
 115
 116        if (monitored_pid == pid)
 117                bprm_count++;
 118
 119        bpf_copy_from_user(args, sizeof(args), (void *)bprm->vma->vm_mm->arg_start);
 120        bpf_copy_from_user(args, sizeof(args), (void *)bprm->mm->arg_start);
 121
 122        value = bpf_map_lookup_elem(&array, &key);
 123        if (value)
 124                *value = 0;
 125        value = bpf_map_lookup_elem(&hash, &key);
 126        if (value)
 127                *value = 0;
 128        value = bpf_map_lookup_elem(&lru_hash, &key);
 129        if (value)
 130                *value = 0;
 131        value = bpf_map_lookup_elem(&percpu_array, &key);
 132        if (value)
 133                *value = 0;
 134        value = bpf_map_lookup_elem(&percpu_hash, &key);
 135        if (value)
 136                *value = 0;
 137        value = bpf_map_lookup_elem(&lru_percpu_hash, &key);
 138        if (value)
 139                *value = 0;
 140        inner_map = bpf_map_lookup_elem(&outer_arr, &key);
 141        if (inner_map) {
 142                value = bpf_map_lookup_elem(inner_map, &key);
 143                if (value)
 144                        *value = 0;
 145        }
 146        inner_map = bpf_map_lookup_elem(&outer_hash, &key);
 147        if (inner_map) {
 148                value = bpf_map_lookup_elem(inner_map, &key);
 149                if (value)
 150                        *value = 0;
 151        }
 152
 153        return 0;
 154}
 155SEC("lsm/task_free") /* lsm/ is ok, lsm.s/ fails */
 156int BPF_PROG(test_task_free, struct task_struct *task)
 157{
 158        return 0;
 159}
 160
 161int copy_test = 0;
 162
 163SEC("fentry.s/__x64_sys_setdomainname")
 164int BPF_PROG(test_sys_setdomainname, struct pt_regs *regs)
 165{
 166        void *ptr = (void *)PT_REGS_PARM1(regs);
 167        int len = PT_REGS_PARM2(regs);
 168        int buf = 0;
 169        long ret;
 170
 171        ret = bpf_copy_from_user(&buf, sizeof(buf), ptr);
 172        if (len == -2 && ret == 0 && buf == 1234)
 173                copy_test++;
 174        if (len == -3 && ret == -EFAULT)
 175                copy_test++;
 176        if (len == -4 && ret == -EFAULT)
 177                copy_test++;
 178        return 0;
 179}
 180