mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02:00
three ksmbd server fixes
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmoQ3EcACgkQiiy9cAdy T1HgVAwAktfOphQUPBUd1RwtGYUZWcMS6uHwBjCvs7As1Rm43dGoNpjCkDkm14eJ w9JuXh8gkHPviIgildCzHn/kt0HvNuFt4PwI8neOLQgSzeQmDKUM9uTnQAgHoj+u Szkf13t0vGHN52fKa0mtFkDCvzYvyuIt6j4hlFNt0NXIdaQq3MS7pTGOnip62edx ZBZWFEoOzEgwi0ZaKxt20Ocgl/P2lrdyEDnRM9U7AfRbae6Po+ephtZL1nN3OvVR ZpdC/nE9ce4KFvr0f4vm3eBqr4BX8g4gYj+OOlBn9Zq93gre28Eo9IKZpCOhq/b6 jPxPhoIVYSwKL7mhmvdy1tM9MYudNOvnkFtQh7JSsyTfjl89rcMiVkb11ZvBi4GS d3lY+CF6U6BUbu65T+HqtwlmplntDZfmVrAc6DvScUkOo7yol+QE9K5llOaVV+ju ZZOH9RY3EQqwkWQoXT70dSwxihzSLhliKEQXm7vQbQe1lvlNaSIqDjIdPdQVqhZ2 VfdlNxnW =Pxit -----END PGP SIGNATURE----- Merge tag 'v7.1-rc5-ksmbd-server-fixes' of git://git.samba.org/ksmbd Pull smb server fixes from Steve French: - fix for creating tmpfiles - fix durable reconnect error path - validate SID in security descriptor when inheriting DACL * tag 'v7.1-rc5-ksmbd-server-fixes' of git://git.samba.org/ksmbd: smb/server: promote S_DEL_ON_CLS to S_DEL_PENDING when close ksmbd: validate SID in parent security descriptor during ACL inheritance ksmbd: fix durable reconnect error path file lifetime
This commit is contained in:
commit
4cbfe4502e
|
|
@ -3804,8 +3804,19 @@ int smb2_open(struct ksmbd_work *work)
|
|||
ksmbd_debug(SMB, "Error response: %x\n", rsp->hdr.Status);
|
||||
}
|
||||
|
||||
if (dh_info.reconnected)
|
||||
ksmbd_put_durable_fd(dh_info.fp);
|
||||
if (dh_info.reconnected) {
|
||||
/*
|
||||
* If reconnect succeeded, fp was republished in the
|
||||
* session file table. On a later error, ksmbd_fd_put()
|
||||
* above drops the session reference; drop the durable
|
||||
* lookup reference through the same session-aware path so
|
||||
* final close removes the volatile id before freeing fp.
|
||||
*/
|
||||
if (rc && fp == dh_info.fp)
|
||||
ksmbd_fd_put(work, dh_info.fp);
|
||||
else
|
||||
ksmbd_put_durable_fd(dh_info.fp);
|
||||
}
|
||||
|
||||
kfree(name);
|
||||
kfree(lc);
|
||||
|
|
|
|||
|
|
@ -1096,6 +1096,40 @@ static int smb_append_inherited_ace(struct smb_ace **ace, int *nt_size,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int smb_validate_ntsd_sid(struct smb_ntsd *pntsd, size_t pntsd_size,
|
||||
unsigned int sid_offset, struct smb_sid **sid,
|
||||
size_t *sid_size)
|
||||
{
|
||||
size_t sid_end;
|
||||
|
||||
*sid = NULL;
|
||||
*sid_size = 0;
|
||||
|
||||
if (!sid_offset)
|
||||
return 0;
|
||||
|
||||
if (sid_offset < sizeof(struct smb_ntsd) ||
|
||||
check_add_overflow(sid_offset, (size_t)CIFS_SID_BASE_SIZE,
|
||||
&sid_end) ||
|
||||
sid_end > pntsd_size)
|
||||
return -EINVAL;
|
||||
|
||||
*sid = (struct smb_sid *)((char *)pntsd + sid_offset);
|
||||
if ((*sid)->num_subauth > SID_MAX_SUB_AUTHORITIES)
|
||||
return -EINVAL;
|
||||
|
||||
if (check_add_overflow((size_t)CIFS_SID_BASE_SIZE,
|
||||
sizeof(__le32) * (size_t)(*sid)->num_subauth,
|
||||
&sid_end))
|
||||
return -EINVAL;
|
||||
|
||||
if (sid_offset > pntsd_size || sid_end > pntsd_size - sid_offset)
|
||||
return -EINVAL;
|
||||
|
||||
*sid_size = sid_end;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int smb_inherit_dacl(struct ksmbd_conn *conn,
|
||||
const struct path *path,
|
||||
unsigned int uid, unsigned int gid)
|
||||
|
|
@ -1108,28 +1142,28 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
|
|||
struct dentry *parent = path->dentry->d_parent;
|
||||
struct mnt_idmap *idmap = mnt_idmap(path->mnt);
|
||||
int inherited_flags = 0, flags = 0, i, nt_size = 0, pdacl_size;
|
||||
int rc = 0, pntsd_type, pntsd_size, acl_len, aces_size;
|
||||
int rc = 0, pntsd_type, ppntsd_size, acl_len, aces_size;
|
||||
unsigned int dacloffset;
|
||||
size_t dacl_struct_end;
|
||||
u16 num_aces, ace_cnt = 0;
|
||||
char *aces_base;
|
||||
bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
|
||||
|
||||
pntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
|
||||
ppntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
|
||||
parent, &parent_pntsd);
|
||||
if (pntsd_size <= 0)
|
||||
if (ppntsd_size <= 0)
|
||||
return -ENOENT;
|
||||
|
||||
dacloffset = le32_to_cpu(parent_pntsd->dacloffset);
|
||||
if (!dacloffset ||
|
||||
check_add_overflow(dacloffset, sizeof(struct smb_acl), &dacl_struct_end) ||
|
||||
dacl_struct_end > (size_t)pntsd_size) {
|
||||
dacl_struct_end > (size_t)ppntsd_size) {
|
||||
rc = -EINVAL;
|
||||
goto free_parent_pntsd;
|
||||
}
|
||||
|
||||
parent_pdacl = (struct smb_acl *)((char *)parent_pntsd + dacloffset);
|
||||
acl_len = pntsd_size - dacloffset;
|
||||
acl_len = ppntsd_size - dacloffset;
|
||||
num_aces = le16_to_cpu(parent_pdacl->num_aces);
|
||||
pntsd_type = le16_to_cpu(parent_pntsd->type);
|
||||
pdacl_size = le16_to_cpu(parent_pdacl->size);
|
||||
|
|
@ -1243,19 +1277,19 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
|
|||
struct smb_ntsd *pntsd;
|
||||
struct smb_acl *pdacl;
|
||||
struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL;
|
||||
int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
|
||||
size_t powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size;
|
||||
size_t pntsd_alloc_size;
|
||||
|
||||
if (parent_pntsd->osidoffset) {
|
||||
powner_sid = (struct smb_sid *)((char *)parent_pntsd +
|
||||
le32_to_cpu(parent_pntsd->osidoffset));
|
||||
powner_sid_size = 1 + 1 + 6 + (powner_sid->num_subauth * 4);
|
||||
}
|
||||
if (parent_pntsd->gsidoffset) {
|
||||
pgroup_sid = (struct smb_sid *)((char *)parent_pntsd +
|
||||
le32_to_cpu(parent_pntsd->gsidoffset));
|
||||
pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4);
|
||||
}
|
||||
rc = smb_validate_ntsd_sid(parent_pntsd, ppntsd_size,
|
||||
le32_to_cpu(parent_pntsd->osidoffset),
|
||||
&powner_sid, &powner_sid_size);
|
||||
if (rc)
|
||||
goto free_aces_base;
|
||||
rc = smb_validate_ntsd_sid(parent_pntsd, ppntsd_size,
|
||||
le32_to_cpu(parent_pntsd->gsidoffset),
|
||||
&pgroup_sid, &pgroup_sid_size);
|
||||
if (rc)
|
||||
goto free_aces_base;
|
||||
|
||||
if (check_add_overflow(sizeof(struct smb_ntsd),
|
||||
(size_t)powner_sid_size,
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ int ksmbd_query_inode_status(struct dentry *dentry)
|
|||
return ret;
|
||||
|
||||
down_read(&ci->m_lock);
|
||||
if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS))
|
||||
if (ci->m_flags & S_DEL_PENDING)
|
||||
ret = KSMBD_INODE_STATUS_PENDING_DELETE;
|
||||
else
|
||||
ret = KSMBD_INODE_STATUS_OK;
|
||||
|
|
@ -227,7 +227,7 @@ bool ksmbd_inode_pending_delete(struct ksmbd_file *fp)
|
|||
int ret;
|
||||
|
||||
down_read(&ci->m_lock);
|
||||
ret = (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS));
|
||||
ret = (ci->m_flags & S_DEL_PENDING);
|
||||
up_read(&ci->m_lock);
|
||||
|
||||
return ret;
|
||||
|
|
@ -395,12 +395,20 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
|
|||
}
|
||||
}
|
||||
|
||||
down_write(&ci->m_lock);
|
||||
/* Promote S_DEL_ON_CLS to S_DEL_PENDING when close */
|
||||
if (ci->m_flags & S_DEL_ON_CLS) {
|
||||
ci->m_flags &= ~S_DEL_ON_CLS;
|
||||
ci->m_flags |= S_DEL_PENDING;
|
||||
}
|
||||
up_write(&ci->m_lock);
|
||||
|
||||
if (atomic_dec_and_test(&ci->m_count)) {
|
||||
bool do_unlink = false;
|
||||
|
||||
down_write(&ci->m_lock);
|
||||
if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) {
|
||||
ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING);
|
||||
if (ci->m_flags & S_DEL_PENDING) {
|
||||
ci->m_flags &= ~S_DEL_PENDING;
|
||||
do_unlink = true;
|
||||
}
|
||||
up_write(&ci->m_lock);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user