* [PATCH v14 14/15] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING
From: Chuck Lever @ 2026-05-07 8:53 UTC (permalink / raw)
To: Al Viro, Christian Brauner, Jan Kara
Cc: linux-fsdevel, linux-ext4, linux-xfs, linux-cifs, linux-nfs,
linux-api, linux-f2fs-devel, hirofumi, linkinjeon, sj1557.seo,
yuezhang.mo, almaz.alexandrovich, slava, glaubitz, frank.li,
tytso, adilger.kernel, cem, sfrench, pc, ronniesahlberg, sprasad,
trondmy, anna, jaegeuk, chao, hansg, senozhatsky, Chuck Lever,
Roland Mainz
In-Reply-To: <20260507-case-sensitivity-v14-0-e62cc8200435@oracle.com>
From: Chuck Lever <chuck.lever@oracle.com>
NFSD currently provides NFSv4 clients with hard-coded responses
indicating all exported filesystems are case-sensitive and
case-preserving. This is incorrect for case-insensitive filesystems
and ext4 directories with casefold enabled.
Query the underlying filesystem's actual case sensitivity via
nfsd_get_case_info() and return accurate values to clients. This
supports per-directory settings for filesystems that allow mixing
case-sensitive and case-insensitive directories within an export.
The helper queries the parent dentry for non-directory filehandles
because case-folding is a per-directory property. That resolution
has the same corner cases here as for NFSv3 PATHCONF: single-file
exports query an unexported parent, disconnected dentries report
defaults until reconnected, and hardlinked files track whichever
alias the dcache currently holds.
Reviewed-by: Roland Mainz <roland.mainz@nrubsig.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfsd/nfs4xdr.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 49 insertions(+), 3 deletions(-)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 2a0946c630e1..319007b79d49 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3158,6 +3158,8 @@ struct nfsd4_fattr_args {
u32 rdattr_err;
bool contextsupport;
bool ignore_crossmnt;
+ bool case_insensitive;
+ bool case_preserving;
};
typedef __be32(*nfsd4_enc_attr)(struct xdr_stream *xdr,
@@ -3356,6 +3358,33 @@ static __be32 nfsd4_encode_fattr4_acl(struct xdr_stream *xdr,
return nfs_ok;
}
+static __be32 nfsd4_encode_fattr4_case_insensitive(struct xdr_stream *xdr,
+ const struct nfsd4_fattr_args *args)
+{
+ return nfsd4_encode_bool(xdr, args->case_insensitive);
+}
+
+static __be32 nfsd4_encode_fattr4_case_preserving(struct xdr_stream *xdr,
+ const struct nfsd4_fattr_args *args)
+{
+ return nfsd4_encode_bool(xdr, args->case_preserving);
+}
+
+static __be32 nfsd4_encode_fattr4_homogeneous(struct xdr_stream *xdr,
+ const struct nfsd4_fattr_args *args)
+{
+ /*
+ * Casefold-capable filesystems (e.g. ext4 or f2fs with the
+ * casefold feature) attach a Unicode encoding at mount time
+ * but apply case folding per directory. The per-file-system
+ * case_insensitive and case_preserving values can therefore
+ * legitimately differ across objects that share the same fsid.
+ * Report FATTR4_HOMOGENEOUS = FALSE on such filesystems to
+ * keep that variation consistent with RFC 8881 Section 5.8.2.16.
+ */
+ return nfsd4_encode_bool(xdr, !sb_has_encoding(args->dentry->d_sb));
+}
+
static __be32 nfsd4_encode_fattr4_filehandle(struct xdr_stream *xdr,
const struct nfsd4_fattr_args *args)
{
@@ -3748,8 +3777,8 @@ static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_ops[] = {
[FATTR4_ACLSUPPORT] = nfsd4_encode_fattr4_aclsupport,
[FATTR4_ARCHIVE] = nfsd4_encode_fattr4__noop,
[FATTR4_CANSETTIME] = nfsd4_encode_fattr4__true,
- [FATTR4_CASE_INSENSITIVE] = nfsd4_encode_fattr4__false,
- [FATTR4_CASE_PRESERVING] = nfsd4_encode_fattr4__true,
+ [FATTR4_CASE_INSENSITIVE] = nfsd4_encode_fattr4_case_insensitive,
+ [FATTR4_CASE_PRESERVING] = nfsd4_encode_fattr4_case_preserving,
[FATTR4_CHOWN_RESTRICTED] = nfsd4_encode_fattr4__true,
[FATTR4_FILEHANDLE] = nfsd4_encode_fattr4_filehandle,
[FATTR4_FILEID] = nfsd4_encode_fattr4_fileid,
@@ -3758,7 +3787,7 @@ static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_ops[] = {
[FATTR4_FILES_TOTAL] = nfsd4_encode_fattr4_files_total,
[FATTR4_FS_LOCATIONS] = nfsd4_encode_fattr4_fs_locations,
[FATTR4_HIDDEN] = nfsd4_encode_fattr4__noop,
- [FATTR4_HOMOGENEOUS] = nfsd4_encode_fattr4__true,
+ [FATTR4_HOMOGENEOUS] = nfsd4_encode_fattr4_homogeneous,
[FATTR4_MAXFILESIZE] = nfsd4_encode_fattr4_maxfilesize,
[FATTR4_MAXLINK] = nfsd4_encode_fattr4_maxlink,
[FATTR4_MAXNAME] = nfsd4_encode_fattr4_maxname,
@@ -3968,6 +3997,23 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
args.fhp = tempfh;
} else
args.fhp = fhp;
+ if (attrmask[0] & (FATTR4_WORD0_CASE_INSENSITIVE |
+ FATTR4_WORD0_CASE_PRESERVING)) {
+ err = nfsd_get_case_info(dentry, &args.case_insensitive,
+ &args.case_preserving);
+ /*
+ * Per RFC 8881 Section 18.7.3, an attribute advertised
+ * in SUPPORTED_ATTRS must come back with a value or the
+ * GETATTR must fail. nfsd_get_case_info() fills POSIX
+ * defaults and returns -EOPNOTSUPP when the underlying
+ * filesystem does not expose case state; encode those
+ * defaults so the reply agrees with what SUPPORTED_ATTRS
+ * advertises. Other errors fail the operation as the
+ * spec requires.
+ */
+ if (err && err != -EOPNOTSUPP)
+ goto out_nfserr;
+ }
if (attrmask[0] & FATTR4_WORD0_ACL) {
err = nfsd4_get_nfs4_acl(rqstp, dentry, &args.acl);
--
2.53.0
^ permalink raw reply related
* [PATCH v14 15/15] ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION
From: Chuck Lever @ 2026-05-07 8:53 UTC (permalink / raw)
To: Al Viro, Christian Brauner, Jan Kara
Cc: linux-fsdevel, linux-ext4, linux-xfs, linux-cifs, linux-nfs,
linux-api, linux-f2fs-devel, hirofumi, linkinjeon, sj1557.seo,
yuezhang.mo, almaz.alexandrovich, slava, glaubitz, frank.li,
tytso, adilger.kernel, cem, sfrench, pc, ronniesahlberg, sprasad,
trondmy, anna, jaegeuk, chao, hansg, senozhatsky, Chuck Lever,
Roland Mainz
In-Reply-To: <20260507-case-sensitivity-v14-0-e62cc8200435@oracle.com>
From: Chuck Lever <chuck.lever@oracle.com>
FS_ATTRIBUTE_INFORMATION responses have always reported
FILE_CASE_SENSITIVE_SEARCH and FILE_CASE_PRESERVED_NAMES
unconditionally. Case-insensitive filesystems like exFAT, and
casefolded directories on ext4 or f2fs, have no way to signal
their actual semantics to SMB clients.
Now that filesystems expose case behavior through ->fileattr_get,
query it via vfs_fileattr_get() and translate the FS_XFLAG_CASEFOLD
and FS_XFLAG_CASENONPRESERVING flags into the corresponding SMB
attributes. Filesystems without ->fileattr_get continue reporting
default POSIX behavior (case-sensitive, case-preserving).
SMB's FS_ATTRIBUTE_INFORMATION reports per-share attributes from
the share root, not per-file. Shares mixing casefold and
non-casefold directories report the root directory's behavior.
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Reviewed-by: Roland Mainz <roland.mainz@nrubsig.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/smb/server/smb2pdu.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index ee32e61b6d3c..cf0bc453a036 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -14,6 +14,7 @@
#include <linux/falloc.h>
#include <linux/mount.h>
#include <linux/filelock.h>
+#include <linux/fileattr.h>
#include "glob.h"
#include "smbfsctl.h"
@@ -5541,16 +5542,33 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
case FS_ATTRIBUTE_INFORMATION:
{
FILE_SYSTEM_ATTRIBUTE_INFO *info;
+ struct file_kattr fa = {};
size_t sz;
+ u32 attrs;
+ int err;
info = (FILE_SYSTEM_ATTRIBUTE_INFO *)rsp->Buffer;
- info->Attributes = cpu_to_le32(FILE_SUPPORTS_OBJECT_IDS |
- FILE_PERSISTENT_ACLS |
- FILE_UNICODE_ON_DISK |
- FILE_CASE_PRESERVED_NAMES |
- FILE_CASE_SENSITIVE_SEARCH |
- FILE_SUPPORTS_BLOCK_REFCOUNTING);
+ attrs = FILE_SUPPORTS_OBJECT_IDS |
+ FILE_PERSISTENT_ACLS |
+ FILE_UNICODE_ON_DISK |
+ FILE_SUPPORTS_BLOCK_REFCOUNTING;
+ err = vfs_fileattr_get(path.dentry, &fa);
+ /*
+ * -EINVAL, -EOPNOTSUPP: ntfs-3g and other FUSE
+ * filesystems that lack FS_IOC_FSGETXATTR support.
+ */
+ if (err && err != -ENOIOCTLCMD && err != -ENOTTY &&
+ err != -EINVAL && err != -EOPNOTSUPP) {
+ path_put(&path);
+ return err;
+ }
+ if (!(fa.fsx_xflags & FS_XFLAG_CASEFOLD))
+ attrs |= FILE_CASE_SENSITIVE_SEARCH;
+ if (!(fa.fsx_xflags & FS_XFLAG_CASENONPRESERVING))
+ attrs |= FILE_CASE_PRESERVED_NAMES;
+
+ info->Attributes = cpu_to_le32(attrs);
info->Attributes |= cpu_to_le32(server_conf.share_fake_fscaps);
if (test_share_config_flag(work->tcon->share_conf,
--
2.53.0
^ permalink raw reply related
* Re: [PATCH] crypto: af_alg - Document the deprecation of AF_ALG
From: Kamran Khan @ 2026-05-10 15:54 UTC (permalink / raw)
To: Jeff Barnes, Andy Lutomirski
Cc: Eric Biggers, linux-crypto@vger.kernel.org, Herbert Xu,
linux-doc@vger.kernel.org, linux-api@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Linus Torvalds
In-Reply-To: <14A441D8-5370-44BE-8732-99BF8107C3FD@getmailspring.com>
Hi,
AF_ALG is useful not just for hardware-offloading, but also for memory
isolation so that applications only get oracle access to the crypto keys
and a memory-safety vulnerability in user applications would not
immediately put the secret key material at risk.
I understand and appreciate the concern with complex attack surface and
the increased frequency of attacks in this area. But I fear that
completely removing AF_ALG increases the risk for userspace applications
relying on it for memory isolation.
What alternatives do userspace applications have on Linux for ensuring
crypto keys are not exposed in user memory? That is, FreeBSD and NetBSD
natively provide /dev/crypto; removing AF_ALG would kill the only
equivalent option on the Linux side for kernel-delegated cryptography.
Thanks,
Kamran.
On 5/6/26 7:42 AM, Jeff Barnes wrote:
> Hi,
>
> On May 5 2026, at 7:17 pm, Andy Lutomirski <luto@amacapital.net> wrote:
>
>>> On Apr 29, 2026, at 6:19 PM, Eric Biggers <ebiggers@kernel.org> wrote:
>>>
>>> AF_ALG is almost completely unnecessary, and it exposes a massive attack
>>> surface that hasn't been standing up to modern vulnerability discovery
>>> tools. The latest one even has its own website, providing a small
>>> Python script that reliably roots most Linux distros: https://copy.fail/
>>
>> How about adding a configuration option, defaulted on, that requires
>> capable(CAP_SYS_ADMIN) to create the socket (and maybe also to bind /
>> connect it). And a sysctl to allow the administrator to override this
>> in the unlikely event that it’s needed.
>>
>> IIRC cryptsetup used to and maybe even still does require these
>> sockets sometimes and this would let it keep working. And there's all
>> the FIPS stuff downthread.
>
> Apologize in advance for the long-winded answer.
>
> The "FIPS stuff" centers on using sha512hmac -> libkcapi -> AF_ALG for
> verifying integrity. The early‑boot sha512hmac check that some
> distributions use (typically from initramfs) sits at an awkward
> intersection of multiple standards, and it may help to clarify where it
> actually fits and where it doesn't.
>
> From a standards perspective, FIPS 140‑3 requires a cryptographic module
> to perform self‑integrity verification using an approved algorithm and
> to prevent the module from entering an operational state on failure. In
> the Linux kernel, the cryptographic module is the kernel crypto
> subsystem, and these requirements are met by the kernel’s internal
> power‑up self‑tests (KATs, etc.) on the crypto code and critical data as
> loaded into memory.
>
> FIPS 199 / SP 800‑53 (e.g., SI‑7) impose system‑level integrity
> requirements (for Moderate impact systems), i.e., that unauthorized
> modification of critical components is prevented or detected and that
> failures result in a protective action. These controls are explicitly
> technology‑agnostic and are not limited to cryptographic‑module self‑tests.
>
> The sha512hmac check is not the FIPS 140‑3 cryptographic‑module
> self‑integrity test. Instead, it has historically been used as a system
> integrity control that provides auditors with assurance that the kernel
> image containing the cryptographic module has not been modified prior to
> execution, and that a failure will halt the boot.
>
> Although FIPS 140‑3 does not mandate an HMAC over the kernel image, the
> early‑boot HMAC became an accepted evidence pattern for satisfying
> system‑integrity expectations (FIPS 199 / SI‑7) alongside a kernel
> crypto validation. This is why it is often perceived as “required” for
> FIPS submissions, even though it is not normatively required by
> FIPS 140‑3 itself.
>
> With the deprecation/removal of AF_ALG for this use case, there is no
> longer a supported way to perform an early‑boot, userspace‑driven HMAC
> using validated kernel crypto without introducing circular dependencies
> (e.g., relying on userspace crypto before crypto self‑tests complete).
> As a result, there is no drop‑in replacement for sha512hmac that
> preserves all of its historical properties.
>
> This is a new development that challenges a long‑standing assumption:
> that system‑integrity evidence and cryptographic‑module self‑integrity
> can be cleanly separated while still being demonstrated by a single
> early‑boot mechanism. That assumption no longer holds given proposed
> kernel interfaces.
>
> A more accurate decomposition (and one that aligns with the intent of
> the standards) is to separate integrity enforcement by system phase.
>
> 1. Secure Boot (or equivalent platform verification) ensures that a
> modified kernel image is not executed at all. This satisfies the
> requirement that critical components are not loaded in a modified state
> and that integrity failure results in a protective action (boot prevention).
>
> 2. IMA (with appraisal and enforcement) ensures that modified
> executables, modules, or firmware cannot be loaded or executed once the
> kernel is running.
>
> 3. Kernel crypto self‑tests continue to satisfy FIPS 140‑3
> self‑integrity requirements independently of the above.
>
> Taken together, Secure Boot + IMA provide continuous system‑integrity
> enforcement without re‑introducing early‑boot HMACs or AF_ALG
> dependencies, while keeping cryptographic‑module self‑integrity
> correctly scoped to the kernel crypto subsystem.
>
> The transition away from sha512hmac is therefore not a removal of
> integrity enforcement, but a shift from a single, early‑boot mechanism
> to a phased integrity model that better reflects the separation of
> concerns already present in the standards — even though this separation
> was previously masked by the hacky HMAC approach.
>
> This change will require updated documentation and auditor education,
> but it reflects the current technical reality and avoids perpetuating an
> interface that no longer has a sustainable implementation path.
>
>>
>>
>>>
>>> This isn't sustainable, especially as LLMs have accelerated the rate the
>>> vulnerabilities are coming in. The effort that is being put into this
>>> thing is vastly disproportional to the few programs that actually use
>>> it, and those programs would be better served by userspace code anyway.
>>>
>>> These issues have been noted in many mailing list discussions already.
>>> But until now they haven't been reflected in the documentation or
>>> kconfig menu itself, and the vulnerabilities are still coming in.
>>>
>>> Let's go ahead and document the deprecation.
>>>
>>> This isn't intended to change anything overnight. After all, most Linux
>>> distros won't be able to disable the kconfig options quite yet, mainly
>>> because of iwd. But this should create a bit more impetus for these
>>> userspace programs to be fixed, and the documentation update should also
>>> help prevent more users from appearing.
>>>
>>> Signed-off-by: Eric Biggers <ebiggers@kernel.org>
>>> ---
>>>
>>> This patch is targeting crypto/master
>>>
>>> Documentation/crypto/userspace-if.rst | 82 ++++++++++++++++++++-------
>>> crypto/Kconfig | 69 ++++++++++++++++------
>>> 2 files changed, 113 insertions(+), 38 deletions(-)
>>>
>>> diff --git a/Documentation/crypto/userspace-if.rst b/Documentation/crypto/userspace-if.rst
>>> index 021759198fe7..c39f5c79a5b7 100644
>>> --- a/Documentation/crypto/userspace-if.rst
>>> +++ b/Documentation/crypto/userspace-if.rst
>>> @@ -2,30 +2,72 @@ User Space Interface
>>> ====================
>>>
>>> Introduction
>>> ------------
>>>
>>> -The concepts of the kernel crypto API visible to kernel space is fully
>>> -applicable to the user space interface as well. Therefore, the kernel
>>> -crypto API high level discussion for the in-kernel use cases applies
>>> -here as well.
>>> -
>>> -The major difference, however, is that user space can only act as a
>>> -consumer and never as a provider of a transformation or cipher
>>> -algorithm.
>>> -
>>> -The following covers the user space interface exported by the kernel
>>> -crypto API. A working example of this description is libkcapi that can
>>> -be obtained from [1]. That library can be used by user space
>>> -applications that require cryptographic services from the kernel.
>>> -
>>> -Some details of the in-kernel kernel crypto API aspects do not apply to
>>> -user space, however. This includes the difference between synchronous
>>> -and asynchronous invocations. The user space API call is fully
>>> -synchronous.
>>> -
>>> -[1] https://www.chronox.de/libkcapi/index.html
>>> +AF_ALG provides unprivileged userspace programs access to arbitrary hash,
>>> +symmetric cipher, AEAD, and RNG algorithms that are implemented in kernel-mode
>>> +code.
>>> +
>>> +AF_ALG is insecure and is deprecated. Originally added to the kernel
>>> in 2010,
>>> +most kernel developers now consider it to be a mistake.
>>> +
>>> +AF_ALG continues to be supported only for backwards compatibility.
>>> On systems
>>> +where no programs using AF_ALG remain, the support for it should be
>>> disabled by
>>> +disabling ``CONFIG_CRYPTO_USER_API_*``.
>>> +
>>> +Deprecation
>>> +-----------
>>> +
>>> +AF_ALG was originally intended to provide userspace programs access
>>> to crypto
>>> +accelerators that they wouldn't otherwise have access to.
>>> +
>>> +However, that capability turned out to not be useful on very many
>>> systems. More
>>> +significantly, the actual implementation exposes a vastly greater
>>> amount of
>>> +functionality than that. It actually provides access to all software algorithms.
>>> +
>>> +This includes arbitrary compositions of different algorithms created
>>> via a
>>> +complex template system, as well as algorithms that only make sense
>>> as internal
>>> +implementation details of other algorithms. It also includes full zero-copy
>>> +support, which is difficult for the kernel to implement securely.
>>> +
>>> +Ultimately, these algorithms are just math computations. They use
>>> the same
>>> +instructions that userspace programs already have access to, just
>>> accessed in a
>>> +much more convoluted and less efficient way.
>>> +
>>> +Indeed, userspace code is nearly always what is being used anyway.
>>> These same
>>> +algorithms are widely implemented in userspace crypto libraries.
>>> +
>>> +Meanwhile, AF_ALG hasn't been withstanding modern vulnerability
>>> discovery tools
>>> +such as syzbot and large language models. It receives a steady
>>> stream of CVEs.
>>> +Some of the examples include:
>>> +
>>> +- CVE-2026-31677
>>> +- CVE-2026-31431 (https://copy.fail)
>>> +- CVE-2025-38079
>>> +- CVE-2025-37808
>>> +- CVE-2024-26824
>>> +- CVE-2022-48781
>>> +- CVE-2019-8912
>>> +- CVE-2018-14619
>>> +- CVE-2017-18075
>>> +- CVE-2017-17806
>>> +- CVE-2017-17805
>>> +- CVE-2016-10147
>>> +- CVE-2015-8970
>>> +- CVE-2015-3331
>>> +- CVE-2014-9644
>>> +- CVE-2013-7421
>>> +- CVE-2011-4081
>>> +
>>> +It is recommended that, whenever possible, userspace programs be
>>> migrated to
>>> +userspace crypto code (which again, is what is normally used anyway) and
>>> +``CONFIG_CRYPTO_USER_API_*`` be disabled. On systems that use
>>> SELinux, SELinux
>>> +can also be used to restrict the use of AF_ALG to trusted programs.
>>> +
>>> +The remainder of this documentation provides the historical
>>> documentation for
>>> +the deprecated AF_ALG interface.
>>>
>>> User Space API General Remarks
>>> ------------------------------
>>>
>>> The kernel crypto API is accessible from user space. Currently, the
>>> diff --git a/crypto/Kconfig b/crypto/Kconfig
>>> index 103d1f58cb7c..6cd1c478d4be 100644
>>> --- a/crypto/Kconfig
>>> +++ b/crypto/Kconfig
>>> @@ -1278,48 +1278,72 @@ config CRYPTO_DF80090A
>>> tristate
>>> select CRYPTO_AES
>>> select CRYPTO_CTR
>>>
>>> endmenu
>>> -menu "Userspace interface"
>>> +menu "Userspace interface (deprecated)"
>>>
>>> config CRYPTO_USER_API
>>> tristate
>>>
>>> config CRYPTO_USER_API_HASH
>>> - tristate "Hash algorithms"
>>> + tristate "Hash algorithms (deprecated)"
>>> depends on NET
>>> select CRYPTO_HASH
>>> select CRYPTO_USER_API
>>> help
>>> - Enable the userspace interface for hash algorithms.
>>> + Enable the AF_ALG userspace interface for hash algorithms. This
>>> + provides unprivileged userspace programs access to arbitrary hash
>>> + algorithms implemented in the kernel's privileged execution context.
>>>
>>> - See Documentation/crypto/userspace-if.rst and
>>> - https://www.chronox.de/libkcapi/html/index.html
>>> + This interface is deprecated and is supported only for backwards
>>> + compatibility. It regularly has vulnerabilities, and the capabilities
>>> + it provides are redundant with userspace crypto libraries.
>>> +
>>> + Enable this only if needed for support for a program that
>>> hasn't yet
>>> + been converted to userspace crypto, for example iwd.
>>> +
>>> + See also Documentation/crypto/userspace-if.rst
>>>
>>> config CRYPTO_USER_API_SKCIPHER
>>> - tristate "Symmetric key cipher algorithms"
>>> + tristate "Symmetric key cipher algorithms (deprecated)"
>>> depends on NET
>>> select CRYPTO_SKCIPHER
>>> select CRYPTO_USER_API
>>> help
>>> - Enable the userspace interface for symmetric key cipher algorithms.
>>> + Enable the AF_ALG userspace interface for symmetric key algorithms.
>>> + This provides unprivileged userspace programs access to arbitrary
>>> + symmetric key algorithms implemented in the kernel's privileged
>>> + execution context.
>>> +
>>> + This interface is deprecated and is supported only for backwards
>>> + compatibility. It regularly has vulnerabilities, and the capabilities
>>> + it provides are redundant with userspace crypto libraries.
>>> +
>>> + Enable this only if needed for support for a program that
>>> hasn't yet
>>> + been converted to userspace crypto, for example iwd, or cryptsetup
>>> + with certain algorithms.
>>>
>>> - See Documentation/crypto/userspace-if.rst and
>>> - https://www.chronox.de/libkcapi/html/index.html
>>> + See also Documentation/crypto/userspace-if.rst
>>>
>>> config CRYPTO_USER_API_RNG
>>> - tristate "RNG (random number generator) algorithms"
>>> + tristate "Random number generation algorithms (deprecated)"
>>> depends on NET
>>> select CRYPTO_RNG
>>> select CRYPTO_USER_API
>>> help
>>> - Enable the userspace interface for RNG (random number generator)
>>> - algorithms.
>>> + Enable the AF_ALG userspace interface for random number generation
>>> + (RNG) algorithms. This provides unprivileged userspace programs
>>> + access to arbitrary RNG algorithms implemented in the kernel's
>>> + privileged execution context.
>>>
>>> - See Documentation/crypto/userspace-if.rst and
>>> - https://www.chronox.de/libkcapi/html/index.html
>>> + This interface is deprecated and is supported only for backwards
>>> + compatibility. It regularly has vulnerabilities, and the capabilities
>>> + it provides are redundant with userspace crypto libraries as
>>> well as
>>> + the normal kernel RNG (e.g., /dev/urandom and getrandom(2)).
>>> +
>>> + See also Documentation/crypto/userspace-if.rst
>>>
>>> config CRYPTO_USER_API_RNG_CAVP
>>> bool "Enable CAVP testing of DRBG"
>>> depends on CRYPTO_USER_API_RNG && CRYPTO_DRBG
>>> help
>>> @@ -1330,20 +1354,29 @@ config CRYPTO_USER_API_RNG_CAVP
>>>
>>> This should only be enabled for CAVP testing. You should say
>>> no unless you know what this is.
>>>
>>> config CRYPTO_USER_API_AEAD
>>> - tristate "AEAD cipher algorithms"
>>> + tristate "AEAD cipher algorithms (deprecated)"
>>> depends on NET
>>> select CRYPTO_AEAD
>>> select CRYPTO_SKCIPHER
>>> select CRYPTO_USER_API
>>> help
>>> - Enable the userspace interface for AEAD cipher algorithms.
>>> + Enable the AF_ALG userspace interface for authenticated encryption
>>> + with associated data (AEAD) algorithms. This provides unprivileged
>>> + userspace programs access to arbitrary AEAD algorithms
>>> implemented in
>>> + the kernel's privileged execution context.
>>> +
>>> + This interface is deprecated and is supported only for backwards
>>> + compatibility. It regularly has vulnerabilities, and the capabilities
>>> + it provides are redundant with userspace crypto libraries.
>>> +
>>> + Enable this only if needed for support for a program that
>>> hasn't yet
>>> + been converted to userspace crypto, for example iwd.
>>>
>>> - See Documentation/crypto/userspace-if.rst and
>>> - https://www.chronox.de/libkcapi/html/index.html
>>> + See also Documentation/crypto/userspace-if.rst
>>>
>>> config CRYPTO_USER_API_ENABLE_OBSOLETE
>>> bool "Obsolete cryptographic algorithms"
>>> depends on CRYPTO_USER_API
>>> default y
>>>
>>> base-commit: 57b8e2d666a31fa201432d58f5fe3469a0dd83ba
>>> --
>>> 2.54.0
>>>
>>>
>>
>
^ permalink raw reply
* Re: [PATCH] crypto: af_alg - Document the deprecation of AF_ALG
From: Eric Biggers @ 2026-05-10 16:32 UTC (permalink / raw)
To: Kamran Khan
Cc: Jeff Barnes, Andy Lutomirski, linux-crypto@vger.kernel.org,
Herbert Xu, linux-doc@vger.kernel.org, linux-api@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Linus Torvalds
In-Reply-To: <0b8bba44-f6bb-4d69-b9d4-5787c276d41a@inspirated.com>
On Sun, May 10, 2026 at 08:54:07AM -0700, Kamran Khan wrote:
> Hi,
>
> AF_ALG is useful not just for hardware-offloading, but also for memory
> isolation so that applications only get oracle access to the crypto keys and
> a memory-safety vulnerability in user applications would not immediately put
> the secret key material at risk.
Note that if that memory-safety vulnerability leads to code execution in
the application, then it doesn't matter that it "only" has oracle
access. It can still decrypt any data encrypted by that key.
The relevant threat model would be arbitrary reads, not any
"memory-safety vulnerability".
> I understand and appreciate the concern with complex attack surface and the
> increased frequency of attacks in this area. But I fear that completely
> removing AF_ALG increases the risk for userspace applications relying on it
> for memory isolation.
>
> What alternatives do userspace applications have on Linux for ensuring
> crypto keys are not exposed in user memory? That is, FreeBSD and NetBSD
> natively provide /dev/crypto; removing AF_ALG would kill the only equivalent
> option on the Linux side for kernel-delegated cryptography.
The standard solution is simply to use an isolated userspace process
like ssh-agent. Yes, the keys will be in "user memory". But "not
exposed in user memory" is *not* a correct statement of the problem.
(Also note that protecting not-actively-in-use data from arbitrary read
primitives doesn't require cryptography at all. That can be done simply
by using mprotect() to remove read permission from the memory, then
temporarily adding it back when it needs to be accessed.)
In any case, any hypothetical security benefit provided by AF_ALG would
have to be *very high* to outweigh the continuous stream of
vulnerabilities in it. I understand that people using AF_ALG might not
be familiar with that continuous stream of vulnerabilities, but it would
be worth spending some time researching what has been going on.
- Eric
^ permalink raw reply
* Re: [PATCH] crypto: af_alg - Document the deprecation of AF_ALG
From: Andy Lutomirski @ 2026-05-10 18:06 UTC (permalink / raw)
To: Eric Biggers
Cc: Kamran Khan, Jeff Barnes, linux-crypto@vger.kernel.org,
Herbert Xu, linux-doc@vger.kernel.org, linux-api@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Linus Torvalds
In-Reply-To: <20260510163204.GA2279@sol>
On Sun, May 10, 2026 at 9:33 AM Eric Biggers <ebiggers@kernel.org> wrote:
> In any case, any hypothetical security benefit provided by AF_ALG would
> have to be *very high* to outweigh the continuous stream of
> vulnerabilities in it. I understand that people using AF_ALG might not
> be familiar with that continuous stream of vulnerabilities, but it would
> be worth spending some time researching what has been going on.
It would not be completely crazy to have a simple, straightforward
interface by which user code could ask the kernel to do a
cryptographic operation. Think:
int compute_keyed_hash(int key_fd, const void *data, size_t len);
where key_fd encodes both the key and the hash type (HMAC-SHA256 or
whatever), and there is a very, very small menu of hashes to choose
from.
But this is not really obviously worth the hassle. And AF_ALG is
definitely not the right interface.
^ permalink raw reply
* Re: [RFC PATCH v2 1/2] vfs: syscalls: add mkdirat2() that returns an O_DIRECTORY fd
From: Christian Brauner @ 2026-05-11 12:00 UTC (permalink / raw)
To: Jori Koolstra
Cc: Aleksa Sarai, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, Alexander Viro, Arnd Bergmann,
H . Peter Anvin, Jan Kara, Peter Zijlstra, Andrey Albershteyn,
Masami Hiramatsu, Jiri Olsa, Thomas Weißschuh,
Mathieu Desnoyers, cmirabil, Greg Kroah-Hartman, Jeff Layton,
linux-kernel, linux-fsdevel, linux-api, linux-arch
In-Reply-To: <1600596489.77018.1777916475931@kpc.webmail.kpnmail.nl>
On Mon, May 04, 2026 at 07:41:15PM +0200, Jori Koolstra wrote:
>
> > Op 27-04-2026 17:48 CEST schreef Christian Brauner <brauner@kernel.org>:
> >
> > So definitely a patchset worthing doing but this will be hairy. And
> > Mateusz is right. As written this doesn't work. The canonical pattern
> > how e.g., dentry_open() does it is to preallocate the file.
> >
>
> Is this because of Mateusz point that we should fail as soon as possible
> to prevent any fs changes from taking effect?
>
> But like Mateusz points out, this is not really happening for open() with
> O_CREAT either. So is there any policy for what we do and do not tolerate?
> (although I agree we should definitely preallocate the file; thanks for
> pointing that pattern out).
Your version can fail in a lot more cases than O_CREAT because the file
is allocated last which is just not acceptable.
And a misbehaving LSM that ends up preventing opening a created file is
really not our concern. The system can behave in all non-standard ways
with mandatory access control.
The other concern that was brought up in some version is truncate but I
really don't understand what that is supposed to be about. O_TRUNC and
O_CREAT raally don't get in the way of each other in the way people
think they would.
Just look at the FMODE_CREATED case. If that's raised on do_open() then
O_TRUNC is ignored for very obvious reasons.
The only reason where O_TRUNC with O_CREAT matters is if the file did
already exist which also implies O_EXCL isn't raised. In that case this
ends up as a regular truncate request and then it is possible to hit the
handle_truncate() codepath. And there it really doesn't matter. A
concurrent exec or truncate that prevents you from O_CREAT | O_TRUNC
seems perfectly benign if you didn't actually create the file in the
first place. The O_TRUNC would only be honored if we did end up creating
the file. If someone else raised us in doing their own truncate or is
attempting an exe then we should most certainly not get to truncate over
them. Failing is the right thing to do here.
>
> > I do wonder though whether we shouldn't just make O_CREAT | O_DIRECTORY
> > work. I remember that I had a vague comment about this in [1] a few
> > years ago (cf. [1]). It might even be less hairy to get that one right
> > as all the thinking for O_CREAT is already there.
> >
> > What was the rationale for mkdirat2() instead of threading this through
> > openat()/openat2() with O_CREAT?
> >
>
> Because of Mateusz' objection, but I agree with Aleksa (and you in 2023)
> that this is intuitive and you mentioned POSIX allows for it.
>
> But a more general issue, that also applies to this mkdirat2 patch,
> is Linus' objection in that same thread.[1] However, the use-case of
mkdirat2() is objectively the worse api. It forces userspace to use a
separate system call without any reason whatsoever. If you can to
O_CREAT you should also be able to to O_DIRECTORY in the same system
call. If we support O_DIRECTORY | O_CREAT we get all the lookup
restriction niceties RESOLVE_* for free. Plus, it is supportable both in
openat() and openat2() because I made that combo return an errno.
UAPI design often is a nasty mix of performance (context switches),
separation of concerns and privileges, tastefulness, and compromises you
never thought or wanted to make.
I think here it is pretty clear that O_DIRECTORY | O_CREAT is the right
thing to do. Instead of restructuring a bunch of codepaths so it can be
plumbed through to the filesystems we just reuse the existing codepaths
that give us the right context for free.
And during LSFMM the VFS maintains all agreed to proceed with
O_DIRECTORY | O_CREAT.
^ permalink raw reply
* Re: [PATCH v14 00/15] Exposing case folding behavior
From: Christian Brauner @ 2026-05-11 14:02 UTC (permalink / raw)
To: Chuck Lever
Cc: Christian Brauner, linux-fsdevel, linux-ext4, linux-xfs,
linux-cifs, linux-nfs, linux-api, linux-f2fs-devel, hirofumi,
linkinjeon, sj1557.seo, yuezhang.mo, almaz.alexandrovich, slava,
glaubitz, frank.li, tytso, adilger.kernel, cem, sfrench, pc,
ronniesahlberg, sprasad, trondmy, anna, jaegeuk, chao, hansg,
senozhatsky, Darrick J. Wong, Roland Mainz, Steve French
In-Reply-To: <20260507-case-sensitivity-v14-0-e62cc8200435@oracle.com>
On Thu, 07 May 2026 04:52:53 -0400, Chuck Lever wrote:
> Christian, let's lock this one in. I will post subsequent changes
> as delta patches.
>
> Following on from:
>
> https://lore.kernel.org/linux-nfs/20251021-zypressen-bazillus-545a44af57fd@brauner/T/#m0ba197d75b7921d994cf284f3cef3a62abb11aaa
>
> [...]
Applied to the vfs-7.2.exportfs branch of the vfs/vfs.git tree.
Patches in the vfs-7.2.exportfs branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs-7.2.exportfs
[01/15] fs: Move file_kattr initialization to callers
https://git.kernel.org/vfs/vfs/c/9d3942fa6a55
[02/15] fs: Add case sensitivity flags to file_kattr
https://git.kernel.org/vfs/vfs/c/72504a889e52
[03/15] fat: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/d0d06cfce960
[04/15] exfat: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/64a4f2090cb2
[05/15] ntfs3: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/5fff53318cbf
[06/15] hfs: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/1b25c01375e0
[07/15] hfsplus: Report case sensitivity in fileattr_get
https://git.kernel.org/vfs/vfs/c/b9e976dd58ff
[08/15] xfs: Report case sensitivity in fileattr_get
https://git.kernel.org/vfs/vfs/c/30617d630d2f
[09/15] cifs: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/0f372b05c80c
[10/15] nfs: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/3ca9954cdc04
[11/15] vboxsf: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/0f5f23d411ac
[12/15] isofs: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/d56f6094035c
[13/15] nfsd: Report export case-folding via NFSv3 PATHCONF
https://git.kernel.org/vfs/vfs/c/5ca2c8f14428
[14/15] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING
https://git.kernel.org/vfs/vfs/c/62c9555937ca
[15/15] ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION
https://git.kernel.org/vfs/vfs/c/35188379f010
^ permalink raw reply
* Re: [PATCH v14 00/15] Exposing case folding behavior
From: Christian Brauner @ 2026-05-11 14:02 UTC (permalink / raw)
To: Chuck Lever
Cc: Al Viro, Jan Kara, linux-fsdevel, linux-ext4, linux-xfs,
linux-cifs, linux-nfs, linux-api, linux-f2fs-devel, hirofumi,
linkinjeon, sj1557.seo, yuezhang.mo, almaz.alexandrovich, slava,
glaubitz, frank.li, tytso, adilger.kernel, cem, sfrench, pc,
ronniesahlberg, sprasad, trondmy, anna, jaegeuk, chao, hansg,
senozhatsky, Chuck Lever, Darrick J. Wong, Roland Mainz,
Steve French
In-Reply-To: <20260507-case-sensitivity-v14-0-e62cc8200435@oracle.com>
On Thu, May 07, 2026 at 04:52:53AM -0400, Chuck Lever wrote:
> Christian, let's lock this one in. I will post subsequent changes
> as delta patches.
Perfect!
^ permalink raw reply
* Re: [PATCH v14 00/15] Exposing case folding behavior
From: Chuck Lever @ 2026-05-11 14:07 UTC (permalink / raw)
To: Christian Brauner
Cc: linux-fsdevel, linux-ext4, linux-xfs, linux-cifs, linux-nfs,
linux-api, linux-f2fs-devel, hirofumi, linkinjeon, sj1557.seo,
yuezhang.mo, almaz.alexandrovich, slava, glaubitz, frank.li,
tytso, adilger.kernel, cem, sfrench, pc, ronniesahlberg, sprasad,
trondmy, anna, jaegeuk, chao, hansg, senozhatsky, Darrick J. Wong,
Roland Mainz, Steve French
In-Reply-To: <20260511-wertverlust-vorbringen-070f016f3bd4@brauner>
On 5/11/26 10:02 AM, Christian Brauner wrote:
> On Thu, 07 May 2026 04:52:53 -0400, Chuck Lever wrote:
>> Christian, let's lock this one in. I will post subsequent changes
>> as delta patches.
>>
>> Following on from:
>>
>> https://lore.kernel.org/linux-nfs/20251021-zypressen-bazillus-545a44af57fd@brauner/T/#m0ba197d75b7921d994cf284f3cef3a62abb11aaa
>>
>> [...]
>
> Applied to the vfs-7.2.exportfs branch of the vfs/vfs.git tree.
> Patches in the vfs-7.2.exportfs branch should appear in linux-next soon.
Not vfs-7.2-casefold ?
Fwiw, I was intending to rebase nfsd-next on the vfs integration branch,
which should have both vfs-7.2-casefold and vfs-7.2.exportfs merged in,
along with Jeff's series that implements the infrastructure to support
directory delegation properly. LMK if that's crazy talk.
--
Chuck Lever
^ permalink raw reply
* Re: [PATCH v14 00/15] Exposing case folding behavior
From: Christian Brauner @ 2026-05-11 14:55 UTC (permalink / raw)
To: Chuck Lever
Cc: linux-fsdevel, linux-ext4, linux-xfs, linux-cifs, linux-nfs,
linux-api, linux-f2fs-devel, hirofumi, linkinjeon, sj1557.seo,
yuezhang.mo, almaz.alexandrovich, slava, glaubitz, frank.li,
tytso, adilger.kernel, cem, sfrench, pc, ronniesahlberg, sprasad,
trondmy, anna, jaegeuk, chao, hansg, senozhatsky, Darrick J. Wong,
Roland Mainz, Steve French
In-Reply-To: <705e1769-6a5e-440d-bf50-5e5feec2b88d@oracle.com>
On Mon, May 11, 2026 at 10:07:44AM -0400, Chuck Lever wrote:
> On 5/11/26 10:02 AM, Christian Brauner wrote:
> > On Thu, 07 May 2026 04:52:53 -0400, Chuck Lever wrote:
> >> Christian, let's lock this one in. I will post subsequent changes
> >> as delta patches.
> >>
> >> Following on from:
> >>
> >> https://lore.kernel.org/linux-nfs/20251021-zypressen-bazillus-545a44af57fd@brauner/T/#m0ba197d75b7921d994cf284f3cef3a62abb11aaa
> >>
> >> [...]
> >
> > Applied to the vfs-7.2.exportfs branch of the vfs/vfs.git tree.
> > Patches in the vfs-7.2.exportfs branch should appear in linux-next soon.
>
> Not vfs-7.2-casefold ?
>
> Fwiw, I was intending to rebase nfsd-next on the vfs integration branch,
> which should have both vfs-7.2-casefold and vfs-7.2.exportfs merged in,
> along with Jeff's series that implements the infrastructure to support
> directory delegation properly. LMK if that's crazy talk.
I think you should just merge:
vfs-7.2.exportfs
vfs-7.2.casefold
as the order doesn't matter and they don't depend on each other. I have
marked both branches as shared so they won't get touched again. If more
ends on either of these branches it doesn't matter to you. IOW, I think
you should just pick the minimum you need and then you don't need to
hear from again and by the time you send your pull request all the
prerequisites will already be in Linus' tree.
If you merge in vfs.all you're subject to problems from rebases. So I'd
not recommend that.
^ permalink raw reply
* Re: [PATCH v14 00/15] Exposing case folding behavior
From: Christian Brauner @ 2026-05-11 14:55 UTC (permalink / raw)
To: Chuck Lever
Cc: Christian Brauner, Al Viro, Jan Kara, linux-fsdevel, linux-ext4,
linux-xfs, linux-cifs, linux-nfs, linux-api, linux-f2fs-devel,
hirofumi, linkinjeon, sj1557.seo, yuezhang.mo,
almaz.alexandrovich, slava, glaubitz, frank.li, tytso,
adilger.kernel, cem, sfrench, pc, ronniesahlberg, sprasad,
trondmy, anna, jaegeuk, chao, hansg, senozhatsky, Darrick J. Wong,
Roland Mainz, Steve French
In-Reply-To: <20260507-case-sensitivity-v14-0-e62cc8200435@oracle.com>
On Thu, 07 May 2026 04:52:53 -0400, Chuck Lever wrote:
> Christian, let's lock this one in. I will post subsequent changes
> as delta patches.
>
> Following on from:
>
> https://lore.kernel.org/linux-nfs/20251021-zypressen-bazillus-545a44af57fd@brauner/T/#m0ba197d75b7921d994cf284f3cef3a62abb11aaa
>
> [...]
Now on the correct branch and pushed out.
---
Applied to the vfs-7.2.casefold branch of the vfs/vfs.git tree.
Patches in the vfs-7.2.casefold branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: master
[01/15] fs: Move file_kattr initialization to callers
https://git.kernel.org/vfs/vfs/c/14c3197ecf07
[02/15] fs: Add case sensitivity flags to file_kattr
https://git.kernel.org/vfs/vfs/c/3035e4454142
[03/15] fat: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/c92db2ca726f
[04/15] exfat: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/27e0b573dd4a
[05/15] ntfs3: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/eeb7b37b9700
[06/15] hfs: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/b6fe046c3023
[07/15] hfsplus: Report case sensitivity in fileattr_get
https://git.kernel.org/vfs/vfs/c/a6469a15eefe
[08/15] xfs: Report case sensitivity in fileattr_get
https://git.kernel.org/vfs/vfs/c/c9da43e4e5c3
[09/15] cifs: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/e50bc12f5a36
[10/15] nfs: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/92d67628a1a9
[11/15] vboxsf: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/ef14aa143f1d
[12/15] isofs: Implement fileattr_get for case sensitivity
https://git.kernel.org/vfs/vfs/c/7bbd51b1d748
[13/15] nfsd: Report export case-folding via NFSv3 PATHCONF
https://git.kernel.org/vfs/vfs/c/211cb2ba4877
[14/15] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING
https://git.kernel.org/vfs/vfs/c/01ee7c3d2e23
[15/15] ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION
https://git.kernel.org/vfs/vfs/c/0164df1d1de7
^ permalink raw reply
* [PATCH bpf-next v13 0/8] bpf: Extend BPF syscall with common attributes support
From: Leon Hwang @ 2026-05-11 15:28 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Christian Brauner, Seth Forshee, Yuichiro Tsuji,
Andrey Albershteyn, Leon Hwang, Willem de Bruijn, Jason Xing,
Tao Chen, Mykyta Yatsenko, Kumar Kartikeya Dwivedi,
Anton Protopopov, Amery Hung, Rong Tao, linux-kernel, linux-api,
linux-kselftest, kernel-patches-bot
This patch series builds upon the discussion in
"[PATCH bpf-next v4 0/4] bpf: Improve error reporting for freplace attachment failure" [1].
This patch series introduces support for *common attributes* in the BPF
syscall, providing a unified mechanism for passing shared metadata across
all BPF commands, initially used by BPF_PROG_LOAD, BPF_BTF_LOAD, and
BPF_MAP_CREATE.
The initial set of common attributes includes:
1. 'log_buf': User-provided buffer for storing log output.
2. 'log_size': Size of the provided log buffer.
3. 'log_level': Verbosity level for logging.
4. 'log_true_size': Actual log size reported by kernel.
With this extension, the BPF syscall will be able to return meaningful
error messages (e.g., map creation failures), improving debuggability
and user experience.
Links:
[1] https://lore.kernel.org/bpf/20250224153352.64689-1-leon.hwang@linux.dev/
Changes:
v12 -> v13:
* Rebase on bpf-next tree to resolve code conflict.
* Report log_true_size on success path in patch #6.
* Check size instead of common->log_buf in patch #6 (per bot+bpf-ci).
* v12: https://lore.kernel.org/bpf/20260420141804.27179-1-leon.hwang@linux.dev/
v11 -> v12:
* Drop "log_" prefix in struct bpf_log_attr in patch #3.
* Drop "log_" prefix in struct bpf_log_opts in patch #7.
* Copy log_true_size using copy_to_bpfptr_offset() in patch #3 (per Alexei).
* v11: https://lore.kernel.org/bpf/20260216150445.68278-1-leon.hwang@linux.dev/
v10 -> v11:
* Collect Acked-by from Andrii, thanks.
* Validate whether log_buf, log_size, and log_level are valid by reusing
bpf_verifier_log_attr_valid() in patch #4 (per Andrii).
* v10: https://lore.kernel.org/bpf/20260211151115.78013-1-leon.hwang@linux.dev/
v9 -> v10:
* Collect Acked-by from Andrii, thanks.
* Address comments from Andrii:
* Drop log NULL check in bpf_log_attr_finalize().
* Return -EFAULT early in bpf_log_attr_finalize().
* Validate whether log_buf, log_size, and log_level are set.
* Keep log_buf, log_size, log_level, and user-pointer log_true_size in struct
bpf_log_attr.
* Make prog_load and btf_load work with the new struct bpf_log_attr.
* Add comment to log_true_size of struct bpf_log_opts in libbpf.
* Address comment from Alexei:
* Avoid using BPF_LOG_FIXED as log_level in tests.
* v9: https://lore.kernel.org/bpf/20260202144046.30651-1-leon.hwang@linux.dev/
v8 -> v9:
* Rework reporting 'log_true_size' for prog_load, btf_load, and map_create to
simplify struct bpf_log_attr (per Alexei).
* v8: https://lore.kernel.org/bpf/20260126151409.52072-1-leon.hwang@linux.dev/
v7 -> v8:
* Return 0 when fd < 0 and errno != EFAULT in probe_sys_bpf_ext(), then simplify
probe_bpf_syscall_common_attrs() (per Alexei and Andrii).
* v7: https://lore.kernel.org/bpf/20260123032445.125259-1-leon.hwang@linux.dev/
v6 -> v7:
* Return -errno when fd < 0 and errno != EFAULT in probe_sys_bpf_ext().
* Convert return value of probe_sys_bpf_ext() to bool in
probe_bpf_syscall_common_attrs().
* Address comments from Andrii:
* Drop the comment, and handle fd >= 0 case explicitly in
probe_sys_bpf_ext().
* Return an error when fd >= 0 in probe_sys_bpf_ext().
* v6: https://lore.kernel.org/bpf/20260120152424.40766-1-leon.hwang@linux.dev/
v5 -> v6:
* Address comments from Andrii:
* Update some variables' name.
* Drop unnecessary 'close(fd)' in libbpf.
* Rename FEAT_EXTENDED_SYSCALL to FEAT_BPF_SYSCALL_COMMON_ATTRS with
updated description in libbpf.
* Use EINVAL instead of EUSERS, as EUSERS is not used in bpf yet.
* Rename struct bpf_syscall_common_attr_opts to bpf_log_opts in libbpf.
* Add 'OPTS_SET(log_opts, log_true_size, 0);' in libbpf's 'bpf_map_create()'.
* v5: https://lore.kernel.org/bpf/20260112145616.44195-1-leon.hwang@linux.dev/
v4 -> v5:
* Rework reporting 'log_true_size' for prog_load, btf_load, and map_create
(per Alexei).
* v4: https://lore.kernel.org/bpf/20260106172018.57757-1-leon.hwang@linux.dev/
RFC v3 -> v4:
* Drop RFC.
* Address comments from Andrii:
* Add parentheses in 'sys_bpf_ext()'.
* Avoid creating new fd in 'probe_sys_bpf_ext()'.
* Add a new struct to wrap log fields in libbpf.
* Address comments from Alexei:
* Do not skip writing to user space when log_true_size is zero.
* Do not use 'bool' arguments.
* Drop the adding WARN_ON_ONCE()'s.
* v3: https://lore.kernel.org/bpf/20251002154841.99348-1-leon.hwang@linux.dev/
RFC v2 -> RFC v3:
* Rename probe_sys_bpf_extended to probe_sys_bpf_ext.
* Refactor reporting 'log_true_size' for prog_load.
* Refactor reporting 'btf_log_true_size' for btf_load.
* Add warnings for internal bugs in map_create.
* Check log_true_size in test cases.
* Address comment from Alexei:
* Change kvzalloc/kvfree to kzalloc/kfree.
* Address comments from Andrii:
* Move BPF_COMMON_ATTRS to 'enum bpf_cmd' alongside brief comment.
* Add bpf_check_uarg_tail_zero() for extra checks.
* Rename sys_bpf_extended to sys_bpf_ext.
* Rename sys_bpf_fd_extended to sys_bpf_ext_fd.
* Probe the new feature using NULL and -EFAULT.
* Move probe_sys_bpf_ext to libbpf_internal.h and drop LIBBPF_API.
* Return -EUSERS when log attrs are conflict between bpf_attr and
bpf_common_attr.
* Avoid touching bpf_vlog_init().
* Update the reason messages in map_create.
* Finalize the log using __cleanup().
* Report log size to users.
* Change type of log_buf from '__u64' to 'const char *' and cast type
using ptr_to_u64() in bpf_map_create().
* Do not return -EOPNOTSUPP when kernel doesn't support this feature
in bpf_map_create().
* Add log_level support for map creation for consistency.
* Address comment from Eduard:
* Use common_attrs->log_level instead of BPF_LOG_FIXED.
* v2: https://lore.kernel.org/bpf/20250911163328.93490-1-leon.hwang@linux.dev/
RFC v1 -> RFC v2:
* Fix build error reported by test bot.
* Address comments from Alexei:
* Drop new uapi for freplace.
* Add common attributes support for prog_load and btf_load.
* Add common attributes support for map_create.
* v1: https://lore.kernel.org/bpf/20250728142346.95681-1-leon.hwang@linux.dev/
Leon Hwang (8):
bpf: Extend BPF syscall with common attributes support
libbpf: Add support for extended BPF syscall
bpf: Refactor reporting log_true_size for prog_load
bpf: Add syscall common attributes support for prog_load
bpf: Add syscall common attributes support for btf_load
bpf: Add syscall common attributes support for map_create
libbpf: Add syscall common attributes support for map_create
selftests/bpf: Add tests to verify map create failure log
include/linux/bpf.h | 4 +-
include/linux/bpf_verifier.h | 16 ++
include/linux/btf.h | 3 +-
include/linux/syscalls.h | 3 +-
include/uapi/linux/bpf.h | 8 +
kernel/bpf/btf.c | 30 +---
kernel/bpf/log.c | 90 +++++++++-
kernel/bpf/syscall.c | 115 +++++++++---
kernel/bpf/verifier.c | 17 +-
tools/include/uapi/linux/bpf.h | 8 +
tools/lib/bpf/bpf.c | 52 +++++-
tools/lib/bpf/bpf.h | 17 +-
tools/lib/bpf/features.c | 8 +
tools/lib/bpf/libbpf_internal.h | 3 +
.../selftests/bpf/prog_tests/map_init.c | 166 ++++++++++++++++++
15 files changed, 473 insertions(+), 67 deletions(-)
--
2.54.0
^ permalink raw reply
* [PATCH bpf-next v13 1/8] bpf: Extend BPF syscall with common attributes support
From: Leon Hwang @ 2026-05-11 15:28 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Christian Brauner, Seth Forshee, Yuichiro Tsuji,
Andrey Albershteyn, Leon Hwang, Willem de Bruijn, Jason Xing,
Tao Chen, Mykyta Yatsenko, Kumar Kartikeya Dwivedi,
Anton Protopopov, Amery Hung, Rong Tao, linux-kernel, linux-api,
linux-kselftest, kernel-patches-bot
In-Reply-To: <20260511152817.89191-1-leon.hwang@linux.dev>
Add generic BPF syscall support for passing common attributes.
The initial set of common attributes includes:
1. 'log_buf': User-provided buffer for storing logs.
2. 'log_size': Size of the log buffer.
3. 'log_level': Log verbosity level.
4. 'log_true_size': Actual log size reported by kernel.
The common-attribute pointer and its size are passed as the 4th and 5th
syscall arguments. A new command bit, 'BPF_COMMON_ATTRS' ('1 << 16'),
indicates that common attributes are supplied.
This commit adds syscall and uapi plumbing. Command-specific handling is
added in follow-up patches.
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
include/linux/syscalls.h | 3 ++-
include/uapi/linux/bpf.h | 8 ++++++++
kernel/bpf/syscall.c | 25 +++++++++++++++++++++----
tools/include/uapi/linux/bpf.h | 8 ++++++++
4 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index f5639d5ac331..50055ab73649 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -936,7 +936,8 @@ asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
asmlinkage long sys_getrandom(char __user *buf, size_t count,
unsigned int flags);
asmlinkage long sys_memfd_create(const char __user *uname_ptr, unsigned int flags);
-asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int size);
+asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int size,
+ struct bpf_common_attr __user *attr_common, unsigned int size_common);
asmlinkage long sys_execveat(int dfd, const char __user *filename,
const char __user *const __user *argv,
const char __user *const __user *envp, int flags);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 552bc5d9afbd..49eeb18ad050 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -994,6 +994,7 @@ enum bpf_cmd {
BPF_PROG_STREAM_READ_BY_FD,
BPF_PROG_ASSOC_STRUCT_OPS,
__MAX_BPF_CMD,
+ BPF_COMMON_ATTRS = 1 << 16, /* Indicate carrying syscall common attrs. */
};
enum bpf_map_type {
@@ -1500,6 +1501,13 @@ struct bpf_stack_build_id {
};
};
+struct bpf_common_attr {
+ __u64 log_buf;
+ __u32 log_size;
+ __u32 log_level;
+ __u32 log_true_size;
+};
+
#define BPF_OBJ_NAME_LEN 16U
enum {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 3b1f0ba02f61..354f6f471a08 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -6211,8 +6211,10 @@ static int prog_assoc_struct_ops(union bpf_attr *attr)
return ret;
}
-static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size)
+static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
+ bpfptr_t uattr_common, unsigned int size_common)
{
+ struct bpf_common_attr attr_common;
union bpf_attr attr;
int err;
@@ -6226,6 +6228,20 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size)
if (copy_from_bpfptr(&attr, uattr, size) != 0)
return -EFAULT;
+ memset(&attr_common, 0, sizeof(attr_common));
+ if (cmd & BPF_COMMON_ATTRS) {
+ err = bpf_check_uarg_tail_zero(uattr_common, sizeof(attr_common), size_common);
+ if (err)
+ return err;
+
+ cmd &= ~BPF_COMMON_ATTRS;
+ size_common = min_t(u32, size_common, sizeof(attr_common));
+ if (copy_from_bpfptr(&attr_common, uattr_common, size_common) != 0)
+ return -EFAULT;
+ } else {
+ size_common = 0;
+ }
+
err = security_bpf(cmd, &attr, size, uattr.is_kernel);
if (err < 0)
return err;
@@ -6361,9 +6377,10 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size)
return err;
}
-SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
+SYSCALL_DEFINE5(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size,
+ struct bpf_common_attr __user *, uattr_common, unsigned int, size_common)
{
- return __sys_bpf(cmd, USER_BPFPTR(uattr), size);
+ return __sys_bpf(cmd, USER_BPFPTR(uattr), size, USER_BPFPTR(uattr_common), size_common);
}
static bool syscall_prog_is_valid_access(int off, int size,
@@ -6393,7 +6410,7 @@ BPF_CALL_3(bpf_sys_bpf, int, cmd, union bpf_attr *, attr, u32, attr_size)
default:
return -EINVAL;
}
- return __sys_bpf(cmd, KERNEL_BPFPTR(attr), attr_size);
+ return __sys_bpf(cmd, KERNEL_BPFPTR(attr), attr_size, KERNEL_BPFPTR(NULL), 0);
}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 677be9a47347..16ff0968fc21 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -994,6 +994,7 @@ enum bpf_cmd {
BPF_PROG_STREAM_READ_BY_FD,
BPF_PROG_ASSOC_STRUCT_OPS,
__MAX_BPF_CMD,
+ BPF_COMMON_ATTRS = 1 << 16, /* Indicate carrying syscall common attrs. */
};
enum bpf_map_type {
@@ -1500,6 +1501,13 @@ struct bpf_stack_build_id {
};
};
+struct bpf_common_attr {
+ __u64 log_buf;
+ __u32 log_size;
+ __u32 log_level;
+ __u32 log_true_size;
+};
+
#define BPF_OBJ_NAME_LEN 16U
enum {
--
2.54.0
^ permalink raw reply related
* [PATCH bpf-next v13 2/8] libbpf: Add support for extended BPF syscall
From: Leon Hwang @ 2026-05-11 15:28 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Christian Brauner, Seth Forshee, Yuichiro Tsuji,
Andrey Albershteyn, Leon Hwang, Willem de Bruijn, Jason Xing,
Tao Chen, Mykyta Yatsenko, Kumar Kartikeya Dwivedi,
Anton Protopopov, Amery Hung, Rong Tao, linux-kernel, linux-api,
linux-kselftest, kernel-patches-bot
In-Reply-To: <20260511152817.89191-1-leon.hwang@linux.dev>
To support the extended BPF syscall introduced in the previous commit,
introduce the following internal APIs:
* 'sys_bpf_ext()'
* 'sys_bpf_ext_fd()'
They wrap the raw 'syscall()' interface to support passing extended
attributes.
* 'probe_sys_bpf_ext()'
Check whether current kernel supports the BPF syscall common attributes.
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
tools/lib/bpf/bpf.c | 36 +++++++++++++++++++++++++++++++++
tools/lib/bpf/features.c | 8 ++++++++
tools/lib/bpf/libbpf_internal.h | 3 +++
3 files changed, 47 insertions(+)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 5846de364209..9d8740761b7a 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -69,6 +69,42 @@ static inline __u64 ptr_to_u64(const void *ptr)
return (__u64) (unsigned long) ptr;
}
+static inline int sys_bpf_ext(enum bpf_cmd cmd, union bpf_attr *attr,
+ unsigned int size,
+ struct bpf_common_attr *attr_common,
+ unsigned int size_common)
+{
+ cmd = attr_common ? (cmd | BPF_COMMON_ATTRS) : (cmd & ~BPF_COMMON_ATTRS);
+ return syscall(__NR_bpf, cmd, attr, size, attr_common, size_common);
+}
+
+static inline int sys_bpf_ext_fd(enum bpf_cmd cmd, union bpf_attr *attr,
+ unsigned int size,
+ struct bpf_common_attr *attr_common,
+ unsigned int size_common)
+{
+ int fd;
+
+ fd = sys_bpf_ext(cmd, attr, size, attr_common, size_common);
+ return ensure_good_fd(fd);
+}
+
+int probe_sys_bpf_ext(void)
+{
+ const size_t attr_sz = offsetofend(union bpf_attr, prog_token_fd);
+ union bpf_attr attr;
+ int fd;
+
+ memset(&attr, 0, attr_sz);
+ fd = syscall(__NR_bpf, BPF_PROG_LOAD | BPF_COMMON_ATTRS, &attr, attr_sz, NULL,
+ sizeof(struct bpf_common_attr));
+ if (fd >= 0) {
+ close(fd);
+ return -EINVAL;
+ }
+ return errno == EFAULT ? 1 : 0;
+}
+
static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
unsigned int size)
{
diff --git a/tools/lib/bpf/features.c b/tools/lib/bpf/features.c
index 4f19a0d79b0c..b7e388f99d0b 100644
--- a/tools/lib/bpf/features.c
+++ b/tools/lib/bpf/features.c
@@ -615,6 +615,11 @@ static int probe_kern_btf_layout(int token_fd)
(char *)layout, token_fd));
}
+static int probe_bpf_syscall_common_attrs(int token_fd)
+{
+ return probe_sys_bpf_ext();
+}
+
typedef int (*feature_probe_fn)(int /* token_fd */);
static struct kern_feature_cache feature_cache;
@@ -699,6 +704,9 @@ static struct kern_feature_desc {
[FEAT_BTF_LAYOUT] = {
"kernel supports BTF layout", probe_kern_btf_layout,
},
+ [FEAT_BPF_SYSCALL_COMMON_ATTRS] = {
+ "BPF syscall common attributes support", probe_bpf_syscall_common_attrs,
+ },
};
bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id)
diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
index 3781c45b46d3..7d93c6c01d60 100644
--- a/tools/lib/bpf/libbpf_internal.h
+++ b/tools/lib/bpf/libbpf_internal.h
@@ -398,6 +398,8 @@ enum kern_feature_id {
FEAT_UPROBE_SYSCALL,
/* Kernel supports BTF layout information */
FEAT_BTF_LAYOUT,
+ /* Kernel supports BPF syscall common attributes */
+ FEAT_BPF_SYSCALL_COMMON_ATTRS,
__FEAT_CNT,
};
@@ -768,4 +770,5 @@ int probe_fd(int fd);
#define SHA256_DWORD_SIZE SHA256_DIGEST_LENGTH / sizeof(__u64)
void libbpf_sha256(const void *data, size_t len, __u8 out[SHA256_DIGEST_LENGTH]);
+int probe_sys_bpf_ext(void);
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */
--
2.54.0
^ permalink raw reply related
* [PATCH bpf-next v13 3/8] bpf: Refactor reporting log_true_size for prog_load
From: Leon Hwang @ 2026-05-11 15:28 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Christian Brauner, Seth Forshee, Yuichiro Tsuji,
Andrey Albershteyn, Leon Hwang, Willem de Bruijn, Jason Xing,
Tao Chen, Mykyta Yatsenko, Kumar Kartikeya Dwivedi,
Anton Protopopov, Amery Hung, Rong Tao, linux-kernel, linux-api,
linux-kselftest, kernel-patches-bot
In-Reply-To: <20260511152817.89191-1-leon.hwang@linux.dev>
The next commit will add support for reporting logs via extended common
attributes, including 'log_true_size'.
To prepare for that, refactor the 'log_true_size' reporting logic by
introducing a new struct bpf_log_attr to encapsulate log-related behavior:
* bpf_log_attr_init(): initialize log fields, which will support
extended common attributes in the next commit.
* bpf_log_attr_finalize(): handle log finalization and write back
'log_true_size' to userspace.
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
include/linux/bpf.h | 4 +++-
include/linux/bpf_verifier.h | 12 ++++++++++++
kernel/bpf/log.c | 29 +++++++++++++++++++++++++++++
kernel/bpf/syscall.c | 12 +++++++++---
kernel/bpf/verifier.c | 17 ++++-------------
5 files changed, 57 insertions(+), 17 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 715b6df9c403..b3a0cca92e54 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -2919,7 +2919,9 @@ int bpf_check_uarg_tail_zero(bpfptr_t uaddr, size_t expected_size,
size_t actual_size);
/* verify correctness of eBPF program */
-int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size);
+struct bpf_log_attr;
+int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr,
+ struct bpf_log_attr *attr_log);
#ifndef CONFIG_BPF_JIT_ALWAYS_ON
void bpf_patch_call_args(struct bpf_insn *insn, u32 stack_depth);
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 976e2b2f40e8..8d27ad1f9f94 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -755,6 +755,18 @@ static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log)
return log && log->level;
}
+struct bpf_log_attr {
+ char __user *ubuf;
+ u32 size;
+ u32 level;
+ u32 offsetof_true_size;
+ bpfptr_t uattr;
+};
+
+int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size, u32 log_level,
+ u32 offsetof_log_true_size, bpfptr_t uattr);
+int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_log *log);
+
#define BPF_MAX_SUBPROGS 256
struct bpf_subprog_arg_info {
diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c
index 64566b86dd27..1b1efe75398b 100644
--- a/kernel/bpf/log.c
+++ b/kernel/bpf/log.c
@@ -825,3 +825,32 @@ void print_insn_state(struct bpf_verifier_env *env, const struct bpf_verifier_st
}
print_verifier_state(env, vstate, frameno, false);
}
+
+int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size, u32 log_level,
+ u32 offsetof_log_true_size, bpfptr_t uattr)
+{
+ char __user *ubuf = u64_to_user_ptr(log_buf);
+
+ memset(log, 0, sizeof(*log));
+ log->ubuf = ubuf;
+ log->size = log_size;
+ log->level = log_level;
+ log->offsetof_true_size = offsetof_log_true_size;
+ log->uattr = uattr;
+ return 0;
+}
+
+int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_log *log)
+{
+ u32 log_true_size;
+ int err;
+
+ err = bpf_vlog_finalize(log, &log_true_size);
+
+ if (attr->offsetof_true_size &&
+ copy_to_bpfptr_offset(attr->uattr, attr->offsetof_true_size, &log_true_size,
+ sizeof(log_true_size)))
+ return -EFAULT;
+
+ return err;
+}
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 354f6f471a08..70b78ddcdedb 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -2861,7 +2861,7 @@ static int bpf_prog_mark_insn_arrays_ready(struct bpf_prog *prog)
/* last field in 'union bpf_attr' used by this command */
#define BPF_PROG_LOAD_LAST_FIELD keyring_id
-static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
+static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, struct bpf_log_attr *attr_log)
{
enum bpf_prog_type type = attr->prog_type;
struct bpf_prog *prog, *dst_prog = NULL;
@@ -3079,7 +3079,7 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
goto free_prog_sec;
/* run eBPF verifier */
- err = bpf_check(&prog, attr, uattr, uattr_size);
+ err = bpf_check(&prog, attr, uattr, attr_log);
if (err < 0)
goto free_used_maps;
@@ -6215,6 +6215,8 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
bpfptr_t uattr_common, unsigned int size_common)
{
struct bpf_common_attr attr_common;
+ u32 offsetof_log_true_size = 0;
+ struct bpf_log_attr attr_log;
union bpf_attr attr;
int err;
@@ -6266,7 +6268,11 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
err = map_freeze(&attr);
break;
case BPF_PROG_LOAD:
- err = bpf_prog_load(&attr, uattr, size);
+ if (size >= offsetofend(union bpf_attr, log_true_size))
+ offsetof_log_true_size = offsetof(union bpf_attr, log_true_size);
+ err = bpf_log_attr_init(&attr_log, attr.log_buf, attr.log_size, attr.log_level,
+ offsetof_log_true_size, uattr);
+ err = err ?: bpf_prog_load(&attr, uattr, &attr_log);
break;
case BPF_OBJ_PIN:
err = bpf_obj_pin(&attr);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 11054ad89c14..0e654ef01ae0 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -19294,12 +19294,12 @@ int bpf_fixup_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
return 0;
}
-int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size)
+int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr,
+ struct bpf_log_attr *attr_log)
{
u64 start_time = ktime_get_ns();
struct bpf_verifier_env *env;
int i, len, ret = -EINVAL, err;
- u32 log_true_size;
bool is_priv;
BTF_TYPE_EMIT(enum bpf_features);
@@ -19346,9 +19346,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
/* user could have requested verbose verifier output
* and supplied buffer to store the verification trace
*/
- ret = bpf_vlog_init(&env->log, attr->log_level,
- (char __user *) (unsigned long) attr->log_buf,
- attr->log_size);
+ ret = bpf_vlog_init(&env->log, attr_log->level, attr_log->ubuf, attr_log->size);
if (ret)
goto err_unlock;
@@ -19510,17 +19508,10 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
env->prog->aux->verified_insns = env->insn_processed;
/* preserve original error even if log finalization is successful */
- err = bpf_vlog_finalize(&env->log, &log_true_size);
+ err = bpf_log_attr_finalize(attr_log, &env->log);
if (err)
ret = err;
- if (uattr_size >= offsetofend(union bpf_attr, log_true_size) &&
- copy_to_bpfptr_offset(uattr, offsetof(union bpf_attr, log_true_size),
- &log_true_size, sizeof(log_true_size))) {
- ret = -EFAULT;
- goto err_release_maps;
- }
-
if (ret)
goto err_release_maps;
--
2.54.0
^ permalink raw reply related
* [PATCH bpf-next v13 4/8] bpf: Add syscall common attributes support for prog_load
From: Leon Hwang @ 2026-05-11 15:28 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Christian Brauner, Seth Forshee, Yuichiro Tsuji,
Andrey Albershteyn, Leon Hwang, Willem de Bruijn, Jason Xing,
Tao Chen, Mykyta Yatsenko, Kumar Kartikeya Dwivedi,
Anton Protopopov, Amery Hung, Rong Tao, linux-kernel, linux-api,
linux-kselftest, kernel-patches-bot
In-Reply-To: <20260511152817.89191-1-leon.hwang@linux.dev>
BPF_PROG_LOAD can now take log parameters from both union bpf_attr and
struct bpf_common_attr. The merge rules are:
- if both sides provide a complete log tuple (buf/size/level) and they
match, use it;
- if only one side provides log parameters, use that one;
- if both sides provide complete tuples but they differ, return -EINVAL.
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
include/linux/bpf_verifier.h | 3 ++-
kernel/bpf/log.c | 34 +++++++++++++++++++++++++++-------
kernel/bpf/syscall.c | 3 ++-
3 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 8d27ad1f9f94..8433430dedb7 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -764,7 +764,8 @@ struct bpf_log_attr {
};
int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size, u32 log_level,
- u32 offsetof_log_true_size, bpfptr_t uattr);
+ u32 offsetof_log_true_size, bpfptr_t uattr, struct bpf_common_attr *common,
+ bpfptr_t uattr_common, u32 size_common);
int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_log *log);
#define BPF_MAX_SUBPROGS 256
diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c
index 1b1efe75398b..fd12ad5a0338 100644
--- a/kernel/bpf/log.c
+++ b/kernel/bpf/log.c
@@ -13,17 +13,17 @@
#define verbose(env, fmt, args...) bpf_verifier_log_write(env, fmt, ##args)
-static bool bpf_verifier_log_attr_valid(const struct bpf_verifier_log *log)
+static bool bpf_verifier_log_attr_valid(u32 log_level, char __user *log_buf, u32 log_size)
{
/* ubuf and len_total should both be specified (or not) together */
- if (!!log->ubuf != !!log->len_total)
+ if (!!log_buf != !!log_size)
return false;
/* log buf without log_level is meaningless */
- if (log->ubuf && log->level == 0)
+ if (log_buf && log_level == 0)
return false;
- if (log->level & ~BPF_LOG_MASK)
+ if (log_level & ~BPF_LOG_MASK)
return false;
- if (log->len_total > UINT_MAX >> 2)
+ if (log_size > UINT_MAX >> 2)
return false;
return true;
}
@@ -36,7 +36,7 @@ int bpf_vlog_init(struct bpf_verifier_log *log, u32 log_level,
log->len_total = log_size;
/* log attributes have to be sane */
- if (!bpf_verifier_log_attr_valid(log))
+ if (!bpf_verifier_log_attr_valid(log_level, log_buf, log_size))
return -EINVAL;
return 0;
@@ -827,16 +827,36 @@ void print_insn_state(struct bpf_verifier_env *env, const struct bpf_verifier_st
}
int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size, u32 log_level,
- u32 offsetof_log_true_size, bpfptr_t uattr)
+ u32 offsetof_log_true_size, bpfptr_t uattr, struct bpf_common_attr *common,
+ bpfptr_t uattr_common, u32 size_common)
{
+ char __user *ubuf_common = u64_to_user_ptr(common->log_buf);
char __user *ubuf = u64_to_user_ptr(log_buf);
+ if (!bpf_verifier_log_attr_valid(common->log_level, ubuf_common, common->log_size) ||
+ !bpf_verifier_log_attr_valid(log_level, ubuf, log_size))
+ return -EINVAL;
+
+ if (ubuf && ubuf_common && (ubuf != ubuf_common || log_size != common->log_size ||
+ log_level != common->log_level))
+ return -EINVAL;
+
memset(log, 0, sizeof(*log));
log->ubuf = ubuf;
log->size = log_size;
log->level = log_level;
log->offsetof_true_size = offsetof_log_true_size;
log->uattr = uattr;
+
+ if (!ubuf && ubuf_common) {
+ log->ubuf = ubuf_common;
+ log->size = common->log_size;
+ log->level = common->log_level;
+ log->uattr = uattr_common;
+ log->offsetof_true_size = 0;
+ if (size_common >= offsetofend(struct bpf_common_attr, log_true_size))
+ log->offsetof_true_size = offsetof(struct bpf_common_attr, log_true_size);
+ }
return 0;
}
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 70b78ddcdedb..db893cae826c 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -6271,7 +6271,8 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
if (size >= offsetofend(union bpf_attr, log_true_size))
offsetof_log_true_size = offsetof(union bpf_attr, log_true_size);
err = bpf_log_attr_init(&attr_log, attr.log_buf, attr.log_size, attr.log_level,
- offsetof_log_true_size, uattr);
+ offsetof_log_true_size, uattr, &attr_common, uattr_common,
+ size_common);
err = err ?: bpf_prog_load(&attr, uattr, &attr_log);
break;
case BPF_OBJ_PIN:
--
2.54.0
^ permalink raw reply related
* [PATCH bpf-next v13 5/8] bpf: Add syscall common attributes support for btf_load
From: Leon Hwang @ 2026-05-11 15:28 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Christian Brauner, Seth Forshee, Yuichiro Tsuji,
Andrey Albershteyn, Leon Hwang, Willem de Bruijn, Jason Xing,
Tao Chen, Mykyta Yatsenko, Kumar Kartikeya Dwivedi,
Anton Protopopov, Amery Hung, Rong Tao, linux-kernel, linux-api,
linux-kselftest, kernel-patches-bot
In-Reply-To: <20260511152817.89191-1-leon.hwang@linux.dev>
BPF_BTF_LOAD can now take log parameters from both union bpf_attr and
struct bpf_common_attr, with the same merge rules as BPF_PROG_LOAD:
- if both sides provide a complete log tuple (buf/size/level) and they
match, use it;
- if only one side provides log parameters, use that one;
- if both sides provide complete tuples but they differ, return -EINVAL.
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
include/linux/btf.h | 3 ++-
kernel/bpf/btf.c | 30 +++++++-----------------------
kernel/bpf/syscall.c | 11 ++++++++---
3 files changed, 17 insertions(+), 27 deletions(-)
diff --git a/include/linux/btf.h b/include/linux/btf.h
index c82d0d689059..240401d9b25b 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -145,7 +145,8 @@ const char *btf_get_name(const struct btf *btf);
void btf_get(struct btf *btf);
void btf_put(struct btf *btf);
const struct btf_header *btf_header(const struct btf *btf);
-int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_sz);
+struct bpf_log_attr;
+int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, struct bpf_log_attr *attr_log);
struct btf *btf_get_by_fd(int fd);
int btf_get_info_by_fd(const struct btf *btf,
const union bpf_attr *attr,
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 77af44d8a3ad..a6bf4781943c 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -5907,25 +5907,10 @@ static int btf_check_type_tags(struct btf_verifier_env *env,
return 0;
}
-static int finalize_log(struct bpf_verifier_log *log, bpfptr_t uattr, u32 uattr_size)
-{
- u32 log_true_size;
- int err;
-
- err = bpf_vlog_finalize(log, &log_true_size);
-
- if (uattr_size >= offsetofend(union bpf_attr, btf_log_true_size) &&
- copy_to_bpfptr_offset(uattr, offsetof(union bpf_attr, btf_log_true_size),
- &log_true_size, sizeof(log_true_size)))
- err = -EFAULT;
-
- return err;
-}
-
-static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
+static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr,
+ struct bpf_log_attr *attr_log)
{
bpfptr_t btf_data = make_bpfptr(attr->btf, uattr.is_kernel);
- char __user *log_ubuf = u64_to_user_ptr(attr->btf_log_buf);
struct btf_struct_metas *struct_meta_tab;
struct btf_verifier_env *env = NULL;
struct btf *btf = NULL;
@@ -5942,8 +5927,7 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat
/* user could have requested verbose verifier output
* and supplied buffer to store the verification trace
*/
- err = bpf_vlog_init(&env->log, attr->btf_log_level,
- log_ubuf, attr->btf_log_size);
+ err = bpf_vlog_init(&env->log, attr_log->level, attr_log->ubuf, attr_log->size);
if (err)
goto errout_free;
@@ -6008,7 +5992,7 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat
}
}
- err = finalize_log(&env->log, uattr, uattr_size);
+ err = bpf_log_attr_finalize(attr_log, &env->log);
if (err)
goto errout_free;
@@ -6020,7 +6004,7 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat
btf_free_struct_meta_tab(btf);
errout:
/* overwrite err with -ENOSPC or -EFAULT */
- ret = finalize_log(&env->log, uattr, uattr_size);
+ ret = bpf_log_attr_finalize(attr_log, &env->log);
if (ret)
err = ret;
errout_free:
@@ -8189,12 +8173,12 @@ static int __btf_new_fd(struct btf *btf)
return anon_inode_getfd("btf", &btf_fops, btf, O_RDONLY | O_CLOEXEC);
}
-int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
+int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, struct bpf_log_attr *attr_log)
{
struct btf *btf;
int ret;
- btf = btf_parse(attr, uattr, uattr_size);
+ btf = btf_parse(attr, uattr, attr_log);
if (IS_ERR(btf))
return PTR_ERR(btf);
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index db893cae826c..2fa05ba8f161 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -5474,7 +5474,7 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
#define BPF_BTF_LOAD_LAST_FIELD btf_token_fd
-static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size)
+static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, struct bpf_log_attr *attr_log)
{
struct bpf_token *token = NULL;
@@ -5501,7 +5501,7 @@ static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_
bpf_token_put(token);
- return btf_new_fd(attr, uattr, uattr_size);
+ return btf_new_fd(attr, uattr, attr_log);
}
#define BPF_BTF_GET_FD_BY_ID_LAST_FIELD fd_by_id_token_fd
@@ -6318,7 +6318,12 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
err = bpf_raw_tracepoint_open(&attr);
break;
case BPF_BTF_LOAD:
- err = bpf_btf_load(&attr, uattr, size);
+ if (size >= offsetofend(union bpf_attr, btf_log_true_size))
+ offsetof_log_true_size = offsetof(union bpf_attr, btf_log_true_size);
+ err = bpf_log_attr_init(&attr_log, attr.btf_log_buf, attr.btf_log_size,
+ attr.btf_log_level, offsetof_log_true_size, uattr,
+ &attr_common, uattr_common, size_common);
+ err = err ?: bpf_btf_load(&attr, uattr, &attr_log);
break;
case BPF_BTF_GET_FD_BY_ID:
err = bpf_btf_get_fd_by_id(&attr);
--
2.54.0
^ permalink raw reply related
* [PATCH bpf-next v13 6/8] bpf: Add syscall common attributes support for map_create
From: Leon Hwang @ 2026-05-11 15:28 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Christian Brauner, Seth Forshee, Yuichiro Tsuji,
Andrey Albershteyn, Leon Hwang, Willem de Bruijn, Jason Xing,
Tao Chen, Mykyta Yatsenko, Kumar Kartikeya Dwivedi,
Anton Protopopov, Amery Hung, Rong Tao, linux-kernel, linux-api,
linux-kselftest, kernel-patches-bot
In-Reply-To: <20260511152817.89191-1-leon.hwang@linux.dev>
Many BPF_MAP_CREATE validation failures currently return -EINVAL without
any explanation to userspace.
Plumb common syscall log attributes into map_create(), create a verifier
log from bpf_common_attr::log_buf/log_size/log_level, and report
map-creation failure reasons through that buffer.
This improves debuggability by allowing userspace to inspect why map
creation failed and read back log_true_size from common attributes.
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
include/linux/bpf_verifier.h | 3 ++
kernel/bpf/log.c | 29 ++++++++++++++++
kernel/bpf/syscall.c | 66 ++++++++++++++++++++++++++++++------
3 files changed, 88 insertions(+), 10 deletions(-)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 8433430dedb7..c15a4c26a43b 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -766,6 +766,9 @@ struct bpf_log_attr {
int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size, u32 log_level,
u32 offsetof_log_true_size, bpfptr_t uattr, struct bpf_common_attr *common,
bpfptr_t uattr_common, u32 size_common);
+struct bpf_verifier_log *bpf_log_attr_create_vlog(struct bpf_log_attr *attr_log,
+ struct bpf_common_attr *common, bpfptr_t uattr,
+ u32 size);
int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_log *log);
#define BPF_MAX_SUBPROGS 256
diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c
index fd12ad5a0338..62fe6ed18374 100644
--- a/kernel/bpf/log.c
+++ b/kernel/bpf/log.c
@@ -860,6 +860,35 @@ int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size, u32 l
return 0;
}
+struct bpf_verifier_log *bpf_log_attr_create_vlog(struct bpf_log_attr *attr_log,
+ struct bpf_common_attr *common, bpfptr_t uattr,
+ u32 size)
+{
+ struct bpf_verifier_log *log;
+ int err;
+
+ memset(attr_log, 0, sizeof(*attr_log));
+ attr_log->uattr = uattr;
+ if (size >= offsetofend(struct bpf_common_attr, log_true_size))
+ attr_log->offsetof_true_size = offsetof(struct bpf_common_attr, log_true_size);
+
+ if (!size)
+ return NULL;
+
+ log = kzalloc_obj(*log, GFP_KERNEL);
+ if (!log)
+ return ERR_PTR(-ENOMEM);
+
+ err = bpf_vlog_init(log, common->log_level, u64_to_user_ptr(common->log_buf),
+ common->log_size);
+ if (err) {
+ kfree(log);
+ return ERR_PTR(err);
+ }
+
+ return log;
+}
+
int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_log *log)
{
u32 log_true_size;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 2fa05ba8f161..54b43e16848a 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1359,7 +1359,7 @@ static int map_check_btf(struct bpf_map *map, struct bpf_token *token,
#define BPF_MAP_CREATE_LAST_FIELD excl_prog_hash_size
/* called via syscall */
-static int map_create(union bpf_attr *attr, bpfptr_t uattr)
+static int __map_create(union bpf_attr *attr, bpfptr_t uattr, struct bpf_verifier_log *log)
{
const struct bpf_map_ops *ops;
struct bpf_token *token = NULL;
@@ -1371,8 +1371,10 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
int err;
err = CHECK_ATTR(BPF_MAP_CREATE);
- if (err)
+ if (err) {
+ bpf_log(log, "Invalid attr.\n");
return -EINVAL;
+ }
/* check BPF_F_TOKEN_FD flag, remember if it's set, and then clear it
* to avoid per-map type checks tripping on unknown flag
@@ -1381,17 +1383,25 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
attr->map_flags &= ~BPF_F_TOKEN_FD;
if (attr->btf_vmlinux_value_type_id) {
- if (attr->map_type != BPF_MAP_TYPE_STRUCT_OPS ||
- attr->btf_key_type_id || attr->btf_value_type_id)
+ if (attr->map_type != BPF_MAP_TYPE_STRUCT_OPS) {
+ bpf_log(log, "btf_vmlinux_value_type_id can only be used with struct_ops maps.\n");
return -EINVAL;
+ }
+ if (attr->btf_key_type_id || attr->btf_value_type_id) {
+ bpf_log(log, "btf_vmlinux_value_type_id is mutually exclusive with btf_key_type_id and btf_value_type_id.\n");
+ return -EINVAL;
+ }
} else if (attr->btf_key_type_id && !attr->btf_value_type_id) {
+ bpf_log(log, "Invalid btf_value_type_id.\n");
return -EINVAL;
}
if (attr->map_type != BPF_MAP_TYPE_BLOOM_FILTER &&
attr->map_type != BPF_MAP_TYPE_ARENA &&
- attr->map_extra != 0)
+ attr->map_extra != 0) {
+ bpf_log(log, "Invalid map_extra.\n");
return -EINVAL;
+ }
f_flags = bpf_get_file_flag(attr->map_flags);
if (f_flags < 0)
@@ -1399,13 +1409,17 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
if (numa_node != NUMA_NO_NODE &&
((unsigned int)numa_node >= nr_node_ids ||
- !node_online(numa_node)))
+ !node_online(numa_node))) {
+ bpf_log(log, "Invalid numa_node.\n");
return -EINVAL;
+ }
/* find map type and init map: hashtable vs rbtree vs bloom vs ... */
map_type = attr->map_type;
- if (map_type >= ARRAY_SIZE(bpf_map_types))
+ if (map_type >= ARRAY_SIZE(bpf_map_types)) {
+ bpf_log(log, "Invalid map_type.\n");
return -EINVAL;
+ }
map_type = array_index_nospec(map_type, ARRAY_SIZE(bpf_map_types));
ops = bpf_map_types[map_type];
if (!ops)
@@ -1423,8 +1437,10 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
if (token_flag) {
token = bpf_token_get_from_fd(attr->map_token_fd);
- if (IS_ERR(token))
+ if (IS_ERR(token)) {
+ bpf_log(log, "Invalid map_token_fd.\n");
return PTR_ERR(token);
+ }
/* if current token doesn't grant map creation permissions,
* then we can't use this token, so ignore it and rely on
@@ -1507,8 +1523,10 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
err = bpf_obj_name_cpy(map->name, attr->map_name,
sizeof(attr->map_name));
- if (err < 0)
+ if (err < 0) {
+ bpf_log(log, "Invalid map_name.\n");
goto free_map;
+ }
preempt_disable();
map->cookie = gen_cookie_next(&bpf_map_cookie);
@@ -1531,6 +1549,7 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
btf = btf_get_by_fd(attr->btf_fd);
if (IS_ERR(btf)) {
+ bpf_log(log, "Invalid btf_fd.\n");
err = PTR_ERR(btf);
goto free_map;
}
@@ -1558,6 +1577,7 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
bpfptr_t uprog_hash = make_bpfptr(attr->excl_prog_hash, uattr.is_kernel);
if (attr->excl_prog_hash_size != SHA256_DIGEST_SIZE) {
+ bpf_log(log, "Invalid excl_prog_hash_size.\n");
err = -EINVAL;
goto free_map;
}
@@ -1573,6 +1593,7 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
goto free_map;
}
} else if (attr->excl_prog_hash_size) {
+ bpf_log(log, "Invalid excl_prog_hash_size.\n");
err = -EINVAL;
goto free_map;
}
@@ -1611,6 +1632,31 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
return err;
}
+static int map_create(union bpf_attr *attr, bpfptr_t uattr, struct bpf_common_attr *attr_common,
+ bpfptr_t uattr_common, u32 size_common)
+{
+ struct bpf_verifier_log *log;
+ struct bpf_log_attr attr_log;
+ int err, ret;
+
+ log = bpf_log_attr_create_vlog(&attr_log, attr_common, uattr_common, size_common);
+ if (IS_ERR(log))
+ return PTR_ERR(log);
+
+ err = __map_create(attr, uattr, log);
+
+ ret = bpf_log_attr_finalize(&attr_log, log);
+ if (ret) {
+ if (err >= 0)
+ close_fd(err);
+ err = ret;
+ }
+
+free:
+ kfree(log);
+ return err;
+}
+
void bpf_map_inc(struct bpf_map *map)
{
atomic64_inc(&map->refcnt);
@@ -6250,7 +6296,7 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
switch (cmd) {
case BPF_MAP_CREATE:
- err = map_create(&attr, uattr);
+ err = map_create(&attr, uattr, &attr_common, uattr_common, size_common);
break;
case BPF_MAP_LOOKUP_ELEM:
err = map_lookup_elem(&attr);
--
2.54.0
^ permalink raw reply related
* [PATCH bpf-next v13 7/8] libbpf: Add syscall common attributes support for map_create
From: Leon Hwang @ 2026-05-11 15:28 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Christian Brauner, Seth Forshee, Yuichiro Tsuji,
Andrey Albershteyn, Leon Hwang, Willem de Bruijn, Jason Xing,
Tao Chen, Mykyta Yatsenko, Kumar Kartikeya Dwivedi,
Anton Protopopov, Amery Hung, Rong Tao, linux-kernel, linux-api,
linux-kselftest, kernel-patches-bot
In-Reply-To: <20260511152817.89191-1-leon.hwang@linux.dev>
With the previous commit adding common attribute support for
BPF_MAP_CREATE, users can now retrieve detailed error messages when map
creation fails via the log_buf field.
Introduce struct bpf_log_opts with the following fields:
log_buf, log_size, log_level, and log_true_size.
Extend bpf_map_create_opts with a new field log_opts, allowing users to
capture and inspect log messages on map creation failures.
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
tools/lib/bpf/bpf.c | 16 +++++++++++++++-
tools/lib/bpf/bpf.h | 17 ++++++++++++++++-
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 9d8740761b7a..483c02cf21d1 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -209,6 +209,9 @@ int bpf_map_create(enum bpf_map_type map_type,
const struct bpf_map_create_opts *opts)
{
const size_t attr_sz = offsetofend(union bpf_attr, excl_prog_hash_size);
+ const size_t attr_common_sz = sizeof(struct bpf_common_attr);
+ struct bpf_common_attr attr_common;
+ struct bpf_log_opts *log_opts;
union bpf_attr attr;
int fd;
@@ -242,7 +245,18 @@ int bpf_map_create(enum bpf_map_type map_type,
attr.excl_prog_hash = ptr_to_u64(OPTS_GET(opts, excl_prog_hash, NULL));
attr.excl_prog_hash_size = OPTS_GET(opts, excl_prog_hash_size, 0);
- fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, attr_sz);
+ log_opts = OPTS_GET(opts, log_opts, NULL);
+ if (log_opts && feat_supported(NULL, FEAT_BPF_SYSCALL_COMMON_ATTRS)) {
+ memset(&attr_common, 0, attr_common_sz);
+ attr_common.log_buf = ptr_to_u64(OPTS_GET(log_opts, buf, NULL));
+ attr_common.log_size = OPTS_GET(log_opts, size, 0);
+ attr_common.log_level = OPTS_GET(log_opts, level, 0);
+ fd = sys_bpf_ext_fd(BPF_MAP_CREATE, &attr, attr_sz, &attr_common, attr_common_sz);
+ OPTS_SET(log_opts, true_size, attr_common.log_true_size);
+ } else {
+ fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, attr_sz);
+ OPTS_SET(log_opts, true_size, 0);
+ }
return libbpf_err_errno(fd);
}
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 2c8e88ddb674..2312900a3263 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -37,6 +37,18 @@ extern "C" {
LIBBPF_API int libbpf_set_memlock_rlim(size_t memlock_bytes);
+struct bpf_log_opts {
+ size_t sz; /* size of this struct for forward/backward compatibility */
+
+ char *buf;
+ __u32 size;
+ __u32 level;
+ __u32 true_size; /* out parameter set by kernel */
+
+ size_t :0;
+};
+#define bpf_log_opts__last_field true_size
+
struct bpf_map_create_opts {
size_t sz; /* size of this struct for forward/backward compatibility */
@@ -57,9 +69,12 @@ struct bpf_map_create_opts {
const void *excl_prog_hash;
__u32 excl_prog_hash_size;
+
+ struct bpf_log_opts *log_opts;
+
size_t :0;
};
-#define bpf_map_create_opts__last_field excl_prog_hash_size
+#define bpf_map_create_opts__last_field log_opts
LIBBPF_API int bpf_map_create(enum bpf_map_type map_type,
const char *map_name,
--
2.54.0
^ permalink raw reply related
* [PATCH bpf-next v13 8/8] selftests/bpf: Add tests to verify map create failure log
From: Leon Hwang @ 2026-05-11 15:28 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Christian Brauner, Seth Forshee, Yuichiro Tsuji,
Andrey Albershteyn, Leon Hwang, Willem de Bruijn, Jason Xing,
Tao Chen, Mykyta Yatsenko, Kumar Kartikeya Dwivedi,
Anton Protopopov, Amery Hung, Rong Tao, linux-kernel, linux-api,
linux-kselftest, kernel-patches-bot
In-Reply-To: <20260511152817.89191-1-leon.hwang@linux.dev>
Add tests to verify that the kernel reports the expected error messages
and correct log_true_size when map creation fails.
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
.../selftests/bpf/prog_tests/map_init.c | 166 ++++++++++++++++++
1 file changed, 166 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/map_init.c b/tools/testing/selftests/bpf/prog_tests/map_init.c
index 14a31109dd0e..5c61c8e37306 100644
--- a/tools/testing/selftests/bpf/prog_tests/map_init.c
+++ b/tools/testing/selftests/bpf/prog_tests/map_init.c
@@ -212,3 +212,169 @@ void test_map_init(void)
if (test__start_subtest("pcpu_lru_map_init"))
test_pcpu_lru_map_init();
}
+
+static void test_map_create(enum bpf_map_type map_type, const char *map_name,
+ struct bpf_map_create_opts *opts, const char *exp_msg)
+{
+ const int key_size = 4, value_size = 4, max_entries = 1;
+ char log_buf[128];
+ int fd;
+ LIBBPF_OPTS(bpf_log_opts, log_opts);
+
+ log_buf[0] = '\0';
+ log_opts.buf = log_buf;
+ log_opts.size = sizeof(log_buf);
+ log_opts.level = 1;
+ opts->log_opts = &log_opts;
+ fd = bpf_map_create(map_type, map_name, key_size, value_size, max_entries, opts);
+ if (!ASSERT_LT(fd, 0, "bpf_map_create")) {
+ close(fd);
+ return;
+ }
+
+ ASSERT_STREQ(log_buf, exp_msg, "log_buf");
+ ASSERT_EQ(log_opts.true_size, strlen(exp_msg) + 1, "true_size");
+}
+
+static void test_map_create_array(struct bpf_map_create_opts *opts, const char *exp_msg)
+{
+ test_map_create(BPF_MAP_TYPE_ARRAY, "test_map_create", opts, exp_msg);
+}
+
+static void test_invalid_vmlinux_value_type_id_struct_ops(void)
+{
+ const char *msg = "btf_vmlinux_value_type_id can only be used with struct_ops maps.\n";
+ LIBBPF_OPTS(bpf_map_create_opts, opts,
+ .btf_vmlinux_value_type_id = 1,
+ );
+
+ test_map_create_array(&opts, msg);
+}
+
+static void test_invalid_vmlinux_value_type_id_kv_type_id(void)
+{
+ const char *msg = "btf_vmlinux_value_type_id is mutually exclusive with btf_key_type_id and btf_value_type_id.\n";
+ LIBBPF_OPTS(bpf_map_create_opts, opts,
+ .btf_vmlinux_value_type_id = 1,
+ .btf_key_type_id = 1,
+ );
+
+ test_map_create(BPF_MAP_TYPE_STRUCT_OPS, "test_map_create", &opts, msg);
+}
+
+static void test_invalid_value_type_id(void)
+{
+ const char *msg = "Invalid btf_value_type_id.\n";
+ LIBBPF_OPTS(bpf_map_create_opts, opts,
+ .btf_key_type_id = 1,
+ );
+
+ test_map_create_array(&opts, msg);
+}
+
+static void test_invalid_map_extra(void)
+{
+ const char *msg = "Invalid map_extra.\n";
+ LIBBPF_OPTS(bpf_map_create_opts, opts,
+ .map_extra = 1,
+ );
+
+ test_map_create_array(&opts, msg);
+}
+
+static void test_invalid_numa_node(void)
+{
+ const char *msg = "Invalid numa_node.\n";
+ LIBBPF_OPTS(bpf_map_create_opts, opts,
+ .map_flags = BPF_F_NUMA_NODE,
+ .numa_node = 0xFF,
+ );
+
+ test_map_create_array(&opts, msg);
+}
+
+static void test_invalid_map_type(void)
+{
+ const char *msg = "Invalid map_type.\n";
+ LIBBPF_OPTS(bpf_map_create_opts, opts);
+
+ test_map_create(__MAX_BPF_MAP_TYPE, "test_map_create", &opts, msg);
+}
+
+static void test_invalid_token_fd(void)
+{
+ const char *msg = "Invalid map_token_fd.\n";
+ LIBBPF_OPTS(bpf_map_create_opts, opts,
+ .map_flags = BPF_F_TOKEN_FD,
+ .token_fd = 0xFF,
+ );
+
+ test_map_create_array(&opts, msg);
+}
+
+static void test_invalid_map_name(void)
+{
+ const char *msg = "Invalid map_name.\n";
+ LIBBPF_OPTS(bpf_map_create_opts, opts);
+
+ test_map_create(BPF_MAP_TYPE_ARRAY, "test-!@#", &opts, msg);
+}
+
+static void test_invalid_btf_fd(void)
+{
+ const char *msg = "Invalid btf_fd.\n";
+ LIBBPF_OPTS(bpf_map_create_opts, opts,
+ .btf_fd = -1,
+ .btf_key_type_id = 1,
+ .btf_value_type_id = 1,
+ );
+
+ test_map_create_array(&opts, msg);
+}
+
+static void test_excl_prog_hash_size_1(void)
+{
+ const char *msg = "Invalid excl_prog_hash_size.\n";
+ const char *hash = "DEADCODE";
+ LIBBPF_OPTS(bpf_map_create_opts, opts,
+ .excl_prog_hash = hash,
+ );
+
+ test_map_create_array(&opts, msg);
+}
+
+static void test_excl_prog_hash_size_2(void)
+{
+ const char *msg = "Invalid excl_prog_hash_size.\n";
+ LIBBPF_OPTS(bpf_map_create_opts, opts,
+ .excl_prog_hash_size = 1,
+ );
+
+ test_map_create_array(&opts, msg);
+}
+
+void test_map_create_failure(void)
+{
+ if (test__start_subtest("invalid_vmlinux_value_type_id_struct_ops"))
+ test_invalid_vmlinux_value_type_id_struct_ops();
+ if (test__start_subtest("invalid_vmlinux_value_type_id_kv_type_id"))
+ test_invalid_vmlinux_value_type_id_kv_type_id();
+ if (test__start_subtest("invalid_value_type_id"))
+ test_invalid_value_type_id();
+ if (test__start_subtest("invalid_map_extra"))
+ test_invalid_map_extra();
+ if (test__start_subtest("invalid_numa_node"))
+ test_invalid_numa_node();
+ if (test__start_subtest("invalid_map_type"))
+ test_invalid_map_type();
+ if (test__start_subtest("invalid_token_fd"))
+ test_invalid_token_fd();
+ if (test__start_subtest("invalid_map_name"))
+ test_invalid_map_name();
+ if (test__start_subtest("invalid_btf_fd"))
+ test_invalid_btf_fd();
+ if (test__start_subtest("invalid_excl_prog_hash_size_1"))
+ test_excl_prog_hash_size_1();
+ if (test__start_subtest("invalid_excl_prog_hash_size_2"))
+ test_excl_prog_hash_size_2();
+}
--
2.54.0
^ permalink raw reply related
* Re: [PATCH bpf-next v13 6/8] bpf: Add syscall common attributes support for map_create
From: bot+bpf-ci @ 2026-05-11 16:19 UTC (permalink / raw)
To: leon.hwang, bpf
Cc: ast, daniel, john.fastabend, andrii, martin.lau, eddyz87, song,
yonghong.song, kpsingh, sdf, haoluo, jolsa, shuah, brauner,
sforshee, yuichtsu, aalbersh, leon.hwang, willemb,
kerneljasonxing, chen.dylane, yatsenko, memxor, a.s.protopopov,
ameryhung, rongtao, linux-kernel, linux-api, linux-kselftest,
kernel-patches-bot, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260511152817.89191-7-leon.hwang@linux.dev>
[-- Attachment #1: Type: text/plain, Size: 2969 bytes --]
> diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
> index 8433430dedb7..c15a4c26a43b 100644
> --- a/include/linux/bpf_verifier.h
> +++ b/include/linux/bpf_verifier.h
[ ... ]
> diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c
> index fd12ad5a0338..62fe6ed18374 100644
> --- a/kernel/bpf/log.c
> +++ b/kernel/bpf/log.c
[ ... ]
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index 2fa05ba8f161..54b43e16848a 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
[ ... ]
> @@ -1611,6 +1632,31 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
> return err;
> }
>
> +static int map_create(union bpf_attr *attr, bpfptr_t uattr, struct bpf_common_attr *attr_common,
> + bpfptr_t uattr_common, u32 size_common)
> +{
> + struct bpf_verifier_log *log;
> + struct bpf_log_attr attr_log;
> + int err, ret;
> +
> + log = bpf_log_attr_create_vlog(&attr_log, attr_common, uattr_common, size_common);
> + if (IS_ERR(log))
> + return PTR_ERR(log);
> +
> + err = __map_create(attr, uattr, log);
> +
> + ret = bpf_log_attr_finalize(&attr_log, log);
> + if (ret) {
> + if (err >= 0)
> + close_fd(err);
> + err = ret;
When bpf_log_attr_finalize() returns an error (say -ENOSPC for log buffer
truncation or -EFAULT for copy_to_user failure) after __map_create() already
returned a negative error (for example -EINVAL from CHECK_ATTR or -EPERM from
security checks), does it make sense to overwrite the original map creation
error with the log finalization error?
The result is that userspace receives -ENOSPC or -EFAULT instead of the
actual reason the map creation failed. A user with an undersized log buffer
might retry with a larger buffer expecting success, when the real issue is
that the map creation itself was rejected for a different reason.
Looking at bpf_check() in kernel/bpf/verifier.c (around the verifier log
finalization), it uses similar logic with 'err = ret;' reassignment. However,
that doesn't appear to have the preserve-original-error comment that would
clarify the intended behavior for this scenario.
> + }
> +
> +free:
Does anything use this free: label? The only exit path before it is the early
return for IS_ERR(log), which correctly returns directly since log is an error
pointer and doesn't need cleanup. There doesn't seem to be any 'goto free;'
statement in the function.
With -Wunused-label enabled by default in the kernel build (part of -Wall),
this will generate a compiler warning. When building with -Werror (common in
CI configurations and allmodconfig builds), this would break the build.
> + kfree(log);
> + return err;
> +}
> +
> void bpf_map_inc(struct bpf_map *map)
> {
> atomic64_inc(&map->refcnt);
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/25680759838
^ permalink raw reply
* Re: [PATCH bpf-next v13 1/8] bpf: Extend BPF syscall with common attributes support
From: bot+bpf-ci @ 2026-05-11 16:19 UTC (permalink / raw)
To: leon.hwang, bpf
Cc: ast, daniel, john.fastabend, andrii, martin.lau, eddyz87, song,
yonghong.song, kpsingh, sdf, haoluo, jolsa, shuah, brauner,
sforshee, yuichtsu, aalbersh, leon.hwang, willemb,
kerneljasonxing, chen.dylane, yatsenko, memxor, a.s.protopopov,
ameryhung, rongtao, linux-kernel, linux-api, linux-kselftest,
kernel-patches-bot, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260511152817.89191-2-leon.hwang@linux.dev>
[-- Attachment #1: Type: text/plain, Size: 2824 bytes --]
> diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> index f5639d5ac331..50055ab73649 100644
> --- a/include/linux/syscalls.h
> +++ b/include/linux/syscalls.h
> @@ -936,7 +936,8 @@ asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
> asmlinkage long sys_getrandom(char __user *buf, size_t count,
> unsigned int flags);
> asmlinkage long sys_memfd_create(const char __user *uname_ptr, unsigned int flags);
> -asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int size);
> +asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int size,
> + struct bpf_common_attr __user *attr_common, unsigned int size_common);
> asmlinkage long sys_execveat(int dfd, const char __user *filename,
> const char __user *const __user *argv,
> const char __user *const __user *envp, int flags);
[ ... ]
> diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
> index 677be9a47347..16ff0968fc21 100644
> --- a/tools/include/uapi/linux/bpf.h
> +++ b/tools/include/uapi/linux/bpf.h
> @@ -994,6 +994,7 @@ enum bpf_cmd {
> BPF_PROG_STREAM_READ_BY_FD,
> BPF_PROG_ASSOC_STRUCT_OPS,
> __MAX_BPF_CMD,
> + BPF_COMMON_ATTRS = 1 << 16, /* Indicate carrying syscall common attrs. */
> };
[ ... ]
> @@ -1500,6 +1501,13 @@ struct bpf_stack_build_id {
> };
> };
>
> +struct bpf_common_attr {
> + __u64 log_buf;
> + __u32 log_size;
> + __u32 log_level;
> + __u32 log_true_size;
> +};
> +
Should log_buf use __aligned_u64 instead of plain __u64?
Looking at other pointer-bearing fields in the BPF UAPI, they consistently
use __aligned_u64. For example, the existing BPF_PROG_LOAD log_buf in union
bpf_attr is declared as:
__aligned_u64 log_buf; /* user supplied buffer */
The __aligned_u64 attribute forces 8-byte alignment on all architectures,
including 32-bit systems where native unsigned long long alignment is only
4 bytes. Without this attribute, struct bpf_common_attr will have different
layouts between 32-bit and 64-bit ABIs:
- 32-bit: 20 bytes, 4-byte aligned
- 64-bit: 24 bytes (4 bytes of tail padding), 8-byte aligned
While the current __sys_bpf() implementation with bpf_check_uarg_tail_zero()
and min_t() capped copying handles this gracefully, deviating from the
established BPF UAPI convention could create problems for future extensions.
If another __u64 field is added later, the inter-field offsets would diverge
between ABIs.
Would it be better to use __aligned_u64 log_buf to match union bpf_attr and
preserve identical struct layouts across 32/64-bit ABIs?
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/25680759838
^ permalink raw reply
* Re: [PATCH bpf-next v13 1/8] bpf: Extend BPF syscall with common attributes support
From: Alexei Starovoitov @ 2026-05-11 16:53 UTC (permalink / raw)
To: bot+bpf-ci, leon.hwang, bpf
Cc: ast, daniel, john.fastabend, andrii, martin.lau, eddyz87, song,
yonghong.song, kpsingh, sdf, haoluo, jolsa, shuah, brauner,
sforshee, yuichtsu, aalbersh, willemb, kerneljasonxing,
chen.dylane, yatsenko, memxor, a.s.protopopov, ameryhung, rongtao,
linux-kernel, linux-api, linux-kselftest, kernel-patches-bot,
martin.lau, clm, ihor.solodrai
In-Reply-To: <810f123d14450d09d147d90dea25ddf5091e636542fcc5729d0594bfbd622757@mail.kernel.org>
On Mon May 11, 2026 at 9:19 AM PDT, bot+bpf-ci wrote:
>> diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
>> index f5639d5ac331..50055ab73649 100644
>> --- a/include/linux/syscalls.h
>> +++ b/include/linux/syscalls.h
>> @@ -936,7 +936,8 @@ asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
>> asmlinkage long sys_getrandom(char __user *buf, size_t count,
>> unsigned int flags);
>> asmlinkage long sys_memfd_create(const char __user *uname_ptr, unsigned int flags);
>> -asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int size);
>> +asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int size,
>> + struct bpf_common_attr __user *attr_common, unsigned int size_common);
>> asmlinkage long sys_execveat(int dfd, const char __user *filename,
>> const char __user *const __user *argv,
>> const char __user *const __user *envp, int flags);
>
> [ ... ]
>
>> diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
>> index 677be9a47347..16ff0968fc21 100644
>> --- a/tools/include/uapi/linux/bpf.h
>> +++ b/tools/include/uapi/linux/bpf.h
>> @@ -994,6 +994,7 @@ enum bpf_cmd {
>> BPF_PROG_STREAM_READ_BY_FD,
>> BPF_PROG_ASSOC_STRUCT_OPS,
>> __MAX_BPF_CMD,
>> + BPF_COMMON_ATTRS = 1 << 16, /* Indicate carrying syscall common attrs. */
>> };
>
> [ ... ]
>
>> @@ -1500,6 +1501,13 @@ struct bpf_stack_build_id {
>> };
>> };
>>
>> +struct bpf_common_attr {
>> + __u64 log_buf;
>> + __u32 log_size;
>> + __u32 log_level;
>> + __u32 log_true_size;
>> +};
>> +
>
> Should log_buf use __aligned_u64 instead of plain __u64?
>
> Looking at other pointer-bearing fields in the BPF UAPI, they consistently
> use __aligned_u64. For example, the existing BPF_PROG_LOAD log_buf in union
> bpf_attr is declared as:
>
> __aligned_u64 log_buf; /* user supplied buffer */
>
> The __aligned_u64 attribute forces 8-byte alignment on all architectures,
> including 32-bit systems where native unsigned long long alignment is only
> 4 bytes. Without this attribute, struct bpf_common_attr will have different
> layouts between 32-bit and 64-bit ABIs:
>
> - 32-bit: 20 bytes, 4-byte aligned
> - 64-bit: 24 bytes (4 bytes of tail padding), 8-byte aligned
>
> While the current __sys_bpf() implementation with bpf_check_uarg_tail_zero()
> and min_t() capped copying handles this gracefully, deviating from the
> established BPF UAPI convention could create problems for future extensions.
> If another __u64 field is added later, the inter-field offsets would diverge
> between ABIs.
>
> Would it be better to use __aligned_u64 log_buf to match union bpf_attr and
> preserve identical struct layouts across 32/64-bit ABIs?
bot has a point.
pw-bot: cr
^ permalink raw reply
* Re: [PATCH bpf-next v13 6/8] bpf: Add syscall common attributes support for map_create
From: Alexei Starovoitov @ 2026-05-11 17:07 UTC (permalink / raw)
To: bot+bpf-ci, leon.hwang, bpf
Cc: ast, daniel, john.fastabend, andrii, martin.lau, eddyz87, song,
yonghong.song, kpsingh, sdf, haoluo, jolsa, shuah, brauner,
sforshee, yuichtsu, aalbersh, willemb, kerneljasonxing,
chen.dylane, yatsenko, memxor, a.s.protopopov, ameryhung, rongtao,
linux-kernel, linux-api, linux-kselftest, kernel-patches-bot,
martin.lau, clm, ihor.solodrai
In-Reply-To: <fad54bcc2f9363f61cda44680e7189ad7a510d81dc52f444a4c30a3fcd37df1d@mail.kernel.org>
On Mon May 11, 2026 at 9:19 AM PDT, bot+bpf-ci wrote:
>> diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
>> index 8433430dedb7..c15a4c26a43b 100644
>> --- a/include/linux/bpf_verifier.h
>> +++ b/include/linux/bpf_verifier.h
>
> [ ... ]
>
>> diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c
>> index fd12ad5a0338..62fe6ed18374 100644
>> --- a/kernel/bpf/log.c
>> +++ b/kernel/bpf/log.c
>
> [ ... ]
>
>> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
>> index 2fa05ba8f161..54b43e16848a 100644
>> --- a/kernel/bpf/syscall.c
>> +++ b/kernel/bpf/syscall.c
>
> [ ... ]
>
>> @@ -1611,6 +1632,31 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr)
>> return err;
>> }
>>
>> +static int map_create(union bpf_attr *attr, bpfptr_t uattr, struct bpf_common_attr *attr_common,
>> + bpfptr_t uattr_common, u32 size_common)
>> +{
>> + struct bpf_verifier_log *log;
>> + struct bpf_log_attr attr_log;
>> + int err, ret;
>> +
>> + log = bpf_log_attr_create_vlog(&attr_log, attr_common, uattr_common, size_common);
>> + if (IS_ERR(log))
>> + return PTR_ERR(log);
>> +
>> + err = __map_create(attr, uattr, log);
>> +
>> + ret = bpf_log_attr_finalize(&attr_log, log);
>> + if (ret) {
>> + if (err >= 0)
>> + close_fd(err);
>> + err = ret;
>
> When bpf_log_attr_finalize() returns an error (say -ENOSPC for log buffer
> truncation or -EFAULT for copy_to_user failure) after __map_create() already
> returned a negative error (for example -EINVAL from CHECK_ATTR or -EPERM from
> security checks), does it make sense to overwrite the original map creation
> error with the log finalization error?
>
> The result is that userspace receives -ENOSPC or -EFAULT instead of the
> actual reason the map creation failed. A user with an undersized log buffer
> might retry with a larger buffer expecting success, when the real issue is
> that the map creation itself was rejected for a different reason.
>
> Looking at bpf_check() in kernel/bpf/verifier.c (around the verifier log
> finalization), it uses similar logic with 'err = ret;' reassignment. However,
> that doesn't appear to have the preserve-original-error comment that would
> clarify the intended behavior for this scenario.
I guess sinle line comment wouldn't hurt.
>
>> + }
>> +
>> +free:
>
> Does anything use this free: label? The only exit path before it is the early
> return for IS_ERR(log), which correctly returns directly since log is an error
> pointer and doesn't need cleanup. There doesn't seem to be any 'goto free;'
> statement in the function.
>
> With -Wunused-label enabled by default in the kernel build (part of -Wall),
> this will generate a compiler warning. When building with -Werror (common in
> CI configurations and allmodconfig builds), this would break the build.
good point. pls fix.
^ permalink raw reply
* Re: [PATCH] crypto: af_alg - Document the deprecation of AF_ALG
From: Ignat Korchagin @ 2026-05-11 21:03 UTC (permalink / raw)
To: Eric Biggers, Kamran Khan
Cc: Jeff Barnes, Andy Lutomirski, linux-crypto@vger.kernel.org,
Herbert Xu, linux-doc@vger.kernel.org, linux-api@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Linus Torvalds
In-Reply-To: <20260510163204.GA2279@sol>
On 10/05/2026 17:32, Eric Biggers wrote:
> On Sun, May 10, 2026 at 08:54:07AM -0700, Kamran Khan wrote:
>> Hi,
>>
>> AF_ALG is useful not just for hardware-offloading, but also for memory
>> isolation so that applications only get oracle access to the crypto keys and
>> a memory-safety vulnerability in user applications would not immediately put
>> the secret key material at risk.
> Note that if that memory-safety vulnerability leads to code execution in
> the application, then it doesn't matter that it "only" has oracle
> access. It can still decrypt any data encrypted by that key.
I don't think fully discounting hardware offloading is beneficial here.
HW accelerators will be produced and without a common interface vendors
would start implementing their own "bespoke" drivers with bespoke
userspace interfaces (we already had such proposals), which in turn may
introduce more attack surface. Yes, AF_ALG needs substantial
improvement, but at least it can be a standardisation point.
> The relevant threat model would be arbitrary reads, not any
> "memory-safety vulnerability".
>
>> I understand and appreciate the concern with complex attack surface and the
>> increased frequency of attacks in this area. But I fear that completely
>> removing AF_ALG increases the risk for userspace applications relying on it
>> for memory isolation.
>>
>> What alternatives do userspace applications have on Linux for ensuring
>> crypto keys are not exposed in user memory? That is, FreeBSD and NetBSD
>> natively provide /dev/crypto; removing AF_ALG would kill the only equivalent
>> option on the Linux side for kernel-delegated cryptography.
> The standard solution is simply to use an isolated userspace process
> like ssh-agent. Yes, the keys will be in "user memory". But "not
> exposed in user memory" is *not* a correct statement of the problem.
>
> (Also note that protecting not-actively-in-use data from arbitrary read
> primitives doesn't require cryptography at all. That can be done simply
> by using mprotect() to remove read permission from the memory, then
> temporarily adding it back when it needs to be accessed.)
>
> In any case, any hypothetical security benefit provided by AF_ALG would
> have to be *very high* to outweigh the continuous stream of
> vulnerabilities in it. I understand that people using AF_ALG might not
> be familiar with that continuous stream of vulnerabilities, but it would
Is it actually that much compared to other features/subsystems, like
eBPF or user namespaces? But we don't rush to deprecate those - instead
trying to harden them and come up with better design.
> be worth spending some time researching what has been going on.
>
> - Eric
Ignat
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox