Skip to content

Commit e2065b8

Browse files
committed
Merge tag '6.4-rc2-ksmbd-server-fixes' of git://git.samba.org/ksmbd
Pull ksmbd server fixes from Steve French: - two fixes for incorrect SMB3 message validation (one for client which uses 8 byte padding, and one for empty bcc) - two fixes for out of bounds bugs: one for username offset checks (in session setup) and the other for create context name length checks in open requests * tag '6.4-rc2-ksmbd-server-fixes' of git://git.samba.org/ksmbd: ksmbd: smb2: Allow messages padded to 8byte boundary ksmbd: allocate one more byte for implied bcc[0] ksmbd: fix wrong UserName check in session_user ksmbd: fix global-out-of-bounds in smb2_find_context_vals
2 parents 0c9dcf1 + e7b8b8e commit e2065b8

File tree

5 files changed

+19
-15
lines changed

5 files changed

+19
-15
lines changed

fs/ksmbd/connection.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,8 @@ int ksmbd_conn_handler_loop(void *p)
351351
break;
352352

353353
/* 4 for rfc1002 length field */
354-
size = pdu_size + 4;
354+
/* 1 for implied bcc[0] */
355+
size = pdu_size + 4 + 1;
355356
conn->request_buf = kvmalloc(size, GFP_KERNEL);
356357
if (!conn->request_buf)
357358
break;

fs/ksmbd/oplock.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,11 +1449,12 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
14491449
* smb2_find_context_vals() - find a particular context info in open request
14501450
* @open_req: buffer containing smb2 file open(create) request
14511451
* @tag: context name to search for
1452+
* @tag_len: the length of tag
14521453
*
14531454
* Return: pointer to requested context, NULL if @str context not found
14541455
* or error pointer if name length is invalid.
14551456
*/
1456-
struct create_context *smb2_find_context_vals(void *open_req, const char *tag)
1457+
struct create_context *smb2_find_context_vals(void *open_req, const char *tag, int tag_len)
14571458
{
14581459
struct create_context *cc;
14591460
unsigned int next = 0;
@@ -1492,7 +1493,7 @@ struct create_context *smb2_find_context_vals(void *open_req, const char *tag)
14921493
return ERR_PTR(-EINVAL);
14931494

14941495
name = (char *)cc + name_off;
1495-
if (memcmp(name, tag, name_len) == 0)
1496+
if (name_len == tag_len && !memcmp(name, tag, name_len))
14961497
return cc;
14971498

14981499
remain_len -= next;

fs/ksmbd/oplock.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ void create_durable_v2_rsp_buf(char *cc, struct ksmbd_file *fp);
118118
void create_mxac_rsp_buf(char *cc, int maximal_access);
119119
void create_disk_id_rsp_buf(char *cc, __u64 file_id, __u64 vol_id);
120120
void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp);
121-
struct create_context *smb2_find_context_vals(void *open_req, const char *str);
121+
struct create_context *smb2_find_context_vals(void *open_req, const char *tag, int tag_len);
122122
struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
123123
char *lease_key);
124124
int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,

fs/ksmbd/smb2misc.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,11 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
416416

417417
/*
418418
* Allow a message that padded to 8byte boundary.
419+
* Linux 4.19.217 with smb 3.0.2 are sometimes
420+
* sending messages where the cls_len is exactly
421+
* 8 bytes less than len.
419422
*/
420-
if (clc_len < len && (len - clc_len) < 8)
423+
if (clc_len < len && (len - clc_len) <= 8)
421424
goto validate_credit;
422425

