Skip to content

Commit 6a31658

Browse files
committed
Merge tag '6.8-rc-smb-server-fixes' of git://git.samba.org/ksmbd
Pull smb server updates from Steve French: - memory allocation fix - three lease fixes, including important rename fix - read only share fix - thread freeze fix - three cleanup fixes (two kernel doc related) - locking fix in setting EAs - packet header validation fix * tag '6.8-rc-smb-server-fixes' of git://git.samba.org/ksmbd: ksmbd: Add missing set_freezable() for freezable kthread ksmbd: free ppace array on error in parse_dacl ksmbd: send lease break notification on FILE_RENAME_INFORMATION ksmbd: don't allow O_TRUNC open on read-only share ksmbd: vfs: fix all kernel-doc warnings ksmbd: auth: fix most kernel-doc warnings ksmbd: Remove usage of the deprecated ida_simple_xx() API ksmbd: don't increment epoch if current state and request state are same ksmbd: fix potential circular locking issue in smb2_set_ea() ksmbd: set v2 lease version on lease upgrade ksmbd: validate the zero field of packet header
2 parents 4889269 + 8fb7b72 commit 6a31658

File tree

8 files changed

+70
-58
lines changed

8 files changed

+70
-58
lines changed

fs/smb/server/auth.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,12 @@ static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,
208208

209209
/**
210210
* ksmbd_auth_ntlmv2() - NTLMv2 authentication handler
211-
* @sess: session of connection
211+
* @conn: connection
212+
* @sess: session of connection
212213
* @ntlmv2: NTLMv2 challenge response
213214
* @blen: NTLMv2 blob length
214215
* @domain_name: domain name
216+
* @cryptkey: session crypto key
215217
*
216218
* Return: 0 on success, error number on error
217219
*/
@@ -294,7 +296,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
294296
* ksmbd_decode_ntlmssp_auth_blob() - helper function to construct
295297
* authenticate blob
296298
* @authblob: authenticate blob source pointer
297-
* @usr: user details
299+
* @blob_len: length of the @authblob message
300+
* @conn: connection
298301
* @sess: session of connection
299302
*
300303
* Return: 0 on success, error number on error
@@ -376,8 +379,8 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
376379
* ksmbd_decode_ntlmssp_neg_blob() - helper function to construct
377380
* negotiate blob
378381
* @negblob: negotiate blob source pointer
379-
* @rsp: response header pointer to be updated
380-
* @sess: session of connection
382+
* @blob_len: length of the @authblob message
383+
* @conn: connection
381384
*
382385
*/
383386
int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
@@ -403,8 +406,7 @@ int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
403406
* ksmbd_build_ntlmssp_challenge_blob() - helper function to construct
404407
* challenge blob
405408
* @chgblob: challenge blob source pointer to initialize
406-
* @rsp: response header pointer to be updated
407-
* @sess: session of connection
409+
* @conn: connection
408410
*
409411
*/
410412
unsigned int

fs/smb/server/connection.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ int ksmbd_conn_handler_loop(void *p)
284284
goto out;
285285

286286
conn->last_active = jiffies;
287+
set_freezable();
287288
while (ksmbd_conn_alive(conn)) {
288289
if (try_to_freeze())
289290
continue;

fs/smb/server/mgmt/ksmbd_ida.c

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,33 @@
55

66
#include "ksmbd_ida.h"
77

8-
static inline int __acquire_id(struct ida *ida, int from, int to)
9-
{
10-
return ida_simple_get(ida, from, to, GFP_KERNEL);
11-
}
12-
138
int ksmbd_acquire_smb2_tid(struct ida *ida)
149
{
15-
int id;
16-
17-
id = __acquire_id(ida, 1, 0xFFFFFFFF);
18-
19-
return id;
10+
return ida_alloc_range(ida, 1, 0xFFFFFFFE, GFP_KERNEL);
2011
}
2112

2213
int ksmbd_acquire_smb2_uid(struct ida *ida)
2314
{
2415
int id;
2516

26-
id = __acquire_id(ida, 1, 0);
17+
id = ida_alloc_min(ida, 1, GFP_KERNEL);
2718
if (id == 0xFFFE)
28-
id = __acquire_id(ida, 1, 0);
19+
id = ida_alloc_min(ida, 1, GFP_KERNEL);
2920

3021
return id;
3122
}
3223

3324
int ksmbd_acquire_async_msg_id(struct ida *ida)
3425
{
35-
return __acquire_id(ida, 1, 0);
26+
return ida_alloc_min(ida, 1, GFP_KERNEL);
3627
}
3728

3829
int ksmbd_acquire_id(struct ida *ida)
3930
{
40-
return __acquire_id(ida, 0, 0);
31+
return ida_alloc(ida, GFP_KERNEL);
4132
}
4233

4334
void ksmbd_release_id(struct ida *ida, int id)
4435
{
45-
ida_simple_remove(ida, id);
36+
ida_free(ida, id);
4637
}

fs/smb/server/oplock.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static int alloc_lease(struct oplock_info *opinfo, struct lease_ctx_info *lctx)
105105
lease->is_dir = lctx->is_dir;
106106
memcpy(lease->parent_lease_key, lctx->parent_lease_key, SMB2_LEASE_KEY_SIZE);
107107
lease->version = lctx->version;
108-
lease->epoch = le16_to_cpu(lctx->epoch);
108+
lease->epoch = le16_to_cpu(lctx->epoch) + 1;
109109
INIT_LIST_HEAD(&opinfo->lease_entry);
110110
opinfo->o_lease = lease;
111111

@@ -546,6 +546,7 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
546546
atomic_read(&ci->sop_count)) == 1) {
547547
if (lease->state != SMB2_LEASE_NONE_LE &&
548548
lease->state == (lctx->req_state & lease->state)) {
549+
lease->epoch++;
549550
lease->state |= lctx->req_state;
550551
if (lctx->req_state &
551552
SMB2_LEASE_WRITE_CACHING_LE)
@@ -556,13 +557,17 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
556557
atomic_read(&ci->sop_count)) > 1) {
557558
if (lctx->req_state ==
558559
(SMB2_LEASE_READ_CACHING_LE |
559-
SMB2_LEASE_HANDLE_CACHING_LE))
560+
SMB2_LEASE_HANDLE_CACHING_LE)) {
561+
lease->epoch++;
560562
lease->state = lctx->req_state;
563+
}
561564
}
562565

563566
if (lctx->req_state && lease->state ==
564-
SMB2_LEASE_NONE_LE)
567+
SMB2_LEASE_NONE_LE) {
568+
lease->epoch++;
565569
lease_none_upgrade(opinfo, lctx->req_state);
570+
}
566571
}
567572
read_lock(&ci->m_lock);
568573
}
@@ -1035,7 +1040,8 @@ static void copy_lease(struct oplock_info *op1, struct oplock_info *op2)
10351040
SMB2_LEASE_KEY_SIZE);
10361041
lease2->duration = lease1->duration;
10371042
lease2->flags = lease1->flags;
1038-
lease2->epoch = lease1->epoch++;
1043+
lease2->epoch = lease1->epoch;
1044+
lease2->version = lease1->version;
10391045
}
10401046

10411047
static int add_lease_global_list(struct oplock_info *opinfo)
@@ -1447,7 +1453,7 @@ void create_lease_buf(u8 *rbuf, struct lease *lease)
14471453
memcpy(buf->lcontext.LeaseKey, lease->lease_key,
14481454
SMB2_LEASE_KEY_SIZE);
14491455
buf->lcontext.LeaseFlags = lease->flags;
1450-
buf->lcontext.Epoch = cpu_to_le16(++lease->epoch);
1456+
buf->lcontext.Epoch = cpu_to_le16(lease->epoch);
14511457
buf->lcontext.LeaseState = lease->state;
14521458
memcpy(buf->lcontext.ParentLeaseKey, lease->parent_lease_key,
14531459
SMB2_LEASE_KEY_SIZE);

fs/smb/server/smb2pdu.c

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2311,11 +2311,12 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work)
23112311
* @eabuf: set info command buffer
23122312
* @buf_len: set info command buffer length
23132313
* @path: dentry path for get ea
2314+
* @get_write: get write access to a mount
23142315
*
23152316
* Return: 0 on success, otherwise error
23162317
*/
23172318
static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len,
2318-
const struct path *path)
2319+
const struct path *path, bool get_write)
23192320
{
23202321
struct mnt_idmap *idmap = mnt_idmap(path->mnt);
23212322
char *attr_name = NULL, *value;
@@ -2971,7 +2972,7 @@ int smb2_open(struct ksmbd_work *work)
29712972
&may_flags);
29722973

29732974
if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
2974-
if (open_flags & O_CREAT) {
2975+
if (open_flags & (O_CREAT | O_TRUNC)) {
29752976
ksmbd_debug(SMB,
29762977
"User does not have write permission\n");
29772978
rc = -EACCES;
@@ -3003,7 +3004,7 @@ int smb2_open(struct ksmbd_work *work)
30033004

30043005
rc = smb2_set_ea(&ea_buf->ea,
30053006
le32_to_cpu(ea_buf->ccontext.DataLength),
3006-
&path);
3007+
&path, false);
30073008
if (rc == -EOPNOTSUPP)
30083009
rc = 0;
30093010
else if (rc)
@@ -5568,6 +5569,7 @@ static int smb2_rename(struct ksmbd_work *work,
55685569
if (!file_info->ReplaceIfExists)
55695570
flags = RENAME_NOREPLACE;
55705571

5572+
smb_break_all_levII_oplock(work, fp, 0);
55715573
rc = ksmbd_vfs_rename(work, &fp->filp->f_path, new_name, flags);
55725574
out:
55735575
kfree(new_name);
@@ -5943,12 +5945,6 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
59435945
}
59445946
case FILE_RENAME_INFORMATION:
59455947
{
5946-
if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
5947-
ksmbd_debug(SMB,
5948-
"User does not have write permission\n");
5949-
return -EACCES;
5950-
}
5951-
59525948
if (buf_len < sizeof(struct smb2_file_rename_info))
59535949
return -EINVAL;
59545950

@@ -5968,12 +5964,6 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
59685964
}
59695965
case FILE_DISPOSITION_INFORMATION:
59705966
{
5971-
if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
5972-
ksmbd_debug(SMB,
5973-
"User does not have write permission\n");
5974-
return -EACCES;
5975-
}
5976-
59775967
if (buf_len < sizeof(struct smb2_file_disposition_info))
59785968
return -EINVAL;
59795969

@@ -5992,7 +5982,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
59925982
return -EINVAL;
59935983

59945984
return smb2_set_ea((struct smb2_ea_info *)req->Buffer,
5995-
buf_len, &fp->filp->f_path);
5985+
buf_len, &fp->filp->f_path, true);
59965986
}
59975987
case FILE_POSITION_INFORMATION:
59985988
{
@@ -6035,7 +6025,7 @@ int smb2_set_info(struct ksmbd_work *work)
60356025
{
60366026
struct smb2_set_info_req *req;
60376027
struct smb2_set_info_rsp *rsp;
6038-
struct ksmbd_file *fp;
6028+
struct ksmbd_file *fp = NULL;
60396029
int rc = 0;
60406030
unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
60416031

@@ -6055,6 +6045,13 @@ int smb2_set_info(struct ksmbd_work *work)
60556045
rsp = smb2_get_msg(work->response_buf);
60566046
}
60576047

6048+
if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
6049+
ksmbd_debug(SMB, "User does not have write permission\n");
6050+
pr_err("User does not have write permission\n");
6051+
rc = -EACCES;
6052+
goto err_out;
6053+
}
6054+
60586055
if (!has_file_id(id)) {
60596056
id = req->VolatileFileId;
60606057
pid = req->PersistentFileId;

fs/smb/server/smb_common.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,12 @@ int ksmbd_verify_smb_message(struct ksmbd_work *work)
158158
*/
159159
bool ksmbd_smb_request(struct ksmbd_conn *conn)
160160
{
161-
__le32 *proto = (__le32 *)smb2_get_msg(conn->request_buf);
161+
__le32 *proto;
162162

163+
if (conn->request_buf[0] != 0)
164+
return false;
165+
166+
proto = (__le32 *)smb2_get_msg(conn->request_buf);
163167
if (*proto == SMB2_COMPRESSION_TRANSFORM_ID) {
164168
pr_err_ratelimited("smb2 compression not support yet");
165169
return false;

fs/smb/server/smbacl.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,10 +401,6 @@ static void parse_dacl(struct mnt_idmap *idmap,
401401
if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
402402
return;
403403

404-
ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), GFP_KERNEL);
405-
if (!ppace)
406-
return;
407-
408404
ret = init_acl_state(&acl_state, num_aces);
409405
if (ret)
410406
return;
@@ -414,6 +410,13 @@ static void parse_dacl(struct mnt_idmap *idmap,
414410
return;
415411
}
416412

413+
ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), GFP_KERNEL);
414+
if (!ppace) {
415+
free_acl_state(&default_acl_state);
416+
free_acl_state(&acl_state);
417+
return;
418+
}
419+
417420
/*
418421
* reset rwx permissions for user/group/other.
419422
* Also, if num_aces is 0 i.e. DACL has no ACEs,

0 commit comments

Comments
 (0)