Skip to content

Commit 71b1543

Browse files
committed
Merge tag '6.9-rc5-ksmbd-fixes' of git://git.samba.org/ksmbd
Pull smb server fixes from Steve French: "Five ksmbd server fixes, most also for stable: - rename fix - two fixes for potential out of bounds - fix for connections from MacOS (padding in close response) - fix for when to enable persistent handles" * tag '6.9-rc5-ksmbd-fixes' of git://git.samba.org/ksmbd: ksmbd: add continuous availability share parameter ksmbd: common: use struct_group_attr instead of struct_group for network_open_info ksmbd: clear RENAME_NOREPLACE before calling vfs_rename ksmbd: validate request buffer size in smb2_allocate_rsp_buf() ksmbd: fix slab-out-of-bounds in smb2_allocate_rsp_buf
2 parents a2c63a3 + e9d8c2f commit 71b1543

File tree

5 files changed

+42
-28
lines changed

5 files changed

+42
-28
lines changed

fs/smb/common/smb2pdu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ struct smb2_close_rsp {
711711
__le16 StructureSize; /* 60 */
712712
__le16 Flags;
713713
__le32 Reserved;
714-
struct_group(network_open_info,
714+
struct_group_attr(network_open_info, __packed,
715715
__le64 CreationTime;
716716
__le64 LastAccessTime;
717717
__le64 LastWriteTime;

fs/smb/server/ksmbd_netlink.h

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -340,23 +340,24 @@ enum KSMBD_TREE_CONN_STATUS {
340340
/*
341341
* Share config flags.
342342
*/
343-
#define KSMBD_SHARE_FLAG_INVALID (0)
344-
#define KSMBD_SHARE_FLAG_AVAILABLE BIT(0)
345-
#define KSMBD_SHARE_FLAG_BROWSEABLE BIT(1)
346-
#define KSMBD_SHARE_FLAG_WRITEABLE BIT(2)
347-
#define KSMBD_SHARE_FLAG_READONLY BIT(3)
348-
#define KSMBD_SHARE_FLAG_GUEST_OK BIT(4)
349-
#define KSMBD_SHARE_FLAG_GUEST_ONLY BIT(5)
350-
#define KSMBD_SHARE_FLAG_STORE_DOS_ATTRS BIT(6)
351-
#define KSMBD_SHARE_FLAG_OPLOCKS BIT(7)
352-
#define KSMBD_SHARE_FLAG_PIPE BIT(8)
353-
#define KSMBD_SHARE_FLAG_HIDE_DOT_FILES BIT(9)
354-
#define KSMBD_SHARE_FLAG_INHERIT_OWNER BIT(10)
355-
#define KSMBD_SHARE_FLAG_STREAMS BIT(11)
356-
#define KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS BIT(12)
357-
#define KSMBD_SHARE_FLAG_ACL_XATTR BIT(13)
358-
#define KSMBD_SHARE_FLAG_UPDATE BIT(14)
359-
#define KSMBD_SHARE_FLAG_CROSSMNT BIT(15)
343+
#define KSMBD_SHARE_FLAG_INVALID (0)
344+
#define KSMBD_SHARE_FLAG_AVAILABLE BIT(0)
345+
#define KSMBD_SHARE_FLAG_BROWSEABLE BIT(1)
346+
#define KSMBD_SHARE_FLAG_WRITEABLE BIT(2)
347+
#define KSMBD_SHARE_FLAG_READONLY BIT(3)
348+
#define KSMBD_SHARE_FLAG_GUEST_OK BIT(4)
349+
#define KSMBD_SHARE_FLAG_GUEST_ONLY BIT(5)
350+
#define KSMBD_SHARE_FLAG_STORE_DOS_ATTRS BIT(6)
351+
#define KSMBD_SHARE_FLAG_OPLOCKS BIT(7)
352+
#define KSMBD_SHARE_FLAG_PIPE BIT(8)
353+
#define KSMBD_SHARE_FLAG_HIDE_DOT_FILES BIT(9)
354+
#define KSMBD_SHARE_FLAG_INHERIT_OWNER BIT(10)
355+
#define KSMBD_SHARE_FLAG_STREAMS BIT(11)
356+
#define KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS BIT(12)
357+
#define KSMBD_SHARE_FLAG_ACL_XATTR BIT(13)
358+
#define KSMBD_SHARE_FLAG_UPDATE BIT(14)
359+
#define KSMBD_SHARE_FLAG_CROSSMNT BIT(15)
360+
#define KSMBD_SHARE_FLAG_CONTINUOUS_AVAILABILITY BIT(16)
360361

361362
/*
362363
* Tree connect request flags.

fs/smb/server/server.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,20 +167,17 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
167167
int rc;
168168
bool is_chained = false;
169169

170-
if (conn->ops->allocate_rsp_buf(work))
171-
return;
172-
173170
if (conn->ops->is_transform_hdr &&
174171
conn->ops->is_transform_hdr(work->request_buf)) {
175172
rc = conn->ops->decrypt_req(work);
176-
if (rc < 0) {
177-
conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
178-
goto send;
179-
}
180-
173+
if (rc < 0)
174+
return;
181175
work->encrypted = true;
182176
}
183177

178+
if (conn->ops->allocate_rsp_buf(work))
179+
return;
180+
184181
rc = conn->ops->init_rsp_hdr(work);
185182
if (rc) {
186183
/* either uid or tid is not correct */

fs/smb/server/smb2pdu.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,10 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work)
535535
if (cmd == SMB2_QUERY_INFO_HE) {
536536
struct smb2_query_info_req *req;
537537

538+
if (get_rfc1002_len(work->request_buf) <
539+
offsetof(struct smb2_query_info_req, OutputBufferLength))
540+
return -EINVAL;
541+
538542
req = smb2_get_msg(work->request_buf);
539543
if ((req->InfoType == SMB2_O_INFO_FILE &&
540544
(req->FileInfoClass == FILE_FULL_EA_INFORMATION ||
@@ -1984,7 +1988,12 @@ int smb2_tree_connect(struct ksmbd_work *work)
19841988
write_unlock(&sess->tree_conns_lock);
19851989
rsp->StructureSize = cpu_to_le16(16);
19861990
out_err1:
1987-
rsp->Capabilities = 0;
1991+
if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE &&
1992+
test_share_config_flag(share,
1993+
KSMBD_SHARE_FLAG_CONTINUOUS_AVAILABILITY))
1994+
rsp->Capabilities = SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY;
1995+
else
1996+
rsp->Capabilities = 0;
19881997
rsp->Reserved = 0;
19891998
/* default manual caching */
19901999
rsp->ShareFlags = SMB2_SHAREFLAG_MANUAL_CACHING;
@@ -3498,7 +3507,9 @@ int smb2_open(struct ksmbd_work *work)
34983507
memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
34993508

35003509
if (dh_info.type == DURABLE_REQ_V2 || dh_info.type == DURABLE_REQ) {
3501-
if (dh_info.type == DURABLE_REQ_V2 && dh_info.persistent)
3510+
if (dh_info.type == DURABLE_REQ_V2 && dh_info.persistent &&
3511+
test_share_config_flag(work->tcon->share_conf,
3512+
KSMBD_SHARE_FLAG_CONTINUOUS_AVAILABILITY))
35023513
fp->is_persistent = true;
35033514
else
35043515
fp->is_durable = true;

fs/smb/server/vfs.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,10 +754,15 @@ int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path,
754754
goto out4;
755755
}
756756

757+
/*
758+
* explicitly handle file overwrite case, for compatibility with
759+
* filesystems that may not support rename flags (e.g: fuse)
760+
*/
757761
if ((flags & RENAME_NOREPLACE) && d_is_positive(new_dentry)) {
758762
err = -EEXIST;
759763
goto out4;
760764
}
765+
flags &= ~(RENAME_NOREPLACE);
761766

762767
if (old_child == trap) {
763768
err = -EINVAL;

0 commit comments

Comments
 (0)