[PATCH 09/24] xfs: use an empty transaction to protect xfs_attr_get from deadlocks

Andrey Albershteyn
2024-12-29T13:40:03Z

From: "Darrick J. Wong" <djwong@kernel.org>

Wrap the xfs_attr_get_ilocked call in xfs_attr_get with an empty
transaction so that we cannot livelock the kernel if someone injects a
loop into the attr structure or the attr fork bmbt.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/libxfs/xfs_attr.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index e452ca55241f..3f3699e9c203 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -274,6 +274,8 @@ xfs_attr_get(

XFS_STATS_INC(args->dp->i_mount, xs_attr_get);

+ ASSERT(!args->trans);
+
if (xfs_is_shutdown(args->dp->i_mount))
return -EIO;

@@ -286,8 +288,14 @@ xfs_attr_get(
/* Entirely possible to look up a name which doesn't exist */
args->op_flags = XFS_DA_OP_OKNOENT;

+ error = xfs_trans_alloc_empty(args->dp->i_mount, &args->trans);
+ if (error)
+ return error;
+
lock_mode = xfs_ilock_attr_map_shared(args->dp);
error = xfs_attr_get_ilocked(args);
+ xfs_trans_cancel(args->trans);
+ args->trans = NULL;
xfs_iunlock(args->dp, lock_mode);

return error;
--
2.47.0