Skip to content

Commit d2dc885

Browse files
author
Martin KaFai Lau
committed
Merge branch 'Add cgroup sockaddr hooks for unix sockets'
Daan De Meyer says: ==================== Changes since v10: * Removed extra check from bpf_sock_addr_set_sun_path() again in favor of calling unix_validate_addr() everywhere in af_unix.c before calling the hooks. Changes since v9: * Renamed bpf_sock_addr_set_unix_addr() to bpf_sock_addr_set_sun_path() and rennamed arguments to match the new name. * Added an extra check to bpf_sock_addr_set_sun_path() to disallow changing the address of an unnamed unix socket. * Removed unnecessary NULL check on uaddrlen in __cgroup_bpf_run_filter_sock_addr(). Changes since v8: * Added missing test programs to last patch Changes since v7: * Fixed formatting nit in comment * Renamed from cgroup/connectun to cgroup/connect_unix (and similar for all other hooks) Changes since v6: * Actually removed bpf_bind() helper for AF_UNIX hooks. * Fixed merge conflict * Updated comment to mention uaddrlen is read-only for AF_INET[6] * Removed unnecessary forward declaration of struct sock_addr_test * Removed unused BPF_CGROUP_RUN_PROG_UNIX_CONNECT() * Fixed formatting nit reported by checkpatch * Added more information to commit message about recvmsg() on connected socket Changes since v5: * Fixed kernel version in bpftool documentation (6.3 => 6.7). * Added connection mode socket recvmsg() test. * Removed bpf_bind() helper for AF_UNIX hooks. * Added missing getpeernameun and getsocknameun BPF test programs. * Added note for bind() test being unused currently. Changes since v4: * Dropped support for intercepting bind() as when using bind() with unix sockets and a pathname sockaddr, bind() will create an inode in the filesystem that needs to be cleaned up. If the address is rewritten, users might try to clean up the wrong file and leak the actual socket file in the filesystem. * Changed bpf_sock_addr_set_unix_addr() to use BTF_KFUNC_HOOK_CGROUP_SKB instead of BTF_KFUNC_HOOK_COMMON. * Removed unix socket related changes from BPF_CGROUP_PRE_CONNECT_ENABLED() as unix sockets do not support pre-connect. * Added tests for getpeernameun and getsocknameun hooks. * We now disallow an empty sockaddr in bpf_sock_addr_set_unix_addr() similar to unix_validate_addr(). * Removed unnecessary cgroup_bpf_enabled() checks * Removed unnecessary error checks Changes since v3: * Renamed bpf_sock_addr_set_addr() to bpf_sock_addr_set_unix_addr() and made it only operate on AF_UNIX sockaddrs. This is because for the other families, users usually want to configure more than just the address so a generic interface will not fit the bill here. e.g. for AF_INET and AF_INET6, users would generally also want to be able to configure the port which the current interface doesn't support. So we expose an AF_UNIX specific function instead. * Made the tests in the new sock addr tests more generic (similar to test_sock_addr.c), this should make it easier to migrate the other sock addr tests in the future. * Removed the new kfunc hook and attached to BTF_KFUNC_HOOK_COMMON instead * Set uaddrlen to 0 when the family is AF_UNSPEC * Pass in the addrlen to the hook from IPv6 code * Fixed mount directory mkdir() to ignore EEXIST Changes since v2: * Configuring the sock addr is now done via a new kfunc bpf_sock_addr_set() * The addrlen is exposed as u32 in bpf_sock_addr_kern * Selftests are updated to use the new kfunc * Selftests are now added as a new sock_addr test in prog_tests/ * Added BTF_KFUNC_HOOK_SOCK_ADDR for BPF_PROG_TYPE_CGROUP_SOCK_ADDR * __cgroup_bpf_run_filter_sock_addr() now returns the modified addrlen Changes since v1: * Split into multiple patches instead of one single patch * Added unix support for all socket address hooks instead of only connect() * Switched approach to expose the socket address length to the bpf hook instead of recalculating the socket address length in kernelspace to properly support abstract unix socket addresses * Modified socket address hook tests to calculate the socket address length once and pass it around everywhere instead of recalculating the actual unix socket address length on demand. * Added some missing section name tests for getpeername()/getsockname() This patch series extends the cgroup sockaddr hooks to include support for unix sockets. To add support for unix sockets, struct bpf_sock_addr_kern is extended to expose the socket address length to the bpf program. Along with that, a new kfunc bpf_sock_addr_set_unix_addr() is added to safely allow modifying an AF_UNIX sockaddr from bpf programs. I intend to use these new hooks in systemd to reimplement the LogNamespace= feature, which allows running multiple instances of systemd-journald to process the logs of different services. systemd-journald also processes syslog messages, so currently, using log namespaces means all services running in the same log namespace have to live in the same private mount namespace so that systemd can mount the journal namespace's associated syslog socket over /dev/log to properly direct syslog messages from all services running in that log namespace to the correct systemd-journald instance. We want to relax this requirement so that processes running in disjoint mount namespaces can still run in the same log namespace. To achieve this, we can use these new hooks to rewrite the socket address of any connect(), sendto(), ... syscalls to /dev/log to the socket address of the journal namespace's syslog socket instead, which will transparently do the redirection without requiring use of a mount namespace and mounting over /dev/log. Aside from the above usecase, these hooks can more generally be used to transparently redirect unix sockets to different addresses as required by services. ==================== Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
2 parents 1ef09e1 + 82ab6b5 commit d2dc885

