Skip to content

Commit 405ac6a

Browse files
committed
Merge tag '6.9-rc2-ksmbd-server-fixes' of git://git.samba.org/ksmbd
Pull smb server fixes from Steve French: "Three fixes, all also for stable: - encryption fix - memory overrun fix - oplock break fix" * tag '6.9-rc2-ksmbd-server-fixes' of git://git.samba.org/ksmbd: ksmbd: do not set SMB2_GLOBAL_CAP_ENCRYPTION for SMB 3.1.1 ksmbd: validate payload size in ipc response ksmbd: don't send oplock break if rename fails
2 parents fae0268 + 5ed11af commit 405ac6a

File tree

5 files changed

+52
-8
lines changed

5 files changed

+52
-8
lines changed

fs/smb/server/ksmbd_netlink.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ struct ksmbd_share_config_response {
167167
__u16 force_uid;
168168
__u16 force_gid;
169169
__s8 share_name[KSMBD_REQ_MAX_SHARE_NAME];
170-
__u32 reserved[112]; /* Reserved room */
170+
__u32 reserved[111]; /* Reserved room */
171+
__u32 payload_sz;
171172
__u32 veto_list_sz;
172173
__s8 ____payload[];
173174
};

fs/smb/server/mgmt/share_config.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,12 @@ static struct ksmbd_share_config *share_config_request(struct unicode_map *um,
158158
share->name = kstrdup(name, GFP_KERNEL);
159159

160160
if (!test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) {
161-
share->path = kstrdup(ksmbd_share_config_path(resp),
161+
int path_len = PATH_MAX;
162+
163+
if (resp->payload_sz)
164+
path_len = resp->payload_sz - resp->veto_list_sz;
165+
166+
share->path = kstrndup(ksmbd_share_config_path(resp), path_len,
162167
GFP_KERNEL);
163168
if (share->path)
164169
share->path_sz = strlen(share->path);

fs/smb/server/smb2ops.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ void init_smb3_0_server(struct ksmbd_conn *conn)
228228
conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION)
229229
conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
230230

231+
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
232+
(!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
233+
conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
234+
conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
235+
231236
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
232237
conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
233238
}
@@ -278,11 +283,6 @@ int init_smb3_11_server(struct ksmbd_conn *conn)
278283
conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
279284
SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
280285

281-
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
282-
(!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
283-
conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
284-
conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
285-
286286
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
287287
conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
288288

fs/smb/server/smb2pdu.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5857,8 +5857,9 @@ static int smb2_rename(struct ksmbd_work *work,
58575857
if (!file_info->ReplaceIfExists)
58585858
flags = RENAME_NOREPLACE;
58595859

5860-
smb_break_all_levII_oplock(work, fp, 0);
58615860
rc = ksmbd_vfs_rename(work, &fp->filp->f_path, new_name, flags);
5861+
if (!rc)
5862+
smb_break_all_levII_oplock(work, fp, 0);
58625863
out:
58635864
kfree(new_name);
58645865
return rc;

fs/smb/server/transport_ipc.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ struct ipc_msg_table_entry {
6565
struct hlist_node ipc_table_hlist;
6666

6767
void *response;
68+
unsigned int msg_sz;
6869
};
6970

7071
static struct delayed_work ipc_timer_work;
@@ -275,6 +276,7 @@ static int handle_response(int type, void *payload, size_t sz)
275276
}
276277

277278
memcpy(entry->response, payload, sz);
279+
entry->msg_sz = sz;
278280
wake_up_interruptible(&entry->wait);
279281
ret = 0;
280282
break;
@@ -453,6 +455,34 @@ static int ipc_msg_send(struct ksmbd_ipc_msg *msg)
453455
return ret;
454456
}
455457

458+
static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
459+
{
460+
unsigned int msg_sz = entry->msg_sz;
461+
462+
if (entry->type == KSMBD_EVENT_RPC_REQUEST) {
463+
struct ksmbd_rpc_command *resp = entry->response;
464+
465+
msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz;
466+
} else if (entry->type == KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST) {
467+
struct ksmbd_spnego_authen_response *resp = entry->response;
468+
469+
msg_sz = sizeof(struct ksmbd_spnego_authen_response) +
470+
resp->session_key_len + resp->spnego_blob_len;
471+
} else if (entry->type == KSMBD_EVENT_SHARE_CONFIG_REQUEST) {
472+
struct ksmbd_share_config_response *resp = entry->response;
473+
474+
if (resp->payload_sz) {
475+
if (resp->payload_sz < resp->veto_list_sz)
476+
return -EINVAL;
477+
478+
msg_sz = sizeof(struct ksmbd_share_config_response) +
479+
resp->payload_sz;
480+
}
481+
}
482+
483+
return entry->msg_sz != msg_sz ? -EINVAL : 0;
484+
}
485+
456486
static void *ipc_msg_send_request(struct ksmbd_ipc_msg *msg, unsigned int handle)
457487
{
458488
struct ipc_msg_table_entry entry;
@@ -477,6 +507,13 @@ static void *ipc_msg_send_request(struct ksmbd_ipc_msg *msg, unsigned int handle
477507
ret = wait_event_interruptible_timeout(entry.wait,
478508
entry.response != NULL,
479509
IPC_WAIT_TIMEOUT);
510+
if (entry.response) {
511+
ret = ipc_validate_msg(&entry);
512+
if (ret) {
513+
kvfree(entry.response);
514+
entry.response = NULL;
515+
}
516+
}
480517
out:
481518
down_write(&ipc_msg_table_lock);
482519
hash_del(&entry.ipc_table_hlist);

0 commit comments

Comments
 (0)