mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
smb: client: fix unaligned access in WSL reparse point parser
When wsl_to_fattr() parses WSL extended attributes, it computes a
payload pointer from ea->ea_data + ea_name_length + 1. Since the
smb2_file_full_ea_info struct is __packed and all WSL xattr names are
6 bytes long, the value pointer always lands at an odd byte offset,
never satisfying __le32 or __le64 alignment requirements.
The code then casts this pointer to __le32 * or __le64 * and
dereferences it directly, which may cause alignment faults on some
architectures.
Replace all such casts with get_unaligned_le32() and
get_unaligned_le64() in reparse_mkdev(), wsl_make_kuid(),
wsl_make_kgid() and wsl_to_fattr().
Closes: https://sashiko.dev/#/patchset/20260906200517.725015-1-pc%40manguebit.org
Fixes: 78e26bec4d ("smb: client: parse uid, gid, mode and dev from WSL reparse points")
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
This commit is contained in:
parent
e75c96157d
commit
e1aeaf79de
|
|
@ -1201,9 +1201,9 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,
|
|||
fattr->cf_gid = wsl_make_kgid(cifs_sb, v);
|
||||
} else if (!strncmp(name, SMB2_WSL_XATTR_MODE, nlen)) {
|
||||
/* File type in reparse point tag and in xattr mode must match. */
|
||||
if (S_DT(fattr->cf_mode) != S_DT(le32_to_cpu(*(__le32 *)v)))
|
||||
if (S_DT(fattr->cf_mode) != S_DT(get_unaligned_le32(v)))
|
||||
return false;
|
||||
fattr->cf_mode = (umode_t)le32_to_cpu(*(__le32 *)v);
|
||||
fattr->cf_mode = (umode_t)get_unaligned_le32(v);
|
||||
} else if (!strncmp(name, SMB2_WSL_XATTR_DEV, nlen)) {
|
||||
fattr->cf_rdev = reparse_mkdev(v);
|
||||
have_xattr_dev = true;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/fs.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/uidgid.h>
|
||||
#include <linux/unaligned.h>
|
||||
#include "fs_context.h"
|
||||
#include "cifsglob.h"
|
||||
#include "../common/smbfsctl.h"
|
||||
|
|
@ -23,7 +24,7 @@
|
|||
|
||||
static inline dev_t reparse_mkdev(void *ptr)
|
||||
{
|
||||
u64 v = le64_to_cpu(*(__le64 *)ptr);
|
||||
u64 v = get_unaligned_le64(ptr);
|
||||
|
||||
return MKDEV(v & 0xffffffff, v >> 32);
|
||||
}
|
||||
|
|
@ -31,7 +32,7 @@ static inline dev_t reparse_mkdev(void *ptr)
|
|||
static inline kuid_t wsl_make_kuid(struct cifs_sb_info *cifs_sb,
|
||||
void *ptr)
|
||||
{
|
||||
u32 uid = le32_to_cpu(*(__le32 *)ptr);
|
||||
u32 uid = get_unaligned_le32(ptr);
|
||||
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_OVERR_UID)
|
||||
return cifs_sb->ctx->linux_uid;
|
||||
|
|
@ -41,7 +42,7 @@ static inline kuid_t wsl_make_kuid(struct cifs_sb_info *cifs_sb,
|
|||
static inline kgid_t wsl_make_kgid(struct cifs_sb_info *cifs_sb,
|
||||
void *ptr)
|
||||
{
|
||||
u32 gid = le32_to_cpu(*(__le32 *)ptr);
|
||||
u32 gid = get_unaligned_le32(ptr);
|
||||
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_OVERR_GID)
|
||||
return cifs_sb->ctx->linux_gid;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user