From nobody Thu Apr 2 17:24:23 2026 Received: from mail-oo1-f46.google.com (mail-oo1-f46.google.com [209.85.161.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D6F3B258ED7 for ; Wed, 11 Feb 2026 15:06:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822393; cv=none; b=TquFMDbu0BllWfXdCQwkfK+g/6vmydy1HEKcM7DXVrDc31NYsuejuk3RXK9YH5WbE+A4A6u9nMO7t5sQYRmD+OoGbX2f0uGvoOYGyysmYF5iZNHnpkGoHoW57UUTvI8BcB4t8lk1T49uowAP09dNoi4wMw0oEPIfL7nuW9vEkd4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822393; c=relaxed/simple; bh=Ej9fl4mQZ69yctcVpf+b9hNDLVrExKQQtGnHwteAsA8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TpOc21ijzEW/Ls70XzhfSK/fGW9oDTwH/fA34KbOY1odS88i9wf+coPifVdvogOI9nQEvcS5DcwORvR2YyzxxsrcSae9bRMB2v5VuJ7YtoXWlaCfLbitYK/9dm9MG8qxtghDWt8BKEVtYHgW9Kug30pDuUmKdL84daN+owpGGvQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk; spf=pass smtp.mailfrom=kernel.dk; dkim=pass (2048-bit key) header.d=kernel-dk.20230601.gappssmtp.com header.i=@kernel-dk.20230601.gappssmtp.com header.b=ilZTz7FF; arc=none smtp.client-ip=209.85.161.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kernel.dk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel-dk.20230601.gappssmtp.com header.i=@kernel-dk.20230601.gappssmtp.com header.b="ilZTz7FF" Received: by mail-oo1-f46.google.com with SMTP id 006d021491bc7-6610d479194so1789359eaf.3 for ; Wed, 11 Feb 2026 07:06:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20230601.gappssmtp.com; s=20230601; t=1770822391; x=1771427191; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uY/NQ9xxRlpLelqZEjLTGgzE855U4ciw83F5DKXPts8=; b=ilZTz7FF8wxeS+aJhXnfLgNnLqJdubCfUeX8BJ/ShnWflwdb+9KKUKa8ovXxHmpBmZ 7OTanJbM7yBtq2iymuAW+IpqjZMAar8lyw1jpRwyejVrFbjYYy6QidhhICZnT7PJ7yoj SNbxB5tS5uCb5zv6JHuNwzPW32gzHWDhm3keftaK0TmHWYjlvaCMQwTYJYXAqGVGdx+D K+Lodj2QCEuPxtmuR13j1+9SndRv6jnzw+tj5dj5c3UOlegZ2evLy84G5h7bXKA98Nek wCBD+KBuZwErNU4vOgMRPwitZ3OeR63bPPCnjSN/lOITwiOarCYtV5Q47DyDrBCXzPYH W6Qg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770822391; x=1771427191; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=uY/NQ9xxRlpLelqZEjLTGgzE855U4ciw83F5DKXPts8=; b=abB6f4yQ4u5w/S0c+dsc/5+KZFTEBaB04bKvPF2Y2d77oQhqQv9uZ7XRA44qvs2+Pn mvetSiMPdUiM2f3xCx+GZd1L4VtIQdM3fCxU2Y/oTOp2/kxXU9acvRRoe5UwU3Ea4k8a NDOZWOm72DToNfjXhqvDgehaIMhQ0pJZ7/Fd88VJ3h161bg8s+Y6DVQPZ2cjoHHQqHao I3/WulXzD38g93c/u8fKp3E1kG7uxONi32DI0ucYUZmjxAIfR2DPbGxcaaR0sUwOmi2G NTdImm1g4FIvlMs+sT6Lm05g8y+qyJ94NHMfMP0XcBrchwBQaxU6B3rPdbRGz4K5Sbtu ahBw== X-Forwarded-Encrypted: i=1; AJvYcCXgFp6Du8lcHnnNGvHBqgq2G26YilQvuXcRfUlcdFwkG05aAdlwgbm3HRAdMs60iF7QReprmg27ZhiDgi0=@vger.kernel.org X-Gm-Message-State: AOJu0YypGd9SMH+7bULbtV/X8jOYp4yp2X1Xs28p0u3lj1//vr8J/FY9 318t8J9FEWsZ2+/RGgMgej9bc5bqJ+FWK/0lJjcEkxZsIjvpTn10EEdxufbpIxntO2cXmUBziUO Y5uj9jUI= X-Gm-Gg: AZuq6aI0F9C8/pi0Y/dLRH2VxjiqN/ChEtkah5QyjDYFobm/tdwXR+WLo1OoxaSbPlZ /Ft0G/64Nl1B1UrElKTHQ6ugvMWlF1+/7CBMdShpxkP8kgasNR4wPVINL7vs7e2fe9k4qARDOaV /ckkTharpvDubQWjRLEmNz4jzBq/8aGoj5fopGlXS028PDl4I2aCACqXwkwbmx1gczgKqVVSBMB aWQwMmJeg+0ERRwktullATZwJNxV+1/89fGBeyNE8f8c9AA4jM82M1g0Z5zNCjtaQU7l5vtQmze 8toeeTIged8LAuVMtb4rJpmfsfV2AFCpV0cp7hhVJXIJ6ukvilfCXyeyUsxDh7jNBNqSzP4x5Kf dSaIf0fwr5cR6fEyT9kONvqAQiTK3BgwikiZOZ/gSrfIiJOxeKxSRmy7w+dkxb95yG3AaX9TnwH F6ldTJ2P9amoQdJAh8ZTSkcGRuC/GQ1nhrgA9lZpq/TGR7sKaVBcbxoNqRGZocXk8TIYHv X-Received: by 2002:a05:6820:1808:b0:662:c6f1:9231 with SMTP id 006d021491bc7-67437d6da96mr1352432eaf.4.1770822390621; Wed, 11 Feb 2026 07:06:30 -0800 (PST) Received: from m2max ([198.8.77.157]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-40eaf16c383sm1462414fac.14.2026.02.11.07.06.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Feb 2026 07:06:29 -0800 (PST) From: Jens Axboe To: io-uring@vger.kernel.org Cc: brauner@kernel.org, linux-kernel@vger.kernel.org, Jens Axboe Subject: [PATCH 1/2] io_uring/bpf_filter: move filter size and populate helper into struct Date: Wed, 11 Feb 2026 08:01:17 -0700 Message-ID: <20260211150626.136826-2-axboe@kernel.dk> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260211150626.136826-1-axboe@kernel.dk> References: <20260211150626.136826-1-axboe@kernel.dk> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rather than open-code this logic in io_uring_populate_bpf_ctx() with a switch, move it to the issue side definitions. Outside of making this easier to extend in the future, it's also a prep patch for using the pdu size for a given opcode filter elsewhere. Signed-off-by: Jens Axboe Reviewed-by: Christian Brauner --- io_uring/bpf_filter.c | 17 ++++++----------- io_uring/opdef.c | 6 ++++++ io_uring/opdef.h | 6 ++++++ 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/io_uring/bpf_filter.c b/io_uring/bpf_filter.c index 3816883a45ed..8ac7d06de122 100644 --- a/io_uring/bpf_filter.c +++ b/io_uring/bpf_filter.c @@ -26,6 +26,8 @@ static const struct io_bpf_filter dummy_filter; static void io_uring_populate_bpf_ctx(struct io_uring_bpf_ctx *bctx, struct io_kiocb *req) { + const struct io_issue_def *def =3D &io_issue_defs[req->opcode]; + bctx->opcode =3D req->opcode; bctx->sqe_flags =3D (__force int) req->flags & SQE_VALID_FLAGS; bctx->user_data =3D req->cqe.user_data; @@ -34,19 +36,12 @@ static void io_uring_populate_bpf_ctx(struct io_uring_b= pf_ctx *bctx, sizeof(*bctx) - offsetof(struct io_uring_bpf_ctx, pdu_size)); =20 /* - * Opcodes can provide a handler fo populating more data into bctx, + * Opcodes can provide a handler for populating more data into bctx, * for filters to use. */ - switch (req->opcode) { - case IORING_OP_SOCKET: - bctx->pdu_size =3D sizeof(bctx->socket); - io_socket_bpf_populate(bctx, req); - break; - case IORING_OP_OPENAT: - case IORING_OP_OPENAT2: - bctx->pdu_size =3D sizeof(bctx->open); - io_openat_bpf_populate(bctx, req); - break; + if (def->filter_pdu_size) { + bctx->pdu_size =3D def->filter_pdu_size; + def->filter_populate(bctx, req); } } =20 diff --git a/io_uring/opdef.c b/io_uring/opdef.c index df52d760240e..91a23baf415e 100644 --- a/io_uring/opdef.c +++ b/io_uring/opdef.c @@ -221,8 +221,10 @@ const struct io_issue_def io_issue_defs[] =3D { .issue =3D io_fallocate, }, [IORING_OP_OPENAT] =3D { + .filter_pdu_size =3D sizeof_field(struct io_uring_bpf_ctx, open), .prep =3D io_openat_prep, .issue =3D io_openat, + .filter_populate =3D io_openat_bpf_populate, }, [IORING_OP_CLOSE] =3D { .prep =3D io_close_prep, @@ -309,8 +311,10 @@ const struct io_issue_def io_issue_defs[] =3D { #endif }, [IORING_OP_OPENAT2] =3D { + .filter_pdu_size =3D sizeof_field(struct io_uring_bpf_ctx, open), .prep =3D io_openat2_prep, .issue =3D io_openat2, + .filter_populate =3D io_openat_bpf_populate, }, [IORING_OP_EPOLL_CTL] =3D { .unbound_nonreg_file =3D 1, @@ -406,8 +410,10 @@ const struct io_issue_def io_issue_defs[] =3D { [IORING_OP_SOCKET] =3D { .audit_skip =3D 1, #if defined(CONFIG_NET) + .filter_pdu_size =3D sizeof_field(struct io_uring_bpf_ctx, socket), .prep =3D io_socket_prep, .issue =3D io_socket, + .filter_populate =3D io_socket_bpf_populate, #else .prep =3D io_eopnotsupp_prep, #endif diff --git a/io_uring/opdef.h b/io_uring/opdef.h index aa37846880ff..faf3955dce8b 100644 --- a/io_uring/opdef.h +++ b/io_uring/opdef.h @@ -2,6 +2,8 @@ #ifndef IOU_OP_DEF_H #define IOU_OP_DEF_H =20 +struct io_uring_bpf_ctx; + struct io_issue_def { /* needs req->file assigned */ unsigned needs_file : 1; @@ -33,8 +35,12 @@ struct io_issue_def { /* size of async data needed, if any */ unsigned short async_size; =20 + /* bpf filter pdu size, if any */ + unsigned short filter_pdu_size; + int (*issue)(struct io_kiocb *, unsigned int); int (*prep)(struct io_kiocb *, const struct io_uring_sqe *); + void (*filter_populate)(struct io_uring_bpf_ctx *, struct io_kiocb *); }; =20 struct io_cold_def { --=20 2.51.0 From nobody Thu Apr 2 17:24:23 2026 Received: from mail-ot1-f68.google.com (mail-ot1-f68.google.com [209.85.210.68]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0467C2877FA for ; Wed, 11 Feb 2026 15:06:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.68 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822394; cv=none; b=Nivigix/gi0ETmU5DpqBJ24YLk8iX7ZWPvffu1nnuq9bjKoorMcEwq0SPWigIC7FV8wJqlDEZ6rbWc2q3HNhmAz5ds+UMQbT1y5SMhMIhVvoRPMafp+TxE/jSpl1oKNnp/kQIlOD1f3mvBOl4HMzvWov3ufUqB4F41t6QIBsPug= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822394; c=relaxed/simple; bh=Ur2H12Ua9CNNew448/VtMyv9yqavPoVJsazEl9i/oiQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pJSmqLK1aBtqd8l5f32rG9E8dymn/uTeQ6M4VPMHUNIlsIcPYe14SME+tcHFhXjNx4QHJFew2AZzui7aNQQ+OyyiGK/UHNeNZnz/XTFWewWu3Lexx1BQuNAToAgJ90udDmQiN5VehA2ds7TXScZTU0ajUzy/GKkwdwvpVKSU6MQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk; spf=pass smtp.mailfrom=kernel.dk; dkim=pass (2048-bit key) header.d=kernel-dk.20230601.gappssmtp.com header.i=@kernel-dk.20230601.gappssmtp.com header.b=YuXaFKeR; arc=none smtp.client-ip=209.85.210.68 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kernel.dk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel-dk.20230601.gappssmtp.com header.i=@kernel-dk.20230601.gappssmtp.com header.b="YuXaFKeR" Received: by mail-ot1-f68.google.com with SMTP id 46e09a7af769-7d19bfe1190so1747698a34.1 for ; Wed, 11 Feb 2026 07:06:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20230601.gappssmtp.com; s=20230601; t=1770822392; x=1771427192; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=IcnQ81G+uIBrhVGOF+QN/9Ez3LBo5RRyKc7qQzoeHh8=; b=YuXaFKeRe6L4IgJrfthsEAZp/iU74jQxcy4WZ5kqn+nSHiOrdMCTiC1wHU0H3j3nZ1 O7fgHrNIqXINWwcZfMKO7LF+Fb1a59HbE/S6giHf/7sOKSf6yu3wdiizyxAodGirDRVI GIvqBieTxsx9RfJFL/BqhB+cClmlTLB8xsTiYIe9sJZiaDkaZ9ijtebMuARwfN/aI+pl 9+wBfC1WCcdact2qw9TRcjALamakYmIqD8dxnVcHlaEHDHbMUkgYMU4Y23fUDFVxy2nM yI5V98cLK8DNBBnRSWIaP0NXOPZriK0FaqUy4p3mveeecJnY1OX7uQRqCF2+dcmPWvFK D+sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770822392; x=1771427192; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=IcnQ81G+uIBrhVGOF+QN/9Ez3LBo5RRyKc7qQzoeHh8=; b=JA+oveBxIvPgq63LaNOqkSggFEYEG1hPIE1j1i0SVyvMWn3Be/N2Z2jks1j4FKNJCF N8U4lNX3x2Czrsx69H/S+WedOiLwT7A0phAauR0RuEpeKsbahbJkJfRlxcAz/sIBHBf5 YATJotSNMLqtgzZznOrjEoiea2OuzUcq4Vnc5zwwTm3MMXWo2wv3RpyCEhAzagvc0U2B HqA2xixnJWUZdYhnnXLvi4VpNH0RyIqerEgVQq17GJl3SUwGJGCevlzGMQVp2QbBVkoa fWxMuw/78Z44KAChafdtj6Kqp7gtA7qRmWjov8A0lB79eiNxKixpgEzo7tYG0UXyOLdt aA8w== X-Forwarded-Encrypted: i=1; AJvYcCWujZwU9NKYajmeNz/tOTTRzNzz+NhJZoEAuntpXafMVlQsMZmyRksiD7HeO37Jj7f7lKYKYCpx06oIjnc=@vger.kernel.org X-Gm-Message-State: AOJu0YwCXGbe+g6E8Nsd0JpWxhaPK9XV6Ssc/4rh0vtF7ufGWaP9M/nq c8dlS8TLNWwxAluvyQfUIYV4Cv8gvIFBb7inQ1x3A/AnJAMXYA/USVBJCCma/ew/2JU= X-Gm-Gg: AZuq6aIMESZ2j8c4OAG5FG+MwgzHsQu5JMWWfDbunnhmB16Wiv250bX/f5nYSd8RfFm 9mLXMZTpagwlddOF0IJtVG8yLlAcyDHGD8jhzZTYoPF1RNQ4nmwgtvFP4VG6zUdezwb9YDJAZ2n pIYXFlcCOzchBH+dfyEZyPRXldKsViYnusi9SU1BIcLVU8fXo/Z5cHih1IY0nJC69Ly3gVXvI2C x+abO3YkHpTybKEZBbAazDfwm6LyGuBOZH4Kuo4DcsADe0sR0PUMBOzWIgYMjJQdvdUdRfCOUi8 e5D/wJF1+uO86Z1r5N3PD1PvF1cDnscCq/euJcSiPVNZ+bjtJKUIL8Br6bHmInaoL+Aeu+NCpLj 4G5abW5M854DqZ2LaLi0t+qDerIK+C2vvbwOo6nseBE13X9UXrUuDk7CFrlpSWemSMGNrVpY4+A pnMBkF8SEQCWGbrIz4I5Ji77hMmo9tO90HMjWKlRhmrBBYCEeYZJsDXXjn6o+Le9sKB3qh X-Received: by 2002:a05:6830:638a:b0:7c6:d0b2:8eb6 with SMTP id 46e09a7af769-7d464411072mr11742100a34.15.1770822391952; Wed, 11 Feb 2026 07:06:31 -0800 (PST) Received: from m2max ([198.8.77.157]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-40eaf16c383sm1462414fac.14.2026.02.11.07.06.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Feb 2026 07:06:31 -0800 (PST) From: Jens Axboe To: io-uring@vger.kernel.org Cc: brauner@kernel.org, linux-kernel@vger.kernel.org, Jens Axboe Subject: [PATCH 2/2] io_uring/bpf_filter: pass in expected filter payload size Date: Wed, 11 Feb 2026 08:01:18 -0700 Message-ID: <20260211150626.136826-3-axboe@kernel.dk> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260211150626.136826-1-axboe@kernel.dk> References: <20260211150626.136826-1-axboe@kernel.dk> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" It's quite possible that opcodes that have payloads attached to them, like IORING_OP_OPENAT/OPENAT2 or IORING_OP_SOCKET, that these paylods can change over time. For example, on the openat/openat2 side, the struct open_how argument is extensible, and could be extended in the future to allow further arguments to be passed in. Allow registration of a cBPF filter to give the size of the filter as seen by userspace. If that filter is for an opcode that takes extra payload data, allow it if the application payload expectation is the same size than the kernels. If that is the case, the kernel supports filtering on the payload that the application expects. If the size differs, the behavior depends on the IO_URING_BPF_FILTER_SZ_STRICT flag: 1) If IO_URING_BPF_FILTER_SZ_STRICT is set and the size expectation differs, fail the attempt to load the filter. 2) If IO_URING_BPF_FILTER_SZ_STRICT isn't set, allow the filter if the userspace pdu size is smaller than what the kernel offers. 3) Regardless if IO_URING_BPF_FILTER_SZ_STRICT, fail loading the filter if the userspace pdu size is bigger than what the kernel supports. An attempt to load a filter due to sizing will error with -EMSGSIZE. For that error, the registration struct will have filter->pdu_size populated with the pdu size that the kernel uses. Reported-by: Christian Brauner Signed-off-by: Jens Axboe Reviewed-by: Christian Brauner --- include/uapi/linux/io_uring/bpf_filter.h | 8 ++- io_uring/bpf_filter.c | 65 ++++++++++++++++++------ 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/include/uapi/linux/io_uring/bpf_filter.h b/include/uapi/linux/= io_uring/bpf_filter.h index 220351b81bc0..1b461d792a7b 100644 --- a/include/uapi/linux/io_uring/bpf_filter.h +++ b/include/uapi/linux/io_uring/bpf_filter.h @@ -35,13 +35,19 @@ enum { * If set, any currently unset opcode will have a deny filter attached */ IO_URING_BPF_FILTER_DENY_REST =3D 1, + /* + * If set, if kernel and application don't agree on pdu_size for + * the given opcode, fail the registration of the filter. + */ + IO_URING_BPF_FILTER_SZ_STRICT =3D 2, }; =20 struct io_uring_bpf_filter { __u32 opcode; /* io_uring opcode to filter */ __u32 flags; __u32 filter_len; /* number of BPF instructions */ - __u32 resv; + __u8 pdu_size; /* expected pdu size for opcode */ + __u8 resv[3]; __u64 filter_ptr; /* pointer to BPF filter */ __u64 resv2[5]; }; diff --git a/io_uring/bpf_filter.c b/io_uring/bpf_filter.c index 8ac7d06de122..4e1dd955c8c4 100644 --- a/io_uring/bpf_filter.c +++ b/io_uring/bpf_filter.c @@ -308,36 +308,69 @@ static struct io_bpf_filters *io_bpf_filter_cow(struc= t io_restriction *src) return ERR_PTR(-EBUSY); } =20 -#define IO_URING_BPF_FILTER_FLAGS IO_URING_BPF_FILTER_DENY_REST +#define IO_URING_BPF_FILTER_FLAGS (IO_URING_BPF_FILTER_DENY_REST | \ + IO_URING_BPF_FILTER_SZ_STRICT) =20 -int io_register_bpf_filter(struct io_restriction *res, - struct io_uring_bpf __user *arg) +static int io_bpf_filter_import(struct io_uring_bpf *reg, + struct io_uring_bpf __user *arg) { - struct io_bpf_filters *filters, *old_filters =3D NULL; - struct io_bpf_filter *filter, *old_filter; - struct io_uring_bpf reg; - struct bpf_prog *prog; - struct sock_fprog fprog; + const struct io_issue_def *def; int ret; =20 - if (copy_from_user(®, arg, sizeof(reg))) + if (copy_from_user(reg, arg, sizeof(*reg))) return -EFAULT; - if (reg.cmd_type !=3D IO_URING_BPF_CMD_FILTER) + if (reg->cmd_type !=3D IO_URING_BPF_CMD_FILTER) return -EINVAL; - if (reg.cmd_flags || reg.resv) + if (reg->cmd_flags || reg->resv) return -EINVAL; =20 - if (reg.filter.opcode >=3D IORING_OP_LAST) + if (reg->filter.opcode >=3D IORING_OP_LAST) return -EINVAL; - if (reg.filter.flags & ~IO_URING_BPF_FILTER_FLAGS) + if (reg->filter.flags & ~IO_URING_BPF_FILTER_FLAGS) return -EINVAL; - if (reg.filter.resv) + if (!mem_is_zero(reg->filter.resv, sizeof(reg->filter.resv))) return -EINVAL; - if (!mem_is_zero(reg.filter.resv2, sizeof(reg.filter.resv2))) + if (!mem_is_zero(reg->filter.resv2, sizeof(reg->filter.resv2))) return -EINVAL; - if (!reg.filter.filter_len || reg.filter.filter_len > BPF_MAXINSNS) + if (!reg->filter.filter_len || reg->filter.filter_len > BPF_MAXINSNS) return -EINVAL; =20 + /* Verify filter size */ + def =3D &io_issue_defs[reg->filter.opcode]; + + /* same size, always ok */ + ret =3D 0; + if (reg->filter.pdu_size =3D=3D def->filter_pdu_size) + ; + /* size differs, fail in strict mode */ + else if (reg->filter.flags & IO_URING_BPF_FILTER_SZ_STRICT) + ret =3D -EMSGSIZE; + /* userspace filter is bigger, always disallow */ + else if (reg->filter.pdu_size > def->filter_pdu_size) + ret =3D -EMSGSIZE; + + /* copy back kernel filter size */ + reg->filter.pdu_size =3D def->filter_pdu_size; + if (copy_to_user(&arg->filter, ®->filter, sizeof(reg->filter))) + return -EFAULT; + + return ret; +} + +int io_register_bpf_filter(struct io_restriction *res, + struct io_uring_bpf __user *arg) +{ + struct io_bpf_filters *filters, *old_filters =3D NULL; + struct io_bpf_filter *filter, *old_filter; + struct io_uring_bpf reg; + struct bpf_prog *prog; + struct sock_fprog fprog; + int ret; + + ret =3D io_bpf_filter_import(®, arg); + if (ret) + return ret; + fprog.len =3D reg.filter.filter_len; fprog.filter =3D u64_to_user_ptr(reg.filter.filter_ptr); =20 --=20 2.51.0