lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <8feeeec8-7330-47ae-9b54-9e789ebdfae5@gmail.com>
Date: Wed, 4 Feb 2026 16:09:02 +0100
From: Simon Weber <simon.weber.39@...il.com>
To: linux-ext4@...r.kernel.org, linux-kernel@...r.kernel.org,
 Theodore Ts'o <tytso@....edu>, Andreas Dilger <adilger.kernel@...ger.ca>,
 anthonydev@...tmail.com
Subject: [PATCH v1] ext4: fix journal credit check when setting fscrypt
 context xattr

From: Simon Weber <simon.weber.39@...il.com>

When creating a new inode, the required number of jbd2 journalling credits
is conservatively estimated by summing up the credits required for various
actions. This includes setting the xattrs for example for ACLs and the
fscrypt context. Since the inode is new and has no xattrs, the estimation
of credits needed for creating these xattrs is performed by passing
is_create=true into the function __ext4_xattr_set_credits, which yields a
lower number of credits than when is_create is false. However, following
the control flow until the fscrypt context xattr is actually set, the
XATTR_CREATE flag is not passed by ext4_set_context to
ext4_xattr_set_handle. This causes the latter function to compare the
remaining credits against the value of __ext4_xattr_set_credits(...,
is_create=false), which may be too much. This flawed design does not
usually cause any issues unless the filesystem features has_journal,
ea_inode, and encrypt are all present at the same time. In this case,
creating a file in any fscrypt-encrypted directory will always return
ENOSPC.
This patch fixes this issue by passing the XATTR_CREATE flag in the
ext4_set_context function. This is safe since ext4_set_context is only
called when creating a new inode (in which case the context xattr is not
present yet) or when setting the encryption policy on an existing file
using the FS_IOC_SET_ENCRYPTION_POLICY ioctl, which however first checks
that the file does not currently have an encryption policy set. When
calling ext4_set_context it is therefore not undesirable behaviour to
possibly fail with an EEXIST error due to the XATTR_CREATE flag and the
context xattr already being present.

Co-developed-by: Anthony Durrer <anthonydev@...tmail.com>
Signed-off-by: Anthony Durrer <anthonydev@...tmail.com>
Signed-off-by: Simon Weber <simon.weber.39@...il.com>
---
 fs/ext4/crypto.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
index cf0a0970c095..5b665f85f6a7 100644
--- a/fs/ext4/crypto.c
+++ b/fs/ext4/crypto.c
@@ -163,10 +163,20 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
      */
 
     if (handle) {
+        /*
+         * Set the xattr using the XATTR_CREATE flag, since this function should
+         * only be called on inodes that do not have an encryption context yet.
+         * Since when estimating the number of credits needed for the new inode
+         * we called ext4_xattr_set with is_create = true, we need to pass this
+         * flag, otherwise the check for remaining credits is too conservative
+         * and may fail.
+         * If for some reason the inode already has an encryption context, this
+         * fails with EEXIST, which is desirable behaviour.
+         */
         res = ext4_xattr_set_handle(handle, inode,
                         EXT4_XATTR_INDEX_ENCRYPTION,
                         EXT4_XATTR_NAME_ENCRYPTION_CONTEXT,
-                        ctx, len, 0);
+                        ctx, len, XATTR_CREATE);
         if (!res) {
             ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
             ext4_clear_inode_state(inode,

base-commit: 4f5e8e6f012349a107531b02eed5b5ace6181449
-- 
2.49.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