diff --git a/patches.suse/NFSv4.2-fix-listxattr-maximum-XDR-buffer-size.patch b/patches.suse/NFSv4.2-fix-listxattr-maximum-XDR-buffer-size.patch new file mode 100644 index 0000000..af24835 --- /dev/null +++ b/patches.suse/NFSv4.2-fix-listxattr-maximum-XDR-buffer-size.patch @@ -0,0 +1,54 @@ +From: Jorge Mora +Date: Thu, 25 Jan 2024 07:51:28 -0700 +Subject: [PATCH] NFSv4.2: fix listxattr maximum XDR buffer size +Git-commit: bcac8bff90a6ee1629f90669cdb9d28fb86049b0 +Patch-mainline: v6.9-rc1 +References: git-fixes + +Switch order of operations to avoid creating a short XDR buffer: +e.g., buflen = 12, old xdrlen = 12, new xdrlen = 20. + +Having a short XDR buffer leads to lxa_maxcount be a few bytes +less than what is needed to retrieve the whole list when using +a buflen as returned by a call with size = 0: + buflen = listxattr(path, NULL, 0); + buf = malloc(buflen); + buflen = listxattr(path, buf, buflen); + +For a file with one attribute (name = '123456'), the first call +with size = 0 will return buflen = 12 ('user.123456\x00'). +The second call with size = 12, sends LISTXATTRS with +lxa_maxcount = 12 + 8 (cookie) + 4 (array count) = 24. The +XDR buffer needs 8 (cookie) + 4 (array count) + 4 (name count) ++ 6 (name len) + 2 (padding) + 4 (eof) = 28 which is 4 bytes +shorter than the lxa_maxcount provided in the call. + +Fixes: 04a5da690e8f ("NFSv4.2: define limits and sizes for user xattr handling") +Signed-off-by: Jorge Mora +Reviewed-by: Benjamin Coddington +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/nfs42.h | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/fs/nfs/nfs42.h ++++ b/fs/nfs/nfs42.h +@@ -54,11 +54,14 @@ int nfs42_proc_removexattr(struct inode + * They would be 7 bytes long in the eventual buffer ("user.x\0"), and + * 8 bytes long XDR-encoded. + * +- * Include the trailing eof word as well. ++ * Include the trailing eof word as well and make the result a multiple ++ * of 4 bytes. + */ + static inline u32 nfs42_listxattr_xdrsize(u32 buflen) + { +- return ((buflen / (XATTR_USER_PREFIX_LEN + 2)) * 8) + 4; ++ u32 size = 8 * buflen / (XATTR_USER_PREFIX_LEN + 2) + 4; ++ ++ return (size + 3) & ~3; + } + #endif /* CONFIG_NFS_V4_2 */ + #endif /* __LINUX_FS_NFS_NFS4_2_H */ diff --git a/series.conf b/series.conf index 0b5a719..160e554 100644 --- a/series.conf +++ b/series.conf @@ -45693,6 +45693,7 @@ patches.suse/nilfs2-prevent-kernel-bug-at-submit_bh_wbc.patch patches.suse/net-sunrpc-Fix-an-off-by-one-in-rpc_sockaddr2uaddr.patch patches.suse/NFSv4.2-fix-nfs4_listxattr-kernel-BUG-at-mm-usercopy.patch + patches.suse/NFSv4.2-fix-listxattr-maximum-XDR-buffer-size.patch # jejb/scsi for-next patches.suse/scsi-lpfc-Initialize-status-local-variable-in-lpfc_s.patch