Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: Implement cgroup sockaddr hooks for unix sockets

These hooks allows intercepting connect(), getsockname(),
getpeername(), sendmsg() and recvmsg() for unix sockets. The unix
socket hooks get write access to the address length because the
address length is not fixed when dealing with unix sockets and
needs to be modified when a unix socket address is modified by
the hook. Because abstract socket unix addresses start with a
NUL byte, we cannot recalculate the socket address in kernelspace
after running the hook by calculating the length of the unix socket
path using strlen().

These hooks can be used when users want to multiplex syscall to a
single unix socket to multiple different processes behind the scenes
by redirecting the connect() and other syscalls to process specific
sockets.

We do not implement support for intercepting bind() because when
using bind() with unix sockets with a pathname address, this creates
an inode in the filesystem which must be cleaned up. If we rewrite
the address, the user might try to clean up the wrong file, leaking
the socket in the filesystem where it is never cleaned up. Until we
figure out a solution for this (and a use case for intercepting bind()),
we opt to not allow rewriting the sockaddr in bind() calls.

We also implement recvmsg() support for connected streams so that
after a connect() that is modified by a sockaddr hook, any corresponding
recmvsg() on the connected socket can also be modified to make the
connected program think it is connected to the "intended" remote.

Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: Daan De Meyer <daan.j.demeyer@gmail.com>
Link: https://lore.kernel.org/r/20231011185113.140426-5-daan.j.demeyer@gmail.com
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>

authored by

Daan De Meyer and committed by
Martin KaFai Lau
859051dd 53e380d2

+114 -14
+5
include/linux/bpf-cgroup-defs.h
··· 28 28 CGROUP_INET6_BIND, 29 29 CGROUP_INET4_CONNECT, 30 30 CGROUP_INET6_CONNECT, 31 + CGROUP_UNIX_CONNECT, 31 32 CGROUP_INET4_POST_BIND, 32 33 CGROUP_INET6_POST_BIND, 33 34 CGROUP_UDP4_SENDMSG, 34 35 CGROUP_UDP6_SENDMSG, 36 + CGROUP_UNIX_SENDMSG, 35 37 CGROUP_SYSCTL, 36 38 CGROUP_UDP4_RECVMSG, 37 39 CGROUP_UDP6_RECVMSG, 40 + CGROUP_UNIX_RECVMSG, 38 41 CGROUP_GETSOCKOPT, 39 42 CGROUP_SETSOCKOPT, 40 43 CGROUP_INET4_GETPEERNAME, 41 44 CGROUP_INET6_GETPEERNAME, 45 + CGROUP_UNIX_GETPEERNAME, 42 46 CGROUP_INET4_GETSOCKNAME, 43 47 CGROUP_INET6_GETSOCKNAME, 48 + CGROUP_UNIX_GETSOCKNAME, 44 49 CGROUP_INET_SOCK_RELEASE, 45 50 CGROUP_LSM_START, 46 51 CGROUP_LSM_END = CGROUP_LSM_START + CGROUP_LSM_NUM - 1,
+17
include/linux/bpf-cgroup.h
··· 48 48 CGROUP_ATYPE(CGROUP_INET6_BIND); 49 49 CGROUP_ATYPE(CGROUP_INET4_CONNECT); 50 50 CGROUP_ATYPE(CGROUP_INET6_CONNECT); 51 + CGROUP_ATYPE(CGROUP_UNIX_CONNECT); 51 52 CGROUP_ATYPE(CGROUP_INET4_POST_BIND); 52 53 CGROUP_ATYPE(CGROUP_INET6_POST_BIND); 53 54 CGROUP_ATYPE(CGROUP_UDP4_SENDMSG); 54 55 CGROUP_ATYPE(CGROUP_UDP6_SENDMSG); 56 + CGROUP_ATYPE(CGROUP_UNIX_SENDMSG); 55 57 CGROUP_ATYPE(CGROUP_SYSCTL); 56 58 CGROUP_ATYPE(CGROUP_UDP4_RECVMSG); 57 59 CGROUP_ATYPE(CGROUP_UDP6_RECVMSG); 60 + CGROUP_ATYPE(CGROUP_UNIX_RECVMSG); 58 61 CGROUP_ATYPE(CGROUP_GETSOCKOPT); 59 62 CGROUP_ATYPE(CGROUP_SETSOCKOPT); 60 63 CGROUP_ATYPE(CGROUP_INET4_GETPEERNAME); 61 64 CGROUP_ATYPE(CGROUP_INET6_GETPEERNAME); 65 + CGROUP_ATYPE(CGROUP_UNIX_GETPEERNAME); 62 66 CGROUP_ATYPE(CGROUP_INET4_GETSOCKNAME); 63 67 CGROUP_ATYPE(CGROUP_INET6_GETSOCKNAME); 68 + CGROUP_ATYPE(CGROUP_UNIX_GETSOCKNAME); 64 69 CGROUP_ATYPE(CGROUP_INET_SOCK_RELEASE); 65 70 default: 66 71 return CGROUP_BPF_ATTACH_TYPE_INVALID; ··· 294 289 #define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr, uaddrlen) \ 295 290 BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_INET6_CONNECT, NULL) 296 291 292 + #define BPF_CGROUP_RUN_PROG_UNIX_CONNECT_LOCK(sk, uaddr, uaddrlen) \ 293 + BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UNIX_CONNECT, NULL) 294 + 297 295 #define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) \ 298 296 BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UDP4_SENDMSG, t_ctx) 299 297 300 298 #define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) \ 301 299 BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UDP6_SENDMSG, t_ctx) 302 300 301 + #define BPF_CGROUP_RUN_PROG_UNIX_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) \ 302 + BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UNIX_SENDMSG, t_ctx) 303 + 303 304 #define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr, uaddrlen) \ 304 305 BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UDP4_RECVMSG, NULL) 305 306 306 307 #define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr, uaddrlen) \ 307 308 BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UDP6_RECVMSG, NULL) 309 + 310 + #define BPF_CGROUP_RUN_PROG_UNIX_RECVMSG_LOCK(sk, uaddr, uaddrlen) \ 311 + BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UNIX_RECVMSG, NULL) 308 312 309 313 /* The SOCK_OPS"_SK" macro should be used when sock_ops->sk is not a 310 314 * fullsock and its parent fullsock cannot be traced by ··· 506 492 #define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr, uaddrlen) ({ 0; }) 507 493 #define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr, uaddrlen) ({ 0; }) 508 494 #define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr, uaddrlen) ({ 0; }) 495 + #define BPF_CGROUP_RUN_PROG_UNIX_CONNECT_LOCK(sk, uaddr, uaddrlen) ({ 0; }) 509 496 #define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) ({ 0; }) 510 497 #define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) ({ 0; }) 498 + #define BPF_CGROUP_RUN_PROG_UNIX_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) ({ 0; }) 511 499 #define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; }) 512 500 #define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; }) 501 + #define BPF_CGROUP_RUN_PROG_UNIX_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; }) 513 502 #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; }) 514 503 #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(atype, major, minor, access) ({ 0; }) 515 504 #define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos) ({ 0; })
+9 -4
include/uapi/linux/bpf.h
··· 1047 1047 BPF_TCX_INGRESS, 1048 1048 BPF_TCX_EGRESS, 1049 1049 BPF_TRACE_UPROBE_MULTI, 1050 + BPF_CGROUP_UNIX_CONNECT, 1051 + BPF_CGROUP_UNIX_SENDMSG, 1052 + BPF_CGROUP_UNIX_RECVMSG, 1053 + BPF_CGROUP_UNIX_GETPEERNAME, 1054 + BPF_CGROUP_UNIX_GETSOCKNAME, 1050 1055 __MAX_BPF_ATTACH_TYPE 1051 1056 }; 1052 1057 ··· 2709 2704 * *bpf_socket* should be one of the following: 2710 2705 * 2711 2706 * * **struct bpf_sock_ops** for **BPF_PROG_TYPE_SOCK_OPS**. 2712 - * * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT** 2713 - * and **BPF_CGROUP_INET6_CONNECT**. 2707 + * * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT**, 2708 + * **BPF_CGROUP_INET6_CONNECT** and **BPF_CGROUP_UNIX_CONNECT**. 2714 2709 * 2715 2710 * This helper actually implements a subset of **setsockopt()**. 2716 2711 * It supports the following *level*\ s: ··· 2948 2943 * *bpf_socket* should be one of the following: 2949 2944 * 2950 2945 * * **struct bpf_sock_ops** for **BPF_PROG_TYPE_SOCK_OPS**. 2951 - * * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT** 2952 - * and **BPF_CGROUP_INET6_CONNECT**. 2946 + * * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT**, 2947 + * **BPF_CGROUP_INET6_CONNECT** and **BPF_CGROUP_UNIX_CONNECT**. 2953 2948 * 2954 2949 * This helper actually implements a subset of **getsockopt()**. 2955 2950 * It supports the same set of *optname*\ s that is supported by
+9 -2
kernel/bpf/cgroup.c
··· 1458 1458 * @flags: Pointer to u32 which contains higher bits of BPF program 1459 1459 * return value (OR'ed together). 1460 1460 * 1461 - * socket is expected to be of type INET or INET6. 1461 + * socket is expected to be of type INET, INET6 or UNIX. 1462 1462 * 1463 1463 * This function will return %-EPERM if an attached program is found and 1464 1464 * returned value != 1 during execution. In all other cases, 0 is returned. ··· 1482 1482 /* Check socket family since not all sockets represent network 1483 1483 * endpoint (e.g. AF_UNIX). 1484 1484 */ 1485 - if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6) 1485 + if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6 && 1486 + sk->sk_family != AF_UNIX) 1486 1487 return 0; 1487 1488 1488 1489 if (!ctx.uaddr) { ··· 2534 2533 case BPF_CGROUP_SOCK_OPS: 2535 2534 case BPF_CGROUP_UDP4_RECVMSG: 2536 2535 case BPF_CGROUP_UDP6_RECVMSG: 2536 + case BPF_CGROUP_UNIX_RECVMSG: 2537 2537 case BPF_CGROUP_INET4_GETPEERNAME: 2538 2538 case BPF_CGROUP_INET6_GETPEERNAME: 2539 + case BPF_CGROUP_UNIX_GETPEERNAME: 2539 2540 case BPF_CGROUP_INET4_GETSOCKNAME: 2540 2541 case BPF_CGROUP_INET6_GETSOCKNAME: 2542 + case BPF_CGROUP_UNIX_GETSOCKNAME: 2541 2543 return NULL; 2542 2544 default: 2543 2545 return &bpf_get_retval_proto; ··· 2552 2548 case BPF_CGROUP_SOCK_OPS: 2553 2549 case BPF_CGROUP_UDP4_RECVMSG: 2554 2550 case BPF_CGROUP_UDP6_RECVMSG: 2551 + case BPF_CGROUP_UNIX_RECVMSG: 2555 2552 case BPF_CGROUP_INET4_GETPEERNAME: 2556 2553 case BPF_CGROUP_INET6_GETPEERNAME: 2554 + case BPF_CGROUP_UNIX_GETPEERNAME: 2557 2555 case BPF_CGROUP_INET4_GETSOCKNAME: 2558 2556 case BPF_CGROUP_INET6_GETSOCKNAME: 2557 + case BPF_CGROUP_UNIX_GETSOCKNAME: 2559 2558 return NULL; 2560 2559 default: 2561 2560 return &bpf_set_retval_proto;
+15
kernel/bpf/syscall.c
··· 2446 2446 case BPF_CGROUP_INET6_BIND: 2447 2447 case BPF_CGROUP_INET4_CONNECT: 2448 2448 case BPF_CGROUP_INET6_CONNECT: 2449 + case BPF_CGROUP_UNIX_CONNECT: 2449 2450 case BPF_CGROUP_INET4_GETPEERNAME: 2450 2451 case BPF_CGROUP_INET6_GETPEERNAME: 2452 + case BPF_CGROUP_UNIX_GETPEERNAME: 2451 2453 case BPF_CGROUP_INET4_GETSOCKNAME: 2452 2454 case BPF_CGROUP_INET6_GETSOCKNAME: 2455 + case BPF_CGROUP_UNIX_GETSOCKNAME: 2453 2456 case BPF_CGROUP_UDP4_SENDMSG: 2454 2457 case BPF_CGROUP_UDP6_SENDMSG: 2458 + case BPF_CGROUP_UNIX_SENDMSG: 2455 2459 case BPF_CGROUP_UDP4_RECVMSG: 2456 2460 case BPF_CGROUP_UDP6_RECVMSG: 2461 + case BPF_CGROUP_UNIX_RECVMSG: 2457 2462 return 0; 2458 2463 default: 2459 2464 return -EINVAL; ··· 3683 3678 case BPF_CGROUP_INET6_BIND: 3684 3679 case BPF_CGROUP_INET4_CONNECT: 3685 3680 case BPF_CGROUP_INET6_CONNECT: 3681 + case BPF_CGROUP_UNIX_CONNECT: 3686 3682 case BPF_CGROUP_INET4_GETPEERNAME: 3687 3683 case BPF_CGROUP_INET6_GETPEERNAME: 3684 + case BPF_CGROUP_UNIX_GETPEERNAME: 3688 3685 case BPF_CGROUP_INET4_GETSOCKNAME: 3689 3686 case BPF_CGROUP_INET6_GETSOCKNAME: 3687 + case BPF_CGROUP_UNIX_GETSOCKNAME: 3690 3688 case BPF_CGROUP_UDP4_SENDMSG: 3691 3689 case BPF_CGROUP_UDP6_SENDMSG: 3690 + case BPF_CGROUP_UNIX_SENDMSG: 3692 3691 case BPF_CGROUP_UDP4_RECVMSG: 3693 3692 case BPF_CGROUP_UDP6_RECVMSG: 3693 + case BPF_CGROUP_UNIX_RECVMSG: 3694 3694 return BPF_PROG_TYPE_CGROUP_SOCK_ADDR; 3695 3695 case BPF_CGROUP_SOCK_OPS: 3696 3696 return BPF_PROG_TYPE_SOCK_OPS; ··· 3952 3942 case BPF_CGROUP_INET6_POST_BIND: 3953 3943 case BPF_CGROUP_INET4_CONNECT: 3954 3944 case BPF_CGROUP_INET6_CONNECT: 3945 + case BPF_CGROUP_UNIX_CONNECT: 3955 3946 case BPF_CGROUP_INET4_GETPEERNAME: 3956 3947 case BPF_CGROUP_INET6_GETPEERNAME: 3948 + case BPF_CGROUP_UNIX_GETPEERNAME: 3957 3949 case BPF_CGROUP_INET4_GETSOCKNAME: 3958 3950 case BPF_CGROUP_INET6_GETSOCKNAME: 3951 + case BPF_CGROUP_UNIX_GETSOCKNAME: 3959 3952 case BPF_CGROUP_UDP4_SENDMSG: 3960 3953 case BPF_CGROUP_UDP6_SENDMSG: 3954 + case BPF_CGROUP_UNIX_SENDMSG: 3961 3955 case BPF_CGROUP_UDP4_RECVMSG: 3962 3956 case BPF_CGROUP_UDP6_RECVMSG: 3957 + case BPF_CGROUP_UNIX_RECVMSG: 3963 3958 case BPF_CGROUP_SOCK_OPS: 3964 3959 case BPF_CGROUP_DEVICE: 3965 3960 case BPF_CGROUP_SYSCTL:
+4 -1
kernel/bpf/verifier.c
··· 14797 14797 case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: 14798 14798 if (env->prog->expected_attach_type == BPF_CGROUP_UDP4_RECVMSG || 14799 14799 env->prog->expected_attach_type == BPF_CGROUP_UDP6_RECVMSG || 14800 + env->prog->expected_attach_type == BPF_CGROUP_UNIX_RECVMSG || 14800 14801 env->prog->expected_attach_type == BPF_CGROUP_INET4_GETPEERNAME || 14801 14802 env->prog->expected_attach_type == BPF_CGROUP_INET6_GETPEERNAME || 14803 + env->prog->expected_attach_type == BPF_CGROUP_UNIX_GETPEERNAME || 14802 14804 env->prog->expected_attach_type == BPF_CGROUP_INET4_GETSOCKNAME || 14803 - env->prog->expected_attach_type == BPF_CGROUP_INET6_GETSOCKNAME) 14805 + env->prog->expected_attach_type == BPF_CGROUP_INET6_GETSOCKNAME || 14806 + env->prog->expected_attach_type == BPF_CGROUP_UNIX_GETSOCKNAME) 14804 14807 range = tnum_range(1, 1); 14805 14808 if (env->prog->expected_attach_type == BPF_CGROUP_INET4_BIND || 14806 14809 env->prog->expected_attach_type == BPF_CGROUP_INET6_BIND)
+12 -2
net/core/filter.c
··· 7875 7875 case BPF_CGROUP_INET6_BIND: 7876 7876 case BPF_CGROUP_INET4_CONNECT: 7877 7877 case BPF_CGROUP_INET6_CONNECT: 7878 + case BPF_CGROUP_UNIX_CONNECT: 7878 7879 case BPF_CGROUP_UDP4_RECVMSG: 7879 7880 case BPF_CGROUP_UDP6_RECVMSG: 7881 + case BPF_CGROUP_UNIX_RECVMSG: 7880 7882 case BPF_CGROUP_UDP4_SENDMSG: 7881 7883 case BPF_CGROUP_UDP6_SENDMSG: 7884 + case BPF_CGROUP_UNIX_SENDMSG: 7882 7885 case BPF_CGROUP_INET4_GETPEERNAME: 7883 7886 case BPF_CGROUP_INET6_GETPEERNAME: 7887 + case BPF_CGROUP_UNIX_GETPEERNAME: 7884 7888 case BPF_CGROUP_INET4_GETSOCKNAME: 7885 7889 case BPF_CGROUP_INET6_GETSOCKNAME: 7890 + case BPF_CGROUP_UNIX_GETSOCKNAME: 7886 7891 return &bpf_sock_addr_setsockopt_proto; 7887 7892 default: 7888 7893 return NULL; ··· 7898 7893 case BPF_CGROUP_INET6_BIND: 7899 7894 case BPF_CGROUP_INET4_CONNECT: 7900 7895 case BPF_CGROUP_INET6_CONNECT: 7896 + case BPF_CGROUP_UNIX_CONNECT: 7901 7897 case BPF_CGROUP_UDP4_RECVMSG: 7902 7898 case BPF_CGROUP_UDP6_RECVMSG: 7899 + case BPF_CGROUP_UNIX_RECVMSG: 7903 7900 case BPF_CGROUP_UDP4_SENDMSG: 7904 7901 case BPF_CGROUP_UDP6_SENDMSG: 7902 + case BPF_CGROUP_UNIX_SENDMSG: 7905 7903 case BPF_CGROUP_INET4_GETPEERNAME: 7906 7904 case BPF_CGROUP_INET6_GETPEERNAME: 7905 + case BPF_CGROUP_UNIX_GETPEERNAME: 7907 7906 case BPF_CGROUP_INET4_GETSOCKNAME: 7908 7907 case BPF_CGROUP_INET6_GETSOCKNAME: 7908 + case BPF_CGROUP_UNIX_GETSOCKNAME: 7909 7909 return &bpf_sock_addr_getsockopt_proto; 7910 7910 default: 7911 7911 return NULL; ··· 8958 8948 if (off % size != 0) 8959 8949 return false; 8960 8950 8961 - /* Disallow access to IPv6 fields from IPv4 contex and vise 8962 - * versa. 8951 + /* Disallow access to fields not belonging to the attach type's address 8952 + * family. 8963 8953 */ 8964 8954 switch (off) { 8965 8955 case bpf_ctx_range(struct bpf_sock_addr, user_ip4):
+34 -1
net/unix/af_unix.c
··· 116 116 #include <linux/freezer.h> 117 117 #include <linux/file.h> 118 118 #include <linux/btf_ids.h> 119 + #include <linux/bpf-cgroup.h> 119 120 120 121 #include "scm.h" 121 122 ··· 1382 1381 if (err) 1383 1382 goto out; 1384 1383 1384 + err = BPF_CGROUP_RUN_PROG_UNIX_CONNECT_LOCK(sk, addr, &alen); 1385 + if (err) 1386 + goto out; 1387 + 1385 1388 if ((test_bit(SOCK_PASSCRED, &sock->flags) || 1386 1389 test_bit(SOCK_PASSPIDFD, &sock->flags)) && 1387 1390 !unix_sk(sk)->addr) { ··· 1492 1487 int st; 1493 1488 1494 1489 err = unix_validate_addr(sunaddr, addr_len); 1490 + if (err) 1491 + goto out; 1492 + 1493 + err = BPF_CGROUP_RUN_PROG_UNIX_CONNECT_LOCK(sk, uaddr, &addr_len); 1495 1494 if (err) 1496 1495 goto out; 1497 1496 ··· 1779 1770 } else { 1780 1771 err = addr->len; 1781 1772 memcpy(sunaddr, addr->name, addr->len); 1773 + 1774 + if (peer) 1775 + BPF_CGROUP_RUN_SA_PROG(sk, uaddr, &err, 1776 + CGROUP_UNIX_GETPEERNAME); 1777 + else 1778 + BPF_CGROUP_RUN_SA_PROG(sk, uaddr, &err, 1779 + CGROUP_UNIX_GETSOCKNAME); 1782 1780 } 1783 1781 sock_put(sk); 1784 1782 out: ··· 1936 1920 1937 1921 if (msg->msg_namelen) { 1938 1922 err = unix_validate_addr(sunaddr, msg->msg_namelen); 1923 + if (err) 1924 + goto out; 1925 + 1926 + err = BPF_CGROUP_RUN_PROG_UNIX_SENDMSG_LOCK(sk, 1927 + msg->msg_name, 1928 + &msg->msg_namelen, 1929 + NULL); 1939 1930 if (err) 1940 1931 goto out; 1941 1932 } else { ··· 2413 2390 EPOLLOUT | EPOLLWRNORM | 2414 2391 EPOLLWRBAND); 2415 2392 2416 - if (msg->msg_name) 2393 + if (msg->msg_name) { 2417 2394 unix_copy_addr(msg, skb->sk); 2395 + 2396 + BPF_CGROUP_RUN_PROG_UNIX_RECVMSG_LOCK(sk, 2397 + msg->msg_name, 2398 + &msg->msg_namelen); 2399 + } 2418 2400 2419 2401 if (size > skb->len - skip) 2420 2402 size = skb->len - skip; ··· 2772 2744 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, 2773 2745 state->msg->msg_name); 2774 2746 unix_copy_addr(state->msg, skb->sk); 2747 + 2748 + BPF_CGROUP_RUN_PROG_UNIX_RECVMSG_LOCK(sk, 2749 + state->msg->msg_name, 2750 + &state->msg->msg_namelen); 2751 + 2775 2752 sunaddr = NULL; 2776 2753 } 2777 2754
+9 -4
tools/include/uapi/linux/bpf.h
··· 1047 1047 BPF_TCX_INGRESS, 1048 1048 BPF_TCX_EGRESS, 1049 1049 BPF_TRACE_UPROBE_MULTI, 1050 + BPF_CGROUP_UNIX_CONNECT, 1051 + BPF_CGROUP_UNIX_SENDMSG, 1052 + BPF_CGROUP_UNIX_RECVMSG, 1053 + BPF_CGROUP_UNIX_GETPEERNAME, 1054 + BPF_CGROUP_UNIX_GETSOCKNAME, 1050 1055 __MAX_BPF_ATTACH_TYPE 1051 1056 }; 1052 1057 ··· 2709 2704 * *bpf_socket* should be one of the following: 2710 2705 * 2711 2706 * * **struct bpf_sock_ops** for **BPF_PROG_TYPE_SOCK_OPS**. 2712 - * * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT** 2713 - * and **BPF_CGROUP_INET6_CONNECT**. 2707 + * * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT**, 2708 + * **BPF_CGROUP_INET6_CONNECT** and **BPF_CGROUP_UNIX_CONNECT**. 2714 2709 * 2715 2710 * This helper actually implements a subset of **setsockopt()**. 2716 2711 * It supports the following *level*\ s: ··· 2948 2943 * *bpf_socket* should be one of the following: 2949 2944 * 2950 2945 * * **struct bpf_sock_ops** for **BPF_PROG_TYPE_SOCK_OPS**. 2951 - * * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT** 2952 - * and **BPF_CGROUP_INET6_CONNECT**. 2946 + * * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT**, 2947 + * **BPF_CGROUP_INET6_CONNECT** and **BPF_CGROUP_UNIX_CONNECT**. 2953 2948 * 2954 2949 * This helper actually implements a subset of **getsockopt()**. 2955 2950 * It supports the same set of *optname*\ s that is supported by