37 files changed

+1191
-92
lines changed

Documentation/bpf/libbpf/program_types.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ described in more detail in the footnotes.
5656
| | ``BPF_CGROUP_UDP6_RECVMSG`` | ``cgroup/recvmsg6`` | |
5757
+ +----------------------------------------+----------------------------------+-----------+
5858
| | ``BPF_CGROUP_UDP6_SENDMSG`` | ``cgroup/sendmsg6`` | |
59+
| +----------------------------------------+----------------------------------+-----------+
60+
| | ``BPF_CGROUP_UNIX_CONNECT`` | ``cgroup/connect_unix`` | |
61+
| +----------------------------------------+----------------------------------+-----------+
62+
| | ``BPF_CGROUP_UNIX_SENDMSG`` | ``cgroup/sendmsg_unix`` | |
63+
| +----------------------------------------+----------------------------------+-----------+
64+
| | ``BPF_CGROUP_UNIX_RECVMSG`` | ``cgroup/recvmsg_unix`` | |
65+
| +----------------------------------------+----------------------------------+-----------+
66+
| | ``BPF_CGROUP_UNIX_GETPEERNAME`` | ``cgroup/getpeername_unix`` | |
67+
| +----------------------------------------+----------------------------------+-----------+
68+
| | ``BPF_CGROUP_UNIX_GETSOCKNAME`` | ``cgroup/getsockname_unix`` | |
5969
+-------------------------------------------+----------------------------------------+----------------------------------+-----------+
6070
| ``BPF_PROG_TYPE_CGROUP_SOCK`` | ``BPF_CGROUP_INET4_POST_BIND`` | ``cgroup/post_bind4`` | |
6171
+ +----------------------------------------+----------------------------------+-----------+

include/linux/bpf-cgroup-defs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,24 @@ enum cgroup_bpf_attach_type {
2828
CGROUP_INET6_BIND,
2929
CGROUP_INET4_CONNECT,
3030
CGROUP_INET6_CONNECT,
31+
CGROUP_UNIX_CONNECT,
3132
CGROUP_INET4_POST_BIND,
3233
CGROUP_INET6_POST_BIND,
3334
CGROUP_UDP4_SENDMSG,
3435
CGROUP_UDP6_SENDMSG,
36+
CGROUP_UNIX_SENDMSG,
3537
CGROUP_SYSCTL,
3638
CGROUP_UDP4_RECVMSG,
3739
CGROUP_UDP6_RECVMSG,
40+
CGROUP_UNIX_RECVMSG,
3841
CGROUP_GETSOCKOPT,
3942
CGROUP_SETSOCKOPT,
4043
CGROUP_INET4_GETPEERNAME,
4144
CGROUP_INET6_GETPEERNAME,
45+
CGROUP_UNIX_GETPEERNAME,
4246
CGROUP_INET4_GETSOCKNAME,
4347
CGROUP_INET6_GETSOCKNAME,
48+
CGROUP_UNIX_GETSOCKNAME,
4449
CGROUP_INET_SOCK_RELEASE,
4550
CGROUP_LSM_START,
4651
CGROUP_LSM_END = CGROUP_LSM_START + CGROUP_LSM_NUM - 1,

include/linux/bpf-cgroup.h

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,24 @@ to_cgroup_bpf_attach_type(enum bpf_attach_type attach_type)
4848
CGROUP_ATYPE(CGROUP_INET6_BIND);
4949
CGROUP_ATYPE(CGROUP_INET4_CONNECT);
5050
CGROUP_ATYPE(CGROUP_INET6_CONNECT);
51+
CGROUP_ATYPE(CGROUP_UNIX_CONNECT);
5152
CGROUP_ATYPE(CGROUP_INET4_POST_BIND);
5253
CGROUP_ATYPE(CGROUP_INET6_POST_BIND);
5354
CGROUP_ATYPE(CGROUP_UDP4_SENDMSG);
5455
CGROUP_ATYPE(CGROUP_UDP6_SENDMSG);
56+
CGROUP_ATYPE(CGROUP_UNIX_SENDMSG);
5557
CGROUP_ATYPE(CGROUP_SYSCTL);
5658
CGROUP_ATYPE(CGROUP_UDP4_RECVMSG);
5759
CGROUP_ATYPE(CGROUP_UDP6_RECVMSG);
60+
CGROUP_ATYPE(CGROUP_UNIX_RECVMSG);
5861
CGROUP_ATYPE(CGROUP_GETSOCKOPT);
5962
CGROUP_ATYPE(CGROUP_SETSOCKOPT);
6063
CGROUP_ATYPE(CGROUP_INET4_GETPEERNAME);
6164
CGROUP_ATYPE(CGROUP_INET6_GETPEERNAME);
65+
CGROUP_ATYPE(CGROUP_UNIX_GETPEERNAME);
6266
CGROUP_ATYPE(CGROUP_INET4_GETSOCKNAME);
6367
CGROUP_ATYPE(CGROUP_INET6_GETSOCKNAME);
68+
CGROUP_ATYPE(CGROUP_UNIX_GETSOCKNAME);
6469
CGROUP_ATYPE(CGROUP_INET_SOCK_RELEASE);
6570
default:
6671
return CGROUP_BPF_ATTACH_TYPE_INVALID;
@@ -120,6 +125,7 @@ int __cgroup_bpf_run_filter_sk(struct sock *sk,
120125

121126
int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
122127
struct sockaddr *uaddr,
128+
int *uaddrlen,
123129
enum cgroup_bpf_attach_type atype,
124130
void *t_ctx,
125131
u32 *flags);
@@ -230,22 +236,22 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
230236
#define BPF_CGROUP_RUN_PROG_INET6_POST_BIND(sk) \
231237
BPF_CGROUP_RUN_SK_PROG(sk, CGROUP_INET6_POST_BIND)
232238

233-
#define BPF_CGROUP_RUN_SA_PROG(sk, uaddr, atype) \
239+
#define BPF_CGROUP_RUN_SA_PROG(sk, uaddr, uaddrlen, atype) \
234240
({ \
235241
int __ret = 0; \
236242
if (cgroup_bpf_enabled(atype)) \
237-
__ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, atype, \
238-
NULL, NULL); \
243+
__ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, uaddrlen, \
244+
atype, NULL, NULL); \
239245
__ret; \
240246
})
241247

