mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 12:00:22 +09:00
ksmbd: fix global-out-of-bounds in smb2_find_context_vals
commit 02f76c401d upstream.
Add tag_len argument in smb2_find_context_vals() to avoid out-of-bound
read when create_context's name_len is larger than tag length.
[ 7.995411] ==================================================================
[ 7.995866] BUG: KASAN: global-out-of-bounds in memcmp+0x83/0xa0
[ 7.996248] Read of size 8 at addr ffffffff8258d940 by task kworker/0:0/7
...
[ 7.998191] Call Trace:
[ 7.998358] <TASK>
[ 7.998503] dump_stack_lvl+0x33/0x50
[ 7.998743] print_report+0xcc/0x620
[ 7.999458] kasan_report+0xae/0xe0
[ 7.999895] kasan_check_range+0x35/0x1b0
[ 8.000152] memcmp+0x83/0xa0
[ 8.000347] smb2_find_context_vals+0xf7/0x1e0
[ 8.000635] smb2_open+0x1df2/0x43a0
[ 8.006398] handle_ksmbd_work+0x274/0x810
[ 8.006666] process_one_work+0x419/0x760
[ 8.006922] worker_thread+0x2a2/0x6f0
[ 8.007429] kthread+0x160/0x190
[ 8.007946] ret_from_fork+0x1f/0x30
[ 8.008181] </TASK>
Cc: stable@vger.kernel.org
Signed-off-by: Chih-Yen Chang <cc85nod@gmail.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
7657321b26
commit
865be1cff2
@@ -1446,11 +1446,12 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
|
||||
* smb2_find_context_vals() - find a particular context info in open request
|
||||
* @open_req: buffer containing smb2 file open(create) request
|
||||
* @tag: context name to search for
|
||||
* @tag_len: the length of tag
|
||||
*
|
||||
* Return: pointer to requested context, NULL if @str context not found
|
||||
* or error pointer if name length is invalid.
|
||||
*/
|
||||
struct create_context *smb2_find_context_vals(void *open_req, const char *tag)
|
||||
struct create_context *smb2_find_context_vals(void *open_req, const char *tag, int tag_len)
|
||||
{
|
||||
struct create_context *cc;
|
||||
unsigned int next = 0;
|
||||
@@ -1489,7 +1490,7 @@ struct create_context *smb2_find_context_vals(void *open_req, const char *tag)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
name = (char *)cc + name_off;
|
||||
if (memcmp(name, tag, name_len) == 0)
|
||||
if (name_len == tag_len && !memcmp(name, tag, name_len))
|
||||
return cc;
|
||||
|
||||
remain_len -= next;
|
||||
|
||||
@@ -120,7 +120,7 @@ void create_durable_v2_rsp_buf(char *cc, struct ksmbd_file *fp);
|
||||
void create_mxac_rsp_buf(char *cc, int maximal_access);
|
||||
void create_disk_id_rsp_buf(char *cc, __u64 file_id, __u64 vol_id);
|
||||
void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp);
|
||||
struct create_context *smb2_find_context_vals(void *open_req, const char *str);
|
||||
struct create_context *smb2_find_context_vals(void *open_req, const char *tag, int tag_len);
|
||||
struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
|
||||
char *lease_key);
|
||||
int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
|
||||
|
||||
@@ -2472,7 +2472,7 @@ static int smb2_create_sd_buffer(struct ksmbd_work *work,
|
||||
return -ENOENT;
|
||||
|
||||
/* Parse SD BUFFER create contexts */
|
||||
context = smb2_find_context_vals(req, SMB2_CREATE_SD_BUFFER);
|
||||
context = smb2_find_context_vals(req, SMB2_CREATE_SD_BUFFER, 4);
|
||||
if (!context)
|
||||
return -ENOENT;
|
||||
else if (IS_ERR(context))
|
||||
@@ -2673,7 +2673,7 @@ int smb2_open(struct ksmbd_work *work)
|
||||
|
||||
if (req->CreateContextsOffset) {
|
||||
/* Parse non-durable handle create contexts */
|
||||
context = smb2_find_context_vals(req, SMB2_CREATE_EA_BUFFER);
|
||||
context = smb2_find_context_vals(req, SMB2_CREATE_EA_BUFFER, 4);
|
||||
if (IS_ERR(context)) {
|
||||
rc = PTR_ERR(context);
|
||||
goto err_out1;
|
||||
@@ -2693,7 +2693,7 @@ int smb2_open(struct ksmbd_work *work)
|
||||
}
|
||||
|
||||
context = smb2_find_context_vals(req,
|
||||
SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST);
|
||||
SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST, 4);
|
||||
if (IS_ERR(context)) {
|
||||
rc = PTR_ERR(context);
|
||||
goto err_out1;
|
||||
@@ -2704,7 +2704,7 @@ int smb2_open(struct ksmbd_work *work)
|
||||
}
|
||||
|
||||
context = smb2_find_context_vals(req,
|
||||
SMB2_CREATE_TIMEWARP_REQUEST);
|
||||
SMB2_CREATE_TIMEWARP_REQUEST, 4);
|
||||
if (IS_ERR(context)) {
|
||||
rc = PTR_ERR(context);
|
||||
goto err_out1;
|
||||
@@ -2716,7 +2716,7 @@ int smb2_open(struct ksmbd_work *work)
|
||||
|
||||
if (tcon->posix_extensions) {
|
||||
context = smb2_find_context_vals(req,
|
||||
SMB2_CREATE_TAG_POSIX);
|
||||
SMB2_CREATE_TAG_POSIX, 16);
|
||||
if (IS_ERR(context)) {
|
||||
rc = PTR_ERR(context);
|
||||
goto err_out1;
|
||||
@@ -3121,7 +3121,7 @@ int smb2_open(struct ksmbd_work *work)
|
||||
struct create_alloc_size_req *az_req;
|
||||
|
||||
az_req = (struct create_alloc_size_req *)smb2_find_context_vals(req,
|
||||
SMB2_CREATE_ALLOCATION_SIZE);
|
||||
SMB2_CREATE_ALLOCATION_SIZE, 4);
|
||||
if (IS_ERR(az_req)) {
|
||||
rc = PTR_ERR(az_req);
|
||||
goto err_out;
|
||||
@@ -3148,7 +3148,7 @@ int smb2_open(struct ksmbd_work *work)
|
||||
err);
|
||||
}
|
||||
|
||||
context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID);
|
||||
context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID, 4);
|
||||
if (IS_ERR(context)) {
|
||||
rc = PTR_ERR(context);
|
||||
goto err_out;
|
||||
|
||||
Reference in New Issue
Block a user