diff mbox series

[bpf,3/3] xsk: Try to make xdp_umem_reg extension a bit more future-proof

Message ID 20240713015253.121248-4-sdf@fomichev.me (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series xsk: require XDP_UMEM_TX_METADATA_LEN to actuate tx_metadata_len | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 45 this patch: 45
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 8 maintainers not CCed: hawk@kernel.org edumazet@google.com bjorn@kernel.org kuba@kernel.org maciej.fijalkowski@intel.com jonathan.lemon@gmail.com magnus.karlsson@intel.com pabeni@redhat.com
netdev/build_clang fail Errors and warnings before: 36 this patch: 36
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 45 this patch: 45
netdev/checkpatch warning WARNING: line length of 82 exceeds 80 columns WARNING: line length of 92 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-PR success PR summary
bpf/vmtest-bpf-VM_Test-32 success Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-27 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-15 success Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-VM_Test-22 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-6 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-31 success Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-38 success Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-23 success Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-24 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-39 success Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-40 success Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-14 success Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
bpf/vmtest-bpf-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-VM_Test-7 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-VM_Test-8 success Logs for set-matrix
bpf/vmtest-bpf-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-VM_Test-9 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-16 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-VM_Test-26 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-30 success Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-VM_Test-18 success Logs for set-matrix
bpf/vmtest-bpf-VM_Test-19 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-VM_Test-13 success Logs for s390x-gcc / test (test_maps, false, 360) / test_maps on s390x with gcc
bpf/vmtest-bpf-VM_Test-25 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-29 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
bpf/vmtest-bpf-VM_Test-28 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-10 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-VM_Test-21 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-17 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-VM_Test-20 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-VM_Test-12 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-VM_Test-33 success Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-34 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-VM_Test-35 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-36 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
bpf/vmtest-bpf-VM_Test-37 success Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-41 success Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-42 success Logs for x86_64-llvm-18 / veristat

Commit Message

Stanislav Fomichev July 13, 2024, 1:52 a.m. UTC
Add a couple of things:
1. Remove xdp_umem_reg_v2 since its sizeof is the same as xdp_umem_reg
2. Add BUILD_BUG_ON that checks that the size of xdp_umem_reg_v1 is less
   than xdp_umem_reg; presumably, when we get to v2, there is gonna
   be a similar line to enforce that sizeof(v2) > sizeof(v1)
3. Add BUILD_BUG_ON to make sure the last field plus its size matches
   the overall struct size. The intent is to demonstrate that we don't
   have any lingering padding.

Reported-by: Julian Schindel <mail@arctic-alpaca.de>
Cc: Magnus Karlsson <magnus.karlsson@gmail.com>
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
 net/xdp/xsk.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

Comments

Maciej Fijalkowski July 24, 2024, 3:21 p.m. UTC | #1
On Fri, Jul 12, 2024 at 06:52:53PM -0700, Stanislav Fomichev wrote:
> Add a couple of things:
> 1. Remove xdp_umem_reg_v2 since its sizeof is the same as xdp_umem_reg

So thing here is that adding __attribute__((packed)) on kernel side
wouldn't help because we wouldn't fix old uapi with this, correct? old
uapi would still yield 32 bytes for xdp_umem_reg without tx_metadata_len.

Just explaining here to myself.

> 2. Add BUILD_BUG_ON that checks that the size of xdp_umem_reg_v1 is less
>    than xdp_umem_reg; presumably, when we get to v2, there is gonna
>    be a similar line to enforce that sizeof(v2) > sizeof(v1)
> 3. Add BUILD_BUG_ON to make sure the last field plus its size matches
>    the overall struct size. The intent is to demonstrate that we don't
>    have any lingering padding.

This is good stuff but I wonder wouldn't it be more feasible to squash
this with 1/3 ? And have it backported. Regarding the patch logistics, you
did not provide fixes tag here for some reason, but still include the
patch routed via bpf tree.

> 
> Reported-by: Julian Schindel <mail@arctic-alpaca.de>
> Cc: Magnus Karlsson <magnus.karlsson@gmail.com>
> Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
> ---
>  net/xdp/xsk.c | 23 ++++++++++++-----------
>  1 file changed, 12 insertions(+), 11 deletions(-)
> 
> diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
> index 7d1c0986f9bb..1d951d7e3797 100644
> --- a/net/xdp/xsk.c
> +++ b/net/xdp/xsk.c
> @@ -1331,14 +1331,6 @@ struct xdp_umem_reg_v1 {
>  	__u32 headroom;
>  };
>  
> -struct xdp_umem_reg_v2 {
> -	__u64 addr; /* Start of packet data area */
> -	__u64 len; /* Length of packet data area */
> -	__u32 chunk_size;
> -	__u32 headroom;
> -	__u32 flags;
> -};
> -
>  static int xsk_setsockopt(struct socket *sock, int level, int optname,
>  			  sockptr_t optval, unsigned int optlen)
>  {
> @@ -1382,10 +1374,19 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname,
>  
>  		if (optlen < sizeof(struct xdp_umem_reg_v1))
>  			return -EINVAL;
> -		else if (optlen < sizeof(struct xdp_umem_reg_v2))
> -			mr_size = sizeof(struct xdp_umem_reg_v1);
>  		else if (optlen < sizeof(mr))
> -			mr_size = sizeof(struct xdp_umem_reg_v2);
> +			mr_size = sizeof(struct xdp_umem_reg_v1);
> +
> +		BUILD_BUG_ON(sizeof(struct xdp_umem_reg_v1) >= sizeof(struct xdp_umem_reg));
> +
> +		/* Make sure the last field of the struct doesn't have
> +		 * uninitialized padding. All padding has to be explicit
> +		 * and has to be set to zero by the userspace to make
> +		 * struct xdp_umem_reg extensible in the future.
> +		 */
> +		BUILD_BUG_ON(offsetof(struct xdp_umem_reg, tx_metadata_len) +
> +			     sizeof_field(struct xdp_umem_reg, tx_metadata_len) !=
> +			     sizeof(struct xdp_umem_reg));
>  
>  		if (copy_from_sockptr(&mr, optval, mr_size))
>  			return -EFAULT;
> -- 
> 2.45.2
> 
>
Stanislav Fomichev July 25, 2024, 6:01 p.m. UTC | #2
On 07/24, Maciej Fijalkowski wrote:
> On Fri, Jul 12, 2024 at 06:52:53PM -0700, Stanislav Fomichev wrote:
> > Add a couple of things:
> > 1. Remove xdp_umem_reg_v2 since its sizeof is the same as xdp_umem_reg
> 
> So thing here is that adding __attribute__((packed)) on kernel side
> wouldn't help because we wouldn't fix old uapi with this, correct? old
> uapi would still yield 32 bytes for xdp_umem_reg without tx_metadata_len.
> 
> Just explaining here to myself.

Yea :-(

> > 2. Add BUILD_BUG_ON that checks that the size of xdp_umem_reg_v1 is less
> >    than xdp_umem_reg; presumably, when we get to v2, there is gonna
> >    be a similar line to enforce that sizeof(v2) > sizeof(v1)
> > 3. Add BUILD_BUG_ON to make sure the last field plus its size matches
> >    the overall struct size. The intent is to demonstrate that we don't
> >    have any lingering padding.
> 
> This is good stuff but I wonder wouldn't it be more feasible to squash
> this with 1/3 ? And have it backported. Regarding the patch logistics, you
> did not provide fixes tag here for some reason, but still include the
> patch routed via bpf tree.

SG, will resend this against bpf-next.
diff mbox series

Patch

diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 7d1c0986f9bb..1d951d7e3797 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -1331,14 +1331,6 @@  struct xdp_umem_reg_v1 {
 	__u32 headroom;
 };
 
-struct xdp_umem_reg_v2 {
-	__u64 addr; /* Start of packet data area */
-	__u64 len; /* Length of packet data area */
-	__u32 chunk_size;
-	__u32 headroom;
-	__u32 flags;
-};
-
 static int xsk_setsockopt(struct socket *sock, int level, int optname,
 			  sockptr_t optval, unsigned int optlen)
 {
@@ -1382,10 +1374,19 @@  static int xsk_setsockopt(struct socket *sock, int level, int optname,
 
 		if (optlen < sizeof(struct xdp_umem_reg_v1))
 			return -EINVAL;
-		else if (optlen < sizeof(struct xdp_umem_reg_v2))
-			mr_size = sizeof(struct xdp_umem_reg_v1);
 		else if (optlen < sizeof(mr))
-			mr_size = sizeof(struct xdp_umem_reg_v2);
+			mr_size = sizeof(struct xdp_umem_reg_v1);
+
+		BUILD_BUG_ON(sizeof(struct xdp_umem_reg_v1) >= sizeof(struct xdp_umem_reg));
+
+		/* Make sure the last field of the struct doesn't have
+		 * uninitialized padding. All padding has to be explicit
+		 * and has to be set to zero by the userspace to make
+		 * struct xdp_umem_reg extensible in the future.
+		 */
+		BUILD_BUG_ON(offsetof(struct xdp_umem_reg, tx_metadata_len) +
+			     sizeof_field(struct xdp_umem_reg, tx_metadata_len) !=
+			     sizeof(struct xdp_umem_reg));
 
 		if (copy_from_sockptr(&mr, optval, mr_size))
 			return -EFAULT;