242-
#define BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, atype, t_ctx) \
248+
#define BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, atype, t_ctx) \
243249
({ \
244250
int __ret = 0; \
245251
if (cgroup_bpf_enabled(atype)) { \
246252
lock_sock(sk); \
247-
__ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, atype, \
248-
t_ctx, NULL); \
253+
__ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, uaddrlen, \
254+
atype, t_ctx, NULL); \
249255
release_sock(sk); \
250256
} \
251257
__ret; \
@@ -256,14 +262,14 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
256262
* (at bit position 0) is to indicate CAP_NET_BIND_SERVICE capability check
257263
* should be bypassed (BPF_RET_BIND_NO_CAP_NET_BIND_SERVICE).
258264
*/
259-
#define BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr, atype, bind_flags) \
265+
#define BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr, uaddrlen, atype, bind_flags) \
260266
({ \
261267
u32 __flags = 0; \
262268
int __ret = 0; \
263269
if (cgroup_bpf_enabled(atype)) { \
264270
lock_sock(sk); \
265-
__ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, atype, \
266-
NULL, &__flags); \
271+
__ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, uaddrlen, \
272+
atype, NULL, &__flags); \
267273
release_sock(sk); \
268274
if (__flags & BPF_RET_BIND_NO_CAP_NET_BIND_SERVICE) \
269275
*bind_flags |= BIND_NO_CAP_NET_BIND_SERVICE; \
@@ -276,29 +282,38 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
276282
cgroup_bpf_enabled(CGROUP_INET6_CONNECT)) && \
277283
(sk)->sk_prot->pre_connect)
278284

279-
#define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr) \
280-
BPF_CGROUP_RUN_SA_PROG(sk, uaddr, CGROUP_INET4_CONNECT)
285+
#define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr, uaddrlen) \
286+
BPF_CGROUP_RUN_SA_PROG(sk, uaddr, uaddrlen, CGROUP_INET4_CONNECT)
281287

282-
#define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr) \
283-
BPF_CGROUP_RUN_SA_PROG(sk, uaddr, CGROUP_INET6_CONNECT)
288+
#define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr, uaddrlen) \
289+
BPF_CGROUP_RUN_SA_PROG(sk, uaddr, uaddrlen, CGROUP_INET6_CONNECT)
284290

285-
#define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr) \
286-
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, CGROUP_INET4_CONNECT, NULL)
291+
#define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr, uaddrlen) \
292+
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_INET4_CONNECT, NULL)
287293

288-
#define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr) \
289-
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, CGROUP_INET6_CONNECT, NULL)
294+
#define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr, uaddrlen) \
295+
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_INET6_CONNECT, NULL)
290296

291-
#define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, t_ctx) \
292-
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, CGROUP_UDP4_SENDMSG, t_ctx)
297+
#define BPF_CGROUP_RUN_PROG_UNIX_CONNECT_LOCK(sk, uaddr, uaddrlen) \
298+
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UNIX_CONNECT, NULL)
293299

294-
#define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) \
295-
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, CGROUP_UDP6_SENDMSG, t_ctx)
300+
#define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) \
301+
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UDP4_SENDMSG, t_ctx)
296302

297-
#define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr) \
298-
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, CGROUP_UDP4_RECVMSG, NULL)
303+
#define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) \
304+
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UDP6_SENDMSG, t_ctx)
299305

300-
#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr) \
301-
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, CGROUP_UDP6_RECVMSG, NULL)
306+
#define BPF_CGROUP_RUN_PROG_UNIX_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) \
307+
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UNIX_SENDMSG, t_ctx)
308+
309+
#define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr, uaddrlen) \
310+
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UDP4_RECVMSG, NULL)
311+
312+
#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr, uaddrlen) \
313+
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UDP6_RECVMSG, NULL)
314+
315+
#define BPF_CGROUP_RUN_PROG_UNIX_RECVMSG_LOCK(sk, uaddr, uaddrlen) \
316+
BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, CGROUP_UNIX_RECVMSG, NULL)
302317

303318
/* The SOCK_OPS"_SK" macro should be used when sock_ops->sk is not a
304319
* fullsock and its parent fullsock cannot be traced by
@@ -477,24 +492,27 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
477492
}
478493

479494
#define cgroup_bpf_enabled(atype) (0)
480-
#define BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, atype, t_ctx) ({ 0; })
481-
#define BPF_CGROUP_RUN_SA_PROG(sk, uaddr, atype) ({ 0; })
495+
#define BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, atype, t_ctx) ({ 0; })
496+
#define BPF_CGROUP_RUN_SA_PROG(sk, uaddr, uaddrlen, atype) ({ 0; })
482497
#define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0)
483498
#define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; })
484499
#define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk,skb) ({ 0; })
485500
#define BPF_CGROUP_RUN_PROG_INET_SOCK(sk) ({ 0; })
486501
#define BPF_CGROUP_RUN_PROG_INET_SOCK_RELEASE(sk) ({ 0; })
487-
#define BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr, atype, flags) ({ 0; })
502+
#define BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr, uaddrlen, atype, flags) ({ 0; })
488503
#define BPF_CGROUP_RUN_PROG_INET4_POST_BIND(sk) ({ 0; })
489504
#define BPF_CGROUP_RUN_PROG_INET6_POST_BIND(sk) ({ 0; })
490-
#define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr) ({ 0; })
491-
#define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr) ({ 0; })
492-
#define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr) ({ 0; })
493-
#define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr) ({ 0; })
494-
#define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; })
495-
#define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; })
496-
#define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr) ({ 0; })
497-
#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr) ({ 0; })
505+
#define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr, uaddrlen) ({ 0; })
506+
#define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr, uaddrlen) ({ 0; })
507+
#define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr, uaddrlen) ({ 0; })
508+
#define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr, uaddrlen) ({ 0; })
509+
#define BPF_CGROUP_RUN_PROG_UNIX_CONNECT_LOCK(sk, uaddr, uaddrlen) ({ 0; })
510+
#define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) ({ 0; })
511+
#define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) ({ 0; })
512+
#define BPF_CGROUP_RUN_PROG_UNIX_SENDMSG_LOCK(sk, uaddr, uaddrlen, t_ctx) ({ 0; })
513+
#define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
514+
#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
515+
#define BPF_CGROUP_RUN_PROG_UNIX_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
498516
#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
499517
#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(atype, major, minor, access) ({ 0; })
500518
#define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos) ({ 0; })

include/linux/filter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,7 @@ struct bpf_sock_addr_kern {
13351335
*/
13361336
u64 tmp_reg;
13371337
void *t_ctx; /* Attach type specific context. */
1338+
u32 uaddrlen;
13381339
};
13391340

13401341
struct bpf_sock_ops_kern {

include/uapi/linux/bpf.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,11 @@ enum bpf_attach_type {
10471047
BPF_TCX_INGRESS,
10481048
BPF_TCX_EGRESS,
10491049
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,
10501055
__MAX_BPF_ATTACH_TYPE
10511056
};
10521057

@@ -2704,8 +2709,8 @@ union bpf_attr {
27042709
* *bpf_socket* should be one of the following:
27052710
*
27062711
* * **struct bpf_sock_ops** for **BPF_PROG_TYPE_SOCK_OPS**.
2707-
* * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT**
2708-
* and **BPF_CGROUP_INET6_CONNECT**.
2712+
* * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT**,
2713+
* **BPF_CGROUP_INET6_CONNECT** and **BPF_CGROUP_UNIX_CONNECT**.
27092714
*
27102715
* This helper actually implements a subset of **setsockopt()**.
27112716
* It supports the following *level*\ s:
@@ -2943,8 +2948,8 @@ union bpf_attr {
29432948
* *bpf_socket* should be one of the following:
29442949
*
29452950
* * **struct bpf_sock_ops** for **BPF_PROG_TYPE_SOCK_OPS**.
2946-
* * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT**
2947-
* and **BPF_CGROUP_INET6_CONNECT**.
2951+
* * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT**,
2952+
* **BPF_CGROUP_INET6_CONNECT** and **BPF_CGROUP_UNIX_CONNECT**.
29482953
*
29492954
* This helper actually implements a subset of **getsockopt()**.
29502955
* It supports the same set of *optname*\ s that is supported by

kernel/bpf/btf.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7850,6 +7850,7 @@ static int bpf_prog_type_to_kfunc_hook(enum bpf_prog_type prog_type)
78507850
case BPF_PROG_TYPE_SYSCALL:
78517851
return BTF_KFUNC_HOOK_SYSCALL;
78527852
case BPF_PROG_TYPE_CGROUP_SKB:
7853+
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
78537854
return BTF_KFUNC_HOOK_CGROUP_SKB;
78547855
case BPF_PROG_TYPE_SCHED_ACT:
78557856
return BTF_KFUNC_HOOK_SCHED_ACT;

kernel/bpf/cgroup.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,18 +1450,22 @@ EXPORT_SYMBOL(__cgroup_bpf_run_filter_sk);
14501450
* provided by user sockaddr
14511451
* @sk: sock struct that will use sockaddr
14521452
* @uaddr: sockaddr struct provided by user
1453+
* @uaddrlen: Pointer to the size of the sockaddr struct provided by user. It is
1454+
* read-only for AF_INET[6] uaddr but can be modified for AF_UNIX
1455+
* uaddr.
14531456
* @atype: The type of program to be executed
14541457
* @t_ctx: Pointer to attach type specific context
14551458
* @flags: Pointer to u32 which contains higher bits of BPF program
14561459
* return value (OR'ed together).
14571460
*
1458-
* socket is expected to be of type INET or INET6.
1461+
* socket is expected to be of type INET, INET6 or UNIX.
14591462
*
14601463
* This function will return %-EPERM if an attached program is found and
14611464
* returned value != 1 during execution. In all other cases, 0 is returned.
14621465
*/
14631466
int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
14641467
struct sockaddr *uaddr,
1468+
int *uaddrlen,
14651469
enum cgroup_bpf_attach_type atype,
14661470
void *t_ctx,
14671471
u32 *flags)
@@ -1473,21 +1477,31 @@ int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
14731477
};
14741478
struct sockaddr_storage unspec;
14751479
struct cgroup *cgrp;
1480+
int ret;
14761481

14771482
/* Check socket family since not all sockets represent network
14781483
* endpoint (e.g. AF_UNIX).
14791484
*/
1480-
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)
14811487
return 0;
14821488

14831489
if (!ctx.uaddr) {
14841490
memset(&unspec, 0, sizeof(unspec));
14851491
ctx.uaddr = (struct sockaddr *)&unspec;
1492+
ctx.uaddrlen = 0;
1493+
} else {
1494+
ctx.uaddrlen = *uaddrlen;
14861495
}
14871496

14881497
cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
1489-
return bpf_prog_run_array_cg(&cgrp->bpf, atype, &ctx, bpf_prog_run,
1490-
0, flags);
1498+
ret = bpf_prog_run_array_cg(&cgrp->bpf, atype, &ctx, bpf_prog_run,
1499+
0, flags);
1500+
1501+
if (!ret && uaddr)
1502+
*uaddrlen = ctx.uaddrlen;
1503+
1504+
return ret;
14911505
}
14921506
EXPORT_SYMBOL(__cgroup_bpf_run_filter_sock_addr);
14931507

@@ -2520,10 +2534,13 @@ cgroup_common_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
25202534
case BPF_CGROUP_SOCK_OPS:
25212535
case BPF_CGROUP_UDP4_RECVMSG:
25222536
case BPF_CGROUP_UDP6_RECVMSG:
2537+
case BPF_CGROUP_UNIX_RECVMSG:
25232538
case BPF_CGROUP_INET4_GETPEERNAME:
25242539
case BPF_CGROUP_INET6_GETPEERNAME:
2540+
case BPF_CGROUP_UNIX_GETPEERNAME:
25252541
case BPF_CGROUP_INET4_GETSOCKNAME:
25262542
case BPF_CGROUP_INET6_GETSOCKNAME:
2543+
case BPF_CGROUP_UNIX_GETSOCKNAME:
25272544
return NULL;
25282545
default:
25292546
return &bpf_get_retval_proto;
@@ -2535,10 +2552,13 @@ cgroup_common_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
25352552
case BPF_CGROUP_SOCK_OPS:
25362553
case BPF_CGROUP_UDP4_RECVMSG:
25372554
case BPF_CGROUP_UDP6_RECVMSG:
2555+
case BPF_CGROUP_UNIX_RECVMSG:
25382556
case BPF_CGROUP_INET4_GETPEERNAME:
25392557
case BPF_CGROUP_INET6_GETPEERNAME:
2558+
case BPF_CGROUP_UNIX_GETPEERNAME:
25402559
case BPF_CGROUP_INET4_GETSOCKNAME:
25412560
case BPF_CGROUP_INET6_GETSOCKNAME:
2561+
case BPF_CGROUP_UNIX_GETSOCKNAME:
25422562
return NULL;
25432563
default:
25442564
return &bpf_set_retval_proto;

0 commit comments

Comments
 (0)