Re: [PATCH] bpf: Add BPF_CGROUP_UNIX_CONNECT attach type

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 12/6/22 8:32 AM, Daan De Meyer wrote:
This hook allows intercepting connect() calls on unix sockets. After
running the hook, we recalculate the sockaddr length as it the hook

as the hook

might have replaced the sun_path with a longer/shorter one. This is
safe because all kernelspace sockaddrs are stored in instances of
sockaddr_storage which is guaranteed to larger than sockaddr_un.

This hook can be used when users want to multiplex connect()
calls to a single unix socket to multiple different processes
behind the scenes by redirecting the connect() calls to process
specific sockets.

Signed-off-by: Daan De Meyer <daan.j.demeyer@xxxxxxxxx>
---
  Documentation/bpf/libbpf/program_types.rst    |  2 +
  include/linux/bpf-cgroup-defs.h               |  1 +
  include/linux/bpf-cgroup.h                    | 12 ++-
  include/uapi/linux/bpf.h                      | 10 ++-
  kernel/bpf/cgroup.c                           |  5 +-
  kernel/bpf/syscall.c                          |  3 +
  net/core/filter.c                             | 28 +++++++
  net/unix/af_unix.c                            | 37 +++++++++
  tools/bpf/bpftool/common.c                    |  1 +
  tools/include/uapi/linux/bpf.h                | 10 ++-
  tools/lib/bpf/libbpf.c                        |  2 +
  .../selftests/bpf/prog_tests/section_names.c  |  5 ++
  .../selftests/bpf/progs/connectun_prog.c      | 27 ++++++
  tools/testing/selftests/bpf/test_sock_addr.c  | 83 +++++++++++++++++--
  14 files changed, 206 insertions(+), 20 deletions(-)
  create mode 100644 tools/testing/selftests/bpf/progs/connectun_prog.c

Please break this into multiple patches for easier review:
patch 1: core change
>   include/linux/bpf-cgroup-defs.h               |  1 +
>   include/linux/bpf-cgroup.h                    | 12 ++-
>   include/uapi/linux/bpf.h                      | 10 ++-
>   kernel/bpf/cgroup.c                           |  5 +-
>   kernel/bpf/syscall.c                          |  3 +
>   net/core/filter.c                             | 28 +++++++
>   net/unix/af_unix.c
>   tools/include/uapi/linux/bpf.h                | 10 ++-
patch 2: libbpf change
>   tools/lib/bpf/libbpf.c                        |  2 +
patch 3: bpftool change
>   tools/bpf/bpftool/common.c                    |  1 +
patch 4: selftest change:
>   .../selftests/bpf/prog_tests/section_names.c  |  5 ++
>   .../selftests/bpf/progs/connectun_prog.c      | 27 ++++++
>   tools/testing/selftests/bpf/test_sock_addr.c  | 83 +++++++++++++++++--
patch 5: doc change:
>   Documentation/bpf/libbpf/program_types.rst    |  2 +


diff --git a/Documentation/bpf/libbpf/program_types.rst b/Documentation/bpf/libbpf/program_types.rst
index ad4d4d5eecb0..7d0bcd883561 100644
--- a/Documentation/bpf/libbpf/program_types.rst
+++ b/Documentation/bpf/libbpf/program_types.rst
@@ -56,6 +56,8 @@ described in more detail in the footnotes.
  |                                           | ``BPF_CGROUP_UDP6_RECVMSG``            | ``cgroup/recvmsg6``              |           |
  +                                           +----------------------------------------+----------------------------------+-----------+
  |                                           | ``BPF_CGROUP_UDP6_SENDMSG``            | ``cgroup/sendmsg6``              |           |
+|                                           +----------------------------------------+----------------------------------+-----------+
+|                                           | ``BPF_CGROUP_UNIX_CONNECT``            | ``cgroup/connectun``             |           |
  +-------------------------------------------+----------------------------------------+----------------------------------+-----------+
  | ``BPF_PROG_TYPE_CGROUP_SOCK``             | ``BPF_CGROUP_INET4_POST_BIND``         | ``cgroup/post_bind4``            |           |
  +                                           +----------------------------------------+----------------------------------+-----------+
[...]
@@ -6353,6 +6354,7 @@ struct bpf_sock_addr {
  	__u32 user_ip6[4];	/* Allows 1,2,4,8-byte read and 4,8-byte write.
  				 * Stored in network byte order.
  				 */
+	char user_path[108];    /* Allows 1 byte read and write. */
  	__u32 user_port;	/* Allows 1,2,4-byte read and 4-byte write.
  				 * Stored in network byte order
  				 */

Please put the new field at the end of struct. Otherwise, we have
uapi compatibility issue.

diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index bf2fdb33fb31..f1d20f69b260 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -1454,7 +1454,7 @@ EXPORT_SYMBOL(__cgroup_bpf_run_filter_sk);
   * @flags: Pointer to u32 which contains higher bits of BPF program
   *         return value (OR'ed together).
   *
- * socket is expected to be of type INET or INET6.
+ * socket is expected to be of type INET, INET6 or UNIX.
   *
   * This function will return %-EPERM if an attached program is found and
   * returned value != 1 during execution. In all other cases, 0 is returned.
@@ -1476,7 +1476,8 @@ int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
  	/* Check socket family since not all sockets represent network
  	 * endpoint (e.g. AF_UNIX).
  	 */
-	if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6)
+	if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6 &&
+		sk->sk_family != AF_UNIX)
  		return 0;
if (!ctx.uaddr) {
[...]
diff --git a/tools/testing/selftests/bpf/progs/connectun_prog.c b/tools/testing/selftests/bpf/progs/connectun_prog.c
new file mode 100644
index 000000000000..91097bd8df3c
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/connectun_prog.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Facebook

/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */

+
+#include <string.h>
+
+#include <linux/stddef.h>
+#include <linux/bpf.h>
+#include <linux/if.h>
+#include <errno.h>
+
+#include <bpf/bpf_helpers.h>
+
+#define DST_REWRITE_PATH	"/tmp/bpf_cgroup_unix_test_rewrite"
+
+SEC("cgroup/connectun")
+int connect_un_prog(struct bpf_sock_addr *ctx)
+{
+	if (ctx->type != SOCK_STREAM && ctx->type != SOCK_DGRAM)
+		return 0;
+
+	/* Rewrite destination. */
+	memcpy(ctx->user_path, DST_REWRITE_PATH, sizeof(DST_REWRITE_PATH));
+
+	return 1;
+}
+
[...]



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux