Commit a36e1fb7 authored by Pali Rohár's avatar Pali Rohár Committed by Wentao Guan
Browse files

cifs: Fix getting and setting SACLs over SMB1

stable inclusion
from stable-v6.6.76
commit 089d1c188a5a448776a50f69e3e8fe5dc012f683
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBW08Q

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=089d1c188a5a448776a50f69e3e8fe5dc012f683



--------------------------------

[ Upstream commit 8b19dfb34d17e77a0809d433cc128b779282131b ]

SMB1 callback get_cifs_acl_by_fid() currently ignores its last argument and
therefore ignores request for SACL_SECINFO. Fix this issue by correctly
propagating info argument from get_cifs_acl() and get_cifs_acl_by_fid() to
CIFSSMBGetCIFSACL() function and pass SACL_SECINFO when requested.

For accessing SACLs it is needed to open object with SYSTEM_SECURITY
access. Pass this flag when trying to get or set SACLs.

Same logic is in the SMB2+ code path.

This change fixes getting and setting of "system.cifs_ntsd_full" and
"system.smb3_ntsd_full" xattrs over SMB1 as currently it silentely ignored
SACL part of passed xattr buffer.

Fixes: 3970acf7 ("SMB3: Add support for getting and setting SACLs")
Signed-off-by: default avatarPali Rohár <pali@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
(cherry picked from commit 089d1c188a5a448776a50f69e3e8fe5dc012f683)
Signed-off-by: default avatarWentao Guan <guanwentao@uniontech.com>
parent ea4d33b7
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -1395,7 +1395,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
				      const struct cifs_fid *cifsfid, u32 *pacllen,
				      u32 __maybe_unused unused)
				      u32 info)
{
	struct smb_ntsd *pntsd = NULL;
	unsigned int xid;
@@ -1407,7 +1407,7 @@ struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,

	xid = get_xid();
	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
				pacllen);
				pacllen, info);
	free_xid(xid);

	cifs_put_tlink(tlink);
@@ -1419,7 +1419,7 @@ struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
}

static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
		const char *path, u32 *pacllen)
		const char *path, u32 *pacllen, u32 info)
{
	struct smb_ntsd *pntsd = NULL;
	int oplock = 0;
@@ -1446,9 +1446,12 @@ static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
		.fid = &fid,
	};

	if (info & SACL_SECINFO)
		oparms.desired_access |= SYSTEM_SECURITY;

	rc = CIFS_open(xid, &oparms, &oplock, NULL);
	if (!rc) {
		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen, info);
		CIFSSMBClose(xid, tcon, fid.netfid);
	}

@@ -1472,7 +1475,7 @@ struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
	if (inode)
		open_file = find_readable_file(CIFS_I(inode), true);
	if (!open_file)
		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
		return get_cifs_acl_by_path(cifs_sb, path, pacllen, info);

	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
	cifsFileInfo_put(open_file);
@@ -1485,7 +1488,7 @@ int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
{
	int oplock = 0;
	unsigned int xid;
	int rc, access_flags;
	int rc, access_flags = 0;
	struct cifs_tcon *tcon;
	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
@@ -1498,10 +1501,12 @@ int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
	tcon = tlink_tcon(tlink);
	xid = get_xid();

	if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
		access_flags = WRITE_OWNER;
	else
		access_flags = WRITE_DAC;
	if (aclflag & CIFS_ACL_OWNER || aclflag & CIFS_ACL_GROUP)
		access_flags |= WRITE_OWNER;
	if (aclflag & CIFS_ACL_SACL)
		access_flags |= SYSTEM_SECURITY;
	if (aclflag & CIFS_ACL_DACL)
		access_flags |= WRITE_DAC;

	oparms = (struct cifs_open_parms) {
		.tcon = tcon,
+1 −1
Original line number Diff line number Diff line
@@ -570,7 +570,7 @@ extern int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
		const struct nls_table *nls_codepage,
		struct cifs_sb_info *cifs_sb);
extern int CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon,
			__u16 fid, struct smb_ntsd **acl_inf, __u32 *buflen);
			__u16 fid, struct smb_ntsd **acl_inf, __u32 *buflen, __u32 info);
extern int CIFSSMBSetCIFSACL(const unsigned int, struct cifs_tcon *, __u16,
			struct smb_ntsd *pntsd, __u32 len, int aclflag);
extern int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
+2 −2
Original line number Diff line number Diff line
@@ -3385,7 +3385,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
/* Get Security Descriptor (by handle) from remote server for a file or dir */
int
CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
		  struct smb_ntsd **acl_inf, __u32 *pbuflen)
		  struct smb_ntsd **acl_inf, __u32 *pbuflen, __u32 info)
{
	int rc = 0;
	int buf_type = 0;
@@ -3408,7 +3408,7 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
	pSMB->MaxSetupCount = 0;
	pSMB->Fid = fid; /* file handle always le */
	pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
				     CIFS_ACL_DACL);
				     CIFS_ACL_DACL | info);
	pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
	inc_rfc1001_len(pSMB, 11);
	iov[0].iov_base = (char *)pSMB;