423426
pr_err_ratelimited(

fs/ksmbd/smb2pdu.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,7 +1356,7 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
13561356
struct authenticate_message *authblob;
13571357
struct ksmbd_user *user;
13581358
char *name;
1359-
unsigned int auth_msg_len, name_off, name_len, secbuf_len;
1359+
unsigned int name_off, name_len, secbuf_len;
13601360

13611361
secbuf_len = le16_to_cpu(req->SecurityBufferLength);
13621362
if (secbuf_len < sizeof(struct authenticate_message)) {
@@ -1366,9 +1366,8 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
13661366
authblob = user_authblob(conn, req);
13671367
name_off = le32_to_cpu(authblob->UserName.BufferOffset);
13681368
name_len = le16_to_cpu(authblob->UserName.Length);
1369-
auth_msg_len = le16_to_cpu(req->SecurityBufferOffset) + secbuf_len;
13701369

1371-
if (auth_msg_len < (u64)name_off + name_len)
1370+
if (secbuf_len < (u64)name_off + name_len)
13721371
return NULL;
13731372

13741373
name = smb_strndup_from_utf16((const char *)authblob + name_off,
@@ -2464,7 +2463,7 @@ static int smb2_create_sd_buffer(struct ksmbd_work *work,
24642463
return -ENOENT;
24652464

24662465
/* Parse SD BUFFER create contexts */
2467-
context = smb2_find_context_vals(req, SMB2_CREATE_SD_BUFFER);
2466+
context = smb2_find_context_vals(req, SMB2_CREATE_SD_BUFFER, 4);
24682467
if (!context)
24692468
return -ENOENT;
24702469
else if (IS_ERR(context))
@@ -2666,7 +2665,7 @@ int smb2_open(struct ksmbd_work *work)
26662665

26672666
if (req->CreateContextsOffset) {
26682667
/* Parse non-durable handle create contexts */
2669-
context = smb2_find_context_vals(req, SMB2_CREATE_EA_BUFFER);
2668+
context = smb2_find_context_vals(req, SMB2_CREATE_EA_BUFFER, 4);
26702669
if (IS_ERR(context)) {
26712670
rc = PTR_ERR(context);
26722671
goto err_out1;
@@ -2686,7 +2685,7 @@ int smb2_open(struct ksmbd_work *work)
26862685
}
26872686

26882687
context = smb2_find_context_vals(req,
2689-
SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST);
2688+
SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST, 4);
26902689
if (IS_ERR(context)) {
26912690
rc = PTR_ERR(context);
26922691
goto err_out1;
@@ -2697,7 +2696,7 @@ int smb2_open(struct ksmbd_work *work)
26972696
}
26982697

26992698
context = smb2_find_context_vals(req,
2700-
SMB2_CREATE_TIMEWARP_REQUEST);
2699+
SMB2_CREATE_TIMEWARP_REQUEST, 4);
27012700
if (IS_ERR(context)) {
27022701
rc = PTR_ERR(context);
27032702
goto err_out1;
@@ -2709,7 +2708,7 @@ int smb2_open(struct ksmbd_work *work)
27092708

27102709
if (tcon->posix_extensions) {
27112710
context = smb2_find_context_vals(req,
2712-
SMB2_CREATE_TAG_POSIX);
2711+
SMB2_CREATE_TAG_POSIX, 16);
27132712
if (IS_ERR(context)) {
27142713
rc = PTR_ERR(context);
27152714
goto err_out1;
@@ -3107,7 +3106,7 @@ int smb2_open(struct ksmbd_work *work)
31073106
struct create_alloc_size_req *az_req;
31083107

31093108
az_req = (struct create_alloc_size_req *)smb2_find_context_vals(req,
3110-
SMB2_CREATE_ALLOCATION_SIZE);
3109+
SMB2_CREATE_ALLOCATION_SIZE, 4);
31113110
if (IS_ERR(az_req)) {
31123111
rc = PTR_ERR(az_req);
31133112
goto err_out;
@@ -3134,7 +3133,7 @@ int smb2_open(struct ksmbd_work *work)
31343133
err);
31353134
}
31363135

3137-
context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID);
3136+
context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID, 4);
31383137
if (IS_ERR(context)) {
31393138
rc = PTR_ERR(context);
31403139
goto err_out;

0 commit comments

Comments
 (0)