brintos

brintos / linux-shallow public Read only

0
0
Text · 4.2 KiB · d759853 Raw
193 lines · c
1// SPDX-License-Identifier: GPL-2.02 3#include "vmlinux.h"4#include "bpf_tracing_net.h"5#include <bpf/bpf_helpers.h>6#include <bpf/bpf_tracing.h>7 8char _license[] SEC("license") = "GPL";9 10extern bool CONFIG_SECURITY_SELINUX __kconfig __weak;11extern bool CONFIG_SECURITY_SMACK __kconfig __weak;12extern bool CONFIG_SECURITY_APPARMOR __kconfig __weak;13 14#ifndef AF_PACKET15#define AF_PACKET 1716#endif17 18#ifndef AF_UNIX19#define AF_UNIX 120#endif21 22#ifndef EPERM23#define EPERM 124#endif25 26struct {27	__uint(type, BPF_MAP_TYPE_CGROUP_STORAGE);28	__type(key, __u64);29	__type(value, __u64);30} cgroup_storage SEC(".maps");31 32int called_socket_post_create;33int called_socket_post_create2;34int called_socket_bind;35int called_socket_bind2;36int called_socket_alloc;37int called_socket_clone;38 39static __always_inline int test_local_storage(void)40{41	__u64 *val;42 43	val = bpf_get_local_storage(&cgroup_storage, 0);44	if (!val)45		return 0;46	*val += 1;47 48	return 1;49}50 51static __always_inline int real_create(struct socket *sock, int family,52				       int protocol)53{54	struct sock *sk;55	int prio = 123;56 57	/* Reject non-tx-only AF_PACKET. */58	if (family == AF_PACKET && protocol != 0)59		return 0; /* EPERM */60 61	sk = sock->sk;62	if (!sk)63		return 1;64 65	/* The rest of the sockets get default policy. */66	if (bpf_setsockopt(sk, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)))67		return 0; /* EPERM */68 69	/* Make sure bpf_getsockopt is allowed and works. */70	prio = 0;71	if (bpf_getsockopt(sk, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)))72		return 0; /* EPERM */73	if (prio != 123)74		return 0; /* EPERM */75 76	/* Can access cgroup local storage. */77	if (!test_local_storage())78		return 0; /* EPERM */79 80	return 1;81}82 83/* __cgroup_bpf_run_lsm_socket */84SEC("lsm_cgroup/socket_post_create")85int BPF_PROG(socket_post_create, struct socket *sock, int family,86	     int type, int protocol, int kern)87{88	called_socket_post_create++;89	return real_create(sock, family, protocol);90}91 92/* __cgroup_bpf_run_lsm_socket */93SEC("lsm_cgroup/socket_post_create")94int BPF_PROG(socket_post_create2, struct socket *sock, int family,95	     int type, int protocol, int kern)96{97	called_socket_post_create2++;98	return real_create(sock, family, protocol);99}100 101static __always_inline int real_bind(struct socket *sock,102				     struct sockaddr *address,103				     int addrlen)104{105	struct sockaddr_ll sa = {};106	struct sock *sk = sock->sk;107 108	if (!sk)109		return 1;110 111	if (sk->__sk_common.skc_family != AF_PACKET)112		return 1;113 114	if (sk->sk_kern_sock)115		return 1;116 117	bpf_probe_read_kernel(&sa, sizeof(sa), address);118	if (sa.sll_protocol)119		return 0; /* EPERM */120 121	/* Can access cgroup local storage. */122	if (!test_local_storage())123		return 0; /* EPERM */124 125	return 1;126}127 128/* __cgroup_bpf_run_lsm_socket */129SEC("lsm_cgroup/socket_bind")130int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address,131	     int addrlen)132{133	called_socket_bind++;134	return real_bind(sock, address, addrlen);135}136 137/* __cgroup_bpf_run_lsm_socket */138SEC("lsm_cgroup/socket_bind")139int BPF_PROG(socket_bind2, struct socket *sock, struct sockaddr *address,140	     int addrlen)141{142	called_socket_bind2++;143	return real_bind(sock, address, addrlen);144}145 146/* __cgroup_bpf_run_lsm_current (via bpf_lsm_current_hooks) */147SEC("lsm_cgroup/sk_alloc_security")148int BPF_PROG(socket_alloc, struct sock *sk, int family, gfp_t priority)149{150	called_socket_alloc++;151	/* if already have non-bpf lsms installed, EPERM will cause memory leak of non-bpf lsms */152	if (CONFIG_SECURITY_SELINUX || CONFIG_SECURITY_SMACK || CONFIG_SECURITY_APPARMOR)153		return 1;154 155	if (family == AF_UNIX)156		return 0; /* EPERM */157 158	/* Can access cgroup local storage. */159	if (!test_local_storage())160		return 0; /* EPERM */161 162	return 1;163}164 165/* __cgroup_bpf_run_lsm_sock */166SEC("lsm_cgroup/inet_csk_clone")167int BPF_PROG(socket_clone, struct sock *newsk, const struct request_sock *req)168{169	int prio = 234;170 171	if (!newsk)172		return 1;173 174	/* Accepted request sockets get a different priority. */175	if (bpf_setsockopt(newsk, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)))176		return 1;177 178	/* Make sure bpf_getsockopt is allowed and works. */179	prio = 0;180	if (bpf_getsockopt(newsk, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)))181		return 1;182	if (prio != 234)183		return 1;184 185	/* Can access cgroup local storage. */186	if (!test_local_storage())187		return 1;188 189	called_socket_clone++;190 191	return 1;192}193