Skip to content

Commit 8976e9d

Browse files
committed
Merge tag '6.5-rc-ksmbd-server-fixes-part1' of git://git.samba.org/ksmbd
Pull ksmbd server updates from Steve French: - two fixes for compounding bugs (make sure no out of bound reads with less common combinations of commands in the compound) - eight minor cleanup patches (e.g. simplifying return values, replace one element array, use of kzalloc where simpler) - fix for clang warning on possible overflow in filename conversion * tag '6.5-rc-ksmbd-server-fixes-part1' of git://git.samba.org/ksmbd: ksmbd: avoid field overflow warning ksmbd: Replace one-element array with flexible-array member ksmbd: Use struct_size() helper in ksmbd_negotiate_smb_dialect() ksmbd: add missing compound request handing in some commands ksmbd: fix out of bounds read in smb2_sess_setup ksmbd: Replace the ternary conditional operator with min() ksmbd: use kvzalloc instead of kvmalloc ksmbd: Change the return value of ksmbd_vfs_query_maximal_access to void ksmbd: return a literal instead of 'err' in ksmbd_vfs_kern_path_locked() ksmbd: use kzalloc() instead of __GFP_ZERO ksmbd: remove unused ksmbd_tree_conn_share function
2 parents ee152be + 9cedc58 commit 8976e9d

File tree

9 files changed

+88
-77
lines changed

9 files changed

+88
-77
lines changed

fs/smb/server/mgmt/tree_connect.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,17 +120,6 @@ struct ksmbd_tree_connect *ksmbd_tree_conn_lookup(struct ksmbd_session *sess,
120120
return tcon;
121121
}
122122

123-
struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess,
124-
unsigned int id)
125-
{
126-
struct ksmbd_tree_connect *tc;
127-
128-
tc = ksmbd_tree_conn_lookup(sess, id);
129-
if (tc)
130-
return tc->share_conf;
131-
return NULL;
132-
}
133-
134123
int ksmbd_tree_conn_session_logoff(struct ksmbd_session *sess)
135124
{
136125
int ret = 0;

fs/smb/server/mgmt/tree_connect.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
5353
struct ksmbd_tree_connect *ksmbd_tree_conn_lookup(struct ksmbd_session *sess,
5454
unsigned int id);
5555

56-
struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess,
57-
unsigned int id);
58-
5956
int ksmbd_tree_conn_session_logoff(struct ksmbd_session *sess);
6057

6158
#endif /* __TREE_CONNECT_MANAGEMENT_H__ */

fs/smb/server/smb2pdu.c

Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work)
543543
if (le32_to_cpu(hdr->NextCommand) > 0)
544544
sz = large_sz;
545545

546-
work->response_buf = kvmalloc(sz, GFP_KERNEL | __GFP_ZERO);
546+
work->response_buf = kvzalloc(sz, GFP_KERNEL);
547547
if (!work->response_buf)
548548
return -ENOMEM;
549549

@@ -1322,9 +1322,8 @@ static int decode_negotiation_token(struct ksmbd_conn *conn,
13221322

13231323
static int ntlm_negotiate(struct ksmbd_work *work,
13241324
struct negotiate_message *negblob,
1325-
size_t negblob_len)
1325+
size_t negblob_len, struct smb2_sess_setup_rsp *rsp)
13261326
{
1327-
struct smb2_sess_setup_rsp *rsp = smb2_get_msg(work->response_buf);
13281327
struct challenge_message *chgblob;
13291328
unsigned char *spnego_blob = NULL;
13301329
u16 spnego_blob_len;
@@ -1429,10 +1428,10 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
14291428
return user;
14301429
}
14311430

1432-
static int ntlm_authenticate(struct ksmbd_work *work)
1431+
static int ntlm_authenticate(struct ksmbd_work *work,
1432+
struct smb2_sess_setup_req *req,
1433+
struct smb2_sess_setup_rsp *rsp)
14331434
{
1434-
struct smb2_sess_setup_req *req = smb2_get_msg(work->request_buf);
1435-
struct smb2_sess_setup_rsp *rsp = smb2_get_msg(work->response_buf);
14361435
struct ksmbd_conn *conn = work->conn;
14371436
struct ksmbd_session *sess = work->sess;
14381437
struct channel *chann = NULL;
@@ -1566,10 +1565,10 @@ static int ntlm_authenticate(struct ksmbd_work *work)
15661565
}
15671566

15681567
#ifdef CONFIG_SMB_SERVER_KERBEROS5
1569-
static int krb5_authenticate(struct ksmbd_work *work)
1568+
static int krb5_authenticate(struct ksmbd_work *work,
1569+
struct smb2_sess_setup_req *req,
1570+
struct smb2_sess_setup_rsp *rsp)
15701571
{
1571-
struct smb2_sess_setup_req *req = smb2_get_msg(work->request_buf);
1572-
struct smb2_sess_setup_rsp *rsp = smb2_get_msg(work->response_buf);
15731572
struct ksmbd_conn *conn = work->conn;
15741573
struct ksmbd_session *sess = work->sess;
15751574
char *in_blob, *out_blob;
@@ -1647,7 +1646,9 @@ static int krb5_authenticate(struct ksmbd_work *work)
16471646
return 0;
16481647
}
16491648
#else
1650-
static int krb5_authenticate(struct ksmbd_work *work)
1649+
static int krb5_authenticate(struct ksmbd_work *work,
1650+
struct smb2_sess_setup_req *req,
1651+
struct smb2_sess_setup_rsp *rsp)
16511652
{
16521653
return -EOPNOTSUPP;
16531654
}
@@ -1656,15 +1657,17 @@ static int krb5_authenticate(struct ksmbd_work *work)
16561657
int smb2_sess_setup(struct ksmbd_work *work)
16571658
{
16581659
struct ksmbd_conn *conn = work->conn;
1659-
struct smb2_sess_setup_req *req = smb2_get_msg(work->request_buf);
1660-
struct smb2_sess_setup_rsp *rsp = smb2_get_msg(work->response_buf);
1660+
struct smb2_sess_setup_req *req;
1661+
struct smb2_sess_setup_rsp *rsp;
16611662
struct ksmbd_session *sess;
16621663
struct negotiate_message *negblob;
16631664
unsigned int negblob_len, negblob_off;
16641665
int rc = 0;
16651666

16661667
ksmbd_debug(SMB, "Received request for session setup\n");
16671668

1669+
WORK_BUFFERS(work, req, rsp);
1670+
16681671
rsp->StructureSize = cpu_to_le16(9);
16691672
rsp->SessionFlags = 0;
16701673
rsp->SecurityBufferOffset = cpu_to_le16(72);
@@ -1786,7 +1789,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
17861789

17871790
if (conn->preferred_auth_mech &
17881791
(KSMBD_AUTH_KRB5 | KSMBD_AUTH_MSKRB5)) {
1789-
rc = krb5_authenticate(work);
1792+
rc = krb5_authenticate(work, req, rsp);
17901793
if (rc) {
17911794
rc = -EINVAL;
17921795
goto out_err;
@@ -1800,7 +1803,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
18001803
sess->Preauth_HashValue = NULL;
18011804
} else if (conn->preferred_auth_mech == KSMBD_AUTH_NTLMSSP) {
18021805
if (negblob->MessageType == NtLmNegotiate) {
1803-
rc = ntlm_negotiate(work, negblob, negblob_len);
1806+
rc = ntlm_negotiate(work, negblob, negblob_len, rsp);
18041807
if (rc)
18051808
goto out_err;
18061809
rsp->hdr.Status =
@@ -1813,7 +1816,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
18131816
le16_to_cpu(rsp->SecurityBufferLength) - 1);
18141817

18151818
} else if (negblob->MessageType == NtLmAuthenticate) {
1816-
rc = ntlm_authenticate(work);
1819+
rc = ntlm_authenticate(work, req, rsp);
18171820
if (rc)
18181821
goto out_err;
18191822

@@ -1911,14 +1914,16 @@ int smb2_sess_setup(struct ksmbd_work *work)
19111914
int smb2_tree_connect(struct ksmbd_work *work)
19121915
{
19131916
struct ksmbd_conn *conn = work->conn;
1914-
struct smb2_tree_connect_req *req = smb2_get_msg(work->request_buf);
1915-
struct smb2_tree_connect_rsp *rsp = smb2_get_msg(work->response_buf);
1917+
struct smb2_tree_connect_req *req;
1918+
struct smb2_tree_connect_rsp *rsp;
19161919
struct ksmbd_session *sess = work->sess;
19171920
char *treename = NULL, *name = NULL;
19181921
struct ksmbd_tree_conn_status status;
19191922
struct ksmbd_share_config *share;
19201923
int rc = -EINVAL;
19211924

1925+
WORK_BUFFERS(work, req, rsp);
1926+
19221927
treename = smb_strndup_from_utf16(req->Buffer,
19231928
le16_to_cpu(req->PathLength), true,
19241929
conn->local_nls);
@@ -2087,19 +2092,19 @@ static int smb2_create_open_flags(bool file_present, __le32 access,
20872092
*/
20882093
int smb2_tree_disconnect(struct ksmbd_work *work)
20892094
{
2090-
struct smb2_tree_disconnect_rsp *rsp = smb2_get_msg(work->response_buf);
2095+
struct smb2_tree_disconnect_rsp *rsp;
2096+
struct smb2_tree_disconnect_req *req;
20912097
struct ksmbd_session *sess = work->sess;
20922098
struct ksmbd_tree_connect *tcon = work->tcon;
20932099

2100+
WORK_BUFFERS(work, req, rsp);
2101+
20942102
rsp->StructureSize = cpu_to_le16(4);
20952103
inc_rfc1001_len(work->response_buf, 4);
20962104

20972105
ksmbd_debug(SMB, "request\n");
20982106

20992107
if (!tcon || test_and_set_bit(TREE_CONN_EXPIRE, &tcon->status)) {
2100-
struct smb2_tree_disconnect_req *req =
2101-
smb2_get_msg(work->request_buf);
2102-
21032108
ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId);
21042109

21052110
rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
@@ -2122,10 +2127,14 @@ int smb2_tree_disconnect(struct ksmbd_work *work)
21222127
int smb2_session_logoff(struct ksmbd_work *work)
21232128
{
21242129
struct ksmbd_conn *conn = work->conn;
2125-
struct smb2_logoff_rsp *rsp = smb2_get_msg(work->response_buf);
2130+
struct smb2_logoff_req *req;
2131+
struct smb2_logoff_rsp *rsp;
21262132
struct ksmbd_session *sess;
2127-
struct smb2_logoff_req *req = smb2_get_msg(work->request_buf);
2128-
u64 sess_id = le64_to_cpu(req->hdr.SessionId);
2133+
u64 sess_id;
2134+
2135+
WORK_BUFFERS(work, req, rsp);
2136+
2137+
sess_id = le64_to_cpu(req->hdr.SessionId);
21292138

21302139
rsp->StructureSize = cpu_to_le16(4);
21312140
inc_rfc1001_len(work->response_buf, 4);
@@ -2165,12 +2174,14 @@ int smb2_session_logoff(struct ksmbd_work *work)
21652174
*/
21662175
static noinline int create_smb2_pipe(struct ksmbd_work *work)
21672176
{
2168-
struct smb2_create_rsp *rsp = smb2_get_msg(work->response_buf);
2169-
struct smb2_create_req *req = smb2_get_msg(work->request_buf);
2177+
struct smb2_create_rsp *rsp;
2178+
struct smb2_create_req *req;
21702179
int id;
21712180
int err;
21722181
char *name;
21732182

2183+
WORK_BUFFERS(work, req, rsp);
2184+
21742185
name = smb_strndup_from_utf16(req->Buffer, le16_to_cpu(req->NameLength),
21752186
1, work->conn->local_nls);
21762187
if (IS_ERR(name)) {
@@ -2872,11 +2883,9 @@ int smb2_open(struct ksmbd_work *work)
28722883
if (!file_present) {
28732884
daccess = cpu_to_le32(GENERIC_ALL_FLAGS);
28742885
} else {
2875-
rc = ksmbd_vfs_query_maximal_access(idmap,
2886+
ksmbd_vfs_query_maximal_access(idmap,
28762887
path.dentry,
28772888
&daccess);
2878-
if (rc)
2879-
goto err_out;
28802889
already_permitted = true;
28812890
}
28822891
maximal_access = daccess;
@@ -5305,8 +5314,10 @@ int smb2_query_info(struct ksmbd_work *work)
53055314
static noinline int smb2_close_pipe(struct ksmbd_work *work)
53065315
{
53075316
u64 id;
5308-
struct smb2_close_req *req = smb2_get_msg(work->request_buf);
5309-
struct smb2_close_rsp *rsp = smb2_get_msg(work->response_buf);
5317+
struct smb2_close_req *req;
5318+
struct smb2_close_rsp *rsp;
5319+
5320+
WORK_BUFFERS(work, req, rsp);
53105321

53115322
id = req->VolatileFileId;
53125323
ksmbd_session_rpc_close(work->sess, id);
@@ -5448,6 +5459,9 @@ int smb2_echo(struct ksmbd_work *work)
54485459
{
54495460
struct smb2_echo_rsp *rsp = smb2_get_msg(work->response_buf);
54505461

5462+
if (work->next_smb2_rcv_hdr_off)
5463+
rsp = ksmbd_resp_buf_next(work);
5464+
54515465
rsp->StructureSize = cpu_to_le16(4);
54525466
rsp->Reserved = 0;
54535467
inc_rfc1001_len(work->response_buf, 4);
@@ -6082,8 +6096,10 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work)
60826096
int nbytes = 0, err;
60836097
u64 id;
60846098
struct ksmbd_rpc_command *rpc_resp;
6085-
struct smb2_read_req *req = smb2_get_msg(work->request_buf);
6086-
struct smb2_read_rsp *rsp = smb2_get_msg(work->response_buf);
6099+
struct smb2_read_req *req;
6100+
struct smb2_read_rsp *rsp;
6101+
6102+
WORK_BUFFERS(work, req, rsp);
60876103

60886104
id = req->VolatileFileId;
60896105

@@ -6096,7 +6112,7 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work)
60966112
}
60976113

60986114
work->aux_payload_buf =
6099-
kvmalloc(rpc_resp->payload_sz, GFP_KERNEL | __GFP_ZERO);
6115+
kvmalloc(rpc_resp->payload_sz, GFP_KERNEL);
61006116
if (!work->aux_payload_buf) {
61016117
err = -ENOMEM;
61026118
goto out;
@@ -6248,7 +6264,7 @@ int smb2_read(struct ksmbd_work *work)
62486264
ksmbd_debug(SMB, "filename %pD, offset %lld, len %zu\n",
62496265
fp->filp, offset, length);
62506266

6251-
work->aux_payload_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO);
6267+
work->aux_payload_buf = kvzalloc(length, GFP_KERNEL);
62526268
if (!work->aux_payload_buf) {
62536269
err = -ENOMEM;
62546270
goto out;
@@ -6331,14 +6347,16 @@ int smb2_read(struct ksmbd_work *work)
63316347
*/
63326348
static noinline int smb2_write_pipe(struct ksmbd_work *work)
63336349
{
6334-
struct smb2_write_req *req = smb2_get_msg(work->request_buf);
6335-
struct smb2_write_rsp *rsp = smb2_get_msg(work->response_buf);
6350+
struct smb2_write_req *req;
6351+
struct smb2_write_rsp *rsp;
63366352
struct ksmbd_rpc_command *rpc_resp;
63376353
u64 id = 0;
63386354
int err = 0, ret = 0;
63396355
char *data_buf;
63406356
size_t length;
63416357

6358+
WORK_BUFFERS(work, req, rsp);
6359+
63426360
length = le32_to_cpu(req->Length);
63436361
id = req->VolatileFileId;
63446362

@@ -6397,7 +6415,7 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
63976415
int ret;
63986416
ssize_t nbytes;
63996417

6400-
data_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO);
6418+
data_buf = kvzalloc(length, GFP_KERNEL);
64016419
if (!data_buf)
64026420
return -ENOMEM;
64036421

@@ -6607,6 +6625,9 @@ int smb2_cancel(struct ksmbd_work *work)
66076625
struct ksmbd_work *iter;
66086626
struct list_head *command_list;
66096627

6628+
if (work->next_smb2_rcv_hdr_off)
6629+
hdr = ksmbd_resp_buf_next(work);
6630+
66106631
ksmbd_debug(SMB, "smb2 cancel called on mid %llu, async flags 0x%x\n",
66116632
hdr->MessageId, hdr->Flags);
66126633

@@ -6766,8 +6787,8 @@ static inline bool lock_defer_pending(struct file_lock *fl)
67666787
*/
67676788
int smb2_lock(struct ksmbd_work *work)
67686789
{
6769-
struct smb2_lock_req *req = smb2_get_msg(work->request_buf);
6770-
struct smb2_lock_rsp *rsp = smb2_get_msg(work->response_buf);
6790+
struct smb2_lock_req *req;
6791+
struct smb2_lock_rsp *rsp;
67716792
struct smb2_lock_element *lock_ele;
67726793
struct ksmbd_file *fp = NULL;
67736794
struct file_lock *flock = NULL;
@@ -6784,6 +6805,8 @@ int smb2_lock(struct ksmbd_work *work)
67846805
LIST_HEAD(rollback_list);
67856806
int prior_lock = 0;
67866807

6808+
WORK_BUFFERS(work, req, rsp);
6809+
67876810
ksmbd_debug(SMB, "Received lock request\n");
67886811
fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
67896812
if (!fp) {
@@ -7897,8 +7920,8 @@ int smb2_ioctl(struct ksmbd_work *work)
78977920
*/
78987921
static void smb20_oplock_break_ack(struct ksmbd_work *work)
78997922
{
7900-
struct smb2_oplock_break *req = smb2_get_msg(work->request_buf);
7901-
struct smb2_oplock_break *rsp = smb2_get_msg(work->response_buf);
7923+
struct smb2_oplock_break *req;
7924+
struct smb2_oplock_break *rsp;
79027925
struct ksmbd_file *fp;
79037926
struct oplock_info *opinfo = NULL;
79047927
__le32 err = 0;
@@ -7907,6 +7930,8 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
79077930
char req_oplevel = 0, rsp_oplevel = 0;
79087931
unsigned int oplock_change_type;
79097932

7933+
WORK_BUFFERS(work, req, rsp);
7934+
79107935
volatile_id = req->VolatileFid;
79117936
persistent_id = req->PersistentFid;
79127937
req_oplevel = req->OplockLevel;
@@ -8041,15 +8066,17 @@ static int check_lease_state(struct lease *lease, __le32 req_state)
80418066
static void smb21_lease_break_ack(struct ksmbd_work *work)
80428067
{
80438068
struct ksmbd_conn *conn = work->conn;
8044-
struct smb2_lease_ack *req = smb2_get_msg(work->request_buf);
8045-
struct smb2_lease_ack *rsp = smb2_get_msg(work->response_buf);
8069+
struct smb2_lease_ack *req;
8070+
struct smb2_lease_ack *rsp;
80468071
struct oplock_info *opinfo;
80478072
__le32 err = 0;
80488073
int ret = 0;
80498074
unsigned int lease_change_type;
80508075
__le32 lease_state;
80518076
struct lease *lease;
80528077

8078+
WORK_BUFFERS(work, req, rsp);
8079+
80538080
ksmbd_debug(OPLOCK, "smb21 lease break, lease state(0x%x)\n",
80548081
le32_to_cpu(req->LeaseState));
80558082
opinfo = lookup_lease_in_table(conn, req->LeaseKey);
@@ -8175,8 +8202,10 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
81758202
*/
81768203
int smb2_oplock_break(struct ksmbd_work *work)
81778204
{
8178-
struct smb2_oplock_break *req = smb2_get_msg(work->request_buf);
8179-
struct smb2_oplock_break *rsp = smb2_get_msg(work->response_buf);
8205+
struct smb2_oplock_break *req;
8206+
struct smb2_oplock_break *rsp;
8207+
8208+
WORK_BUFFERS(work, req, rsp);
81808209

81818210
switch (le16_to_cpu(req->StructureSize)) {
81828211
case OP_BREAK_STRUCT_SIZE_20:

0 commit comments

Comments
 (0)