Skip to content

Commit a613224

Browse files
committed
Merge tag '5.16-rc-ksmbd-fixes' of git://git.samba.org/ksmbd
Pull ksmbd updates from Steve French: "Several smb server fixes; three for stable: - important fix for negotiation info validation - fix alignment check in packet validation - cleanup of dead code (like MD4) - refactoring some protocol headers to use common code in smbfs_common" * tag '5.16-rc-ksmbd-fixes' of git://git.samba.org/ksmbd: ksmbd: Use the SMB3_Create definitions from the shared ksmbd: Move more definitions into the shared area ksmbd: use the common definitions for NEGOTIATE_PROTOCOL ksmbd: switch to use shared definitions where available ksmbd: change LeaseKey data type to u8 array ksmbd: remove smb2_buf_length in smb2_transform_hdr ksmbd: remove smb2_buf_length in smb2_hdr ksmbd: remove md4 leftovers ksmbd: set unique value to volume serial field in FS_VOLUME_INFORMATION ksmbd: don't need 8byte alignment for request length in ksmbd_check_message ksmbd: Fix buffer length check in fsctl_validate_negotiate_info() ksmbd: Remove redundant 'flush_workqueue()' calls ksmdb: use cmd helper variable in smb2_get_ksmbd_tcon() ksmbd: use ksmbd_req_buf_next() in ksmbd_smb2_check_message() ksmbd: use ksmbd_req_buf_next() in ksmbd_verify_smb_message()
2 parents 0ecca62 + 26a2787 commit a613224

17 files changed

+372
-1139
lines changed

fs/ksmbd/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ config SMB_SERVER
66
select NLS
77
select NLS_UTF8
88
select CRYPTO
9-
select CRYPTO_MD4
109
select CRYPTO_MD5
1110
select CRYPTO_HMAC
1211
select CRYPTO_ECB
@@ -19,6 +18,7 @@ config SMB_SERVER
1918
select CRYPTO_GCM
2019
select ASN1
2120
select OID_REGISTRY
21+
select CRC32
2222
default n
2323
help
2424
Choose Y here if you want to allow SMB3 compliant clients

fs/ksmbd/auth.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -873,9 +873,9 @@ int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
873873
__u8 *pi_hash)
874874
{
875875
int rc;
876-
struct smb2_hdr *rcv_hdr = (struct smb2_hdr *)buf;
876+
struct smb2_hdr *rcv_hdr = smb2_get_msg(buf);
877877
char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
878-
int msg_size = be32_to_cpu(rcv_hdr->smb2_buf_length);
878+
int msg_size = get_rfc1002_len(buf);
879879
struct ksmbd_crypto_ctx *ctx = NULL;
880880

881881
if (conn->preauth_info->Preauth_HashId !=
@@ -983,7 +983,7 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
983983
u8 *sign)
984984
{
985985
struct scatterlist *sg;
986-
unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
986+
unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
987987
int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0;
988988

989989
if (!nvec)
@@ -1047,9 +1047,8 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
10471047
int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
10481048
unsigned int nvec, int enc)
10491049
{
1050-
struct smb2_transform_hdr *tr_hdr =
1051-
(struct smb2_transform_hdr *)iov[0].iov_base;
1052-
unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
1050+
struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
1051+
unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
10531052
int rc;
10541053
struct scatterlist *sg;
10551054
u8 sign[SMB2_SIGNATURE_SIZE] = {};

fs/ksmbd/connection.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,35 +158,34 @@ void ksmbd_conn_wait_idle(struct ksmbd_conn *conn)
158158
int ksmbd_conn_write(struct ksmbd_work *work)
159159
{
160160
struct ksmbd_conn *conn = work->conn;
161-
struct smb_hdr *rsp_hdr = work->response_buf;
162161
size_t len = 0;
163162
int sent;
164163
struct kvec iov[3];
165164
int iov_idx = 0;
166165

167166
ksmbd_conn_try_dequeue_request(work);
168-
if (!rsp_hdr) {
167+
if (!work->response_buf) {
169168
pr_err("NULL response header\n");
170169
return -EINVAL;
171170
}
172171

173172
if (work->tr_buf) {
174173
iov[iov_idx] = (struct kvec) { work->tr_buf,
175-
sizeof(struct smb2_transform_hdr) };
174+
sizeof(struct smb2_transform_hdr) + 4 };
176175
len += iov[iov_idx++].iov_len;
177176
}
178177

179178
if (work->aux_payload_sz) {
180-
iov[iov_idx] = (struct kvec) { rsp_hdr, work->resp_hdr_sz };
179+
iov[iov_idx] = (struct kvec) { work->response_buf, work->resp_hdr_sz };
181180
len += iov[iov_idx++].iov_len;
182181
iov[iov_idx] = (struct kvec) { work->aux_payload_buf, work->aux_payload_sz };
183182
len += iov[iov_idx++].iov_len;
184183
} else {
185184
if (work->tr_buf)
186185
iov[iov_idx].iov_len = work->resp_hdr_sz;
187186
else
188-
iov[iov_idx].iov_len = get_rfc1002_len(rsp_hdr) + 4;
189-
iov[iov_idx].iov_base = rsp_hdr;
187+
iov[iov_idx].iov_len = get_rfc1002_len(work->response_buf) + 4;
188+
iov[iov_idx].iov_base = work->response_buf;
190189
len += iov[iov_idx++].iov_len;
191190
}
192191

fs/ksmbd/ksmbd_work.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ int ksmbd_workqueue_init(void)
6969

7070
void ksmbd_workqueue_destroy(void)
7171
{
72-
flush_workqueue(ksmbd_wq);
7372
destroy_workqueue(ksmbd_wq);
7473
ksmbd_wq = NULL;
7574
}

fs/ksmbd/ksmbd_work.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ struct ksmbd_work {
9292
*/
9393
static inline void *ksmbd_resp_buf_next(struct ksmbd_work *work)
9494
{
95-
return work->response_buf + work->next_smb2_rsp_hdr_off;
95+
return work->response_buf + work->next_smb2_rsp_hdr_off + 4;
9696
}
9797

9898
/**
@@ -101,7 +101,7 @@ static inline void *ksmbd_resp_buf_next(struct ksmbd_work *work)
101101
*/
102102
static inline void *ksmbd_req_buf_next(struct ksmbd_work *work)
103103
{
104-
return work->request_buf + work->next_smb2_rcv_hdr_off;
104+
return work->request_buf + work->next_smb2_rcv_hdr_off + 4;
105105
}
106106

107107
struct ksmbd_work *ksmbd_alloc_work_struct(void);

fs/ksmbd/oplock.c

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -629,10 +629,10 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
629629
return;
630630
}
631631

632-
rsp_hdr = work->response_buf;
632+
rsp_hdr = smb2_get_msg(work->response_buf);
633633
memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
634-
rsp_hdr->smb2_buf_length =
635-
cpu_to_be32(smb2_hdr_size_no_buflen(conn->vals));
634+
*(__be32 *)work->response_buf =
635+
cpu_to_be32(conn->vals->header_size);
636636
rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER;
637637
rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE;
638638
rsp_hdr->CreditRequest = cpu_to_le16(0);
@@ -645,7 +645,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
645645
rsp_hdr->SessionId = 0;
646646
memset(rsp_hdr->Signature, 0, 16);
647647

648-
rsp = work->response_buf;
648+
rsp = smb2_get_msg(work->response_buf);
649649

650650
rsp->StructureSize = cpu_to_le16(24);
651651
if (!br_info->open_trunc &&
@@ -659,7 +659,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
659659
rsp->PersistentFid = cpu_to_le64(fp->persistent_id);
660660
rsp->VolatileFid = cpu_to_le64(fp->volatile_id);
661661

662-
inc_rfc1001_len(rsp, 24);
662+
inc_rfc1001_len(work->response_buf, 24);
663663

664664
ksmbd_debug(OPLOCK,
665665
"sending oplock break v_id %llu p_id = %llu lock level = %d\n",
@@ -736,10 +736,10 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
736736
return;
737737
}
738738

739-
rsp_hdr = work->response_buf;
739+
rsp_hdr = smb2_get_msg(work->response_buf);
740740
memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
741-
rsp_hdr->smb2_buf_length =
742-
cpu_to_be32(smb2_hdr_size_no_buflen(conn->vals));
741+
*(__be32 *)work->response_buf =
742+
cpu_to_be32(conn->vals->header_size);
743743
rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER;
744744
rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE;
745745
rsp_hdr->CreditRequest = cpu_to_le16(0);
@@ -752,7 +752,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
752752
rsp_hdr->SessionId = 0;
753753
memset(rsp_hdr->Signature, 0, 16);
754754

755-
rsp = work->response_buf;
755+
rsp = smb2_get_msg(work->response_buf);
756756
rsp->StructureSize = cpu_to_le16(44);
757757
rsp->Epoch = br_info->epoch;
758758
rsp->Flags = 0;
@@ -768,7 +768,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
768768
rsp->AccessMaskHint = 0;
769769
rsp->ShareMaskHint = 0;
770770

771-
inc_rfc1001_len(rsp, 44);
771+
inc_rfc1001_len(work->response_buf, 44);
772772

773773
ksmbd_conn_write(work);
774774
ksmbd_free_work_struct(work);
@@ -1335,19 +1335,16 @@ __u8 smb2_map_lease_to_oplock(__le32 lease_state)
13351335
*/
13361336
void create_lease_buf(u8 *rbuf, struct lease *lease)
13371337
{
1338-
char *LeaseKey = (char *)&lease->lease_key;
1339-
13401338
if (lease->version == 2) {
13411339
struct create_lease_v2 *buf = (struct create_lease_v2 *)rbuf;
1342-
char *ParentLeaseKey = (char *)&lease->parent_lease_key;
13431340

13441341
memset(buf, 0, sizeof(struct create_lease_v2));
1345-
buf->lcontext.LeaseKeyLow = *((__le64 *)LeaseKey);
1346-
buf->lcontext.LeaseKeyHigh = *((__le64 *)(LeaseKey + 8));
1342+
memcpy(buf->lcontext.LeaseKey, lease->lease_key,
1343+
SMB2_LEASE_KEY_SIZE);
13471344
buf->lcontext.LeaseFlags = lease->flags;
13481345
buf->lcontext.LeaseState = lease->state;
1349-
buf->lcontext.ParentLeaseKeyLow = *((__le64 *)ParentLeaseKey);
1350-
buf->lcontext.ParentLeaseKeyHigh = *((__le64 *)(ParentLeaseKey + 8));
1346+
memcpy(buf->lcontext.ParentLeaseKey, lease->parent_lease_key,
1347+
SMB2_LEASE_KEY_SIZE);
13511348
buf->ccontext.DataOffset = cpu_to_le16(offsetof
13521349
(struct create_lease_v2, lcontext));
13531350
buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2));
@@ -1362,8 +1359,7 @@ void create_lease_buf(u8 *rbuf, struct lease *lease)
13621359
struct create_lease *buf = (struct create_lease *)rbuf;
13631360

13641361
memset(buf, 0, sizeof(struct create_lease));
1365-
buf->lcontext.LeaseKeyLow = *((__le64 *)LeaseKey);
1366-
buf->lcontext.LeaseKeyHigh = *((__le64 *)(LeaseKey + 8));
1362+
memcpy(buf->lcontext.LeaseKey, lease->lease_key, SMB2_LEASE_KEY_SIZE);
13671363
buf->lcontext.LeaseFlags = lease->flags;
13681364
buf->lcontext.LeaseState = lease->state;
13691365
buf->ccontext.DataOffset = cpu_to_le16(offsetof
@@ -1398,7 +1394,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
13981394
if (!lreq)
13991395
return NULL;
14001396

1401-
data_offset = (char *)req + 4 + le32_to_cpu(req->CreateContextsOffset);
1397+
data_offset = (char *)req + le32_to_cpu(req->CreateContextsOffset);
14021398
cc = (struct create_context *)data_offset;
14031399
do {
14041400
cc = (struct create_context *)((char *)cc + next);
@@ -1416,19 +1412,17 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
14161412
if (sizeof(struct lease_context_v2) == le32_to_cpu(cc->DataLength)) {
14171413
struct create_lease_v2 *lc = (struct create_lease_v2 *)cc;
14181414

1419-
*((__le64 *)lreq->lease_key) = lc->lcontext.LeaseKeyLow;
1420-
*((__le64 *)(lreq->lease_key + 8)) = lc->lcontext.LeaseKeyHigh;
1415+
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
14211416
lreq->req_state = lc->lcontext.LeaseState;
14221417
lreq->flags = lc->lcontext.LeaseFlags;
14231418
lreq->duration = lc->lcontext.LeaseDuration;
1424-
*((__le64 *)lreq->parent_lease_key) = lc->lcontext.ParentLeaseKeyLow;
1425-
*((__le64 *)(lreq->parent_lease_key + 8)) = lc->lcontext.ParentLeaseKeyHigh;
1419+
memcpy(lreq->parent_lease_key, lc->lcontext.ParentLeaseKey,
1420+
SMB2_LEASE_KEY_SIZE);
14261421
lreq->version = 2;
14271422
} else {
14281423
struct create_lease *lc = (struct create_lease *)cc;
14291424

1430-
*((__le64 *)lreq->lease_key) = lc->lcontext.LeaseKeyLow;
1431-
*((__le64 *)(lreq->lease_key + 8)) = lc->lcontext.LeaseKeyHigh;
1425+
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
14321426
lreq->req_state = lc->lcontext.LeaseState;
14331427
lreq->flags = lc->lcontext.LeaseFlags;
14341428
lreq->duration = lc->lcontext.LeaseDuration;
@@ -1462,7 +1456,7 @@ struct create_context *smb2_find_context_vals(void *open_req, const char *tag)
14621456
* CreateContextsOffset and CreateContextsLength are guaranteed to
14631457
* be valid because of ksmbd_smb2_check_message().
14641458
*/
1465-
cc = (struct create_context *)((char *)req + 4 +
1459+
cc = (struct create_context *)((char *)req +
14661460
le32_to_cpu(req->CreateContextsOffset));
14671461
remain_len = le32_to_cpu(req->CreateContextsLength);
14681462
do {

fs/ksmbd/oplock.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
#define OPLOCK_WRITE_TO_NONE 0x04
2929
#define OPLOCK_READ_TO_NONE 0x08
3030

31-
#define SMB2_LEASE_KEY_SIZE 16
32-
3331
struct lease_ctx_info {
3432
__u8 lease_key[SMB2_LEASE_KEY_SIZE];
3533
__le32 req_state;

fs/ksmbd/server.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,6 @@ MODULE_DESCRIPTION("Linux kernel CIFS/SMB SERVER");
622622
MODULE_LICENSE("GPL");
623623
MODULE_SOFTDEP("pre: ecb");
624624
MODULE_SOFTDEP("pre: hmac");
625-
MODULE_SOFTDEP("pre: md4");
626625
MODULE_SOFTDEP("pre: md5");
627626
MODULE_SOFTDEP("pre: nls");
628627
MODULE_SOFTDEP("pre: aes");
@@ -632,5 +631,6 @@ MODULE_SOFTDEP("pre: sha512");
632631
MODULE_SOFTDEP("pre: aead2");
633632
MODULE_SOFTDEP("pre: ccm");
634633
MODULE_SOFTDEP("pre: gcm");
634+
MODULE_SOFTDEP("pre: crc32");
635635
module_init(ksmbd_server_init)
636636
module_exit(ksmbd_server_exit)

fs/ksmbd/smb2misc.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#include "glob.h"
88
#include "nterr.h"
9-
#include "smb2pdu.h"
109
#include "smb_common.h"
1110
#include "smbstatus.h"
1211
#include "mgmt/user_session.h"
@@ -347,23 +346,16 @@ static int smb2_validate_credit_charge(struct ksmbd_conn *conn,
347346

348347
int ksmbd_smb2_check_message(struct ksmbd_work *work)
349348
{
350-
struct smb2_pdu *pdu = work->request_buf;
349+
struct smb2_pdu *pdu = ksmbd_req_buf_next(work);
351350
struct smb2_hdr *hdr = &pdu->hdr;
352351
int command;
353352
__u32 clc_len; /* calculated length */
354-
__u32 len = get_rfc1002_len(pdu);
353+
__u32 len = get_rfc1002_len(work->request_buf);
355354

356-
if (work->next_smb2_rcv_hdr_off) {
357-
pdu = ksmbd_req_buf_next(work);
358-
hdr = &pdu->hdr;
359-
}
360-
361-
if (le32_to_cpu(hdr->NextCommand) > 0) {
355+
if (le32_to_cpu(hdr->NextCommand) > 0)
362356
len = le32_to_cpu(hdr->NextCommand);
363-
} else if (work->next_smb2_rcv_hdr_off) {
357+
else if (work->next_smb2_rcv_hdr_off)
364358
len -= work->next_smb2_rcv_hdr_off;
365-
len = round_up(len, 8);
366-
}
367359

368360
if (check_smb2_hdr(hdr))
369361
return 1;

fs/ksmbd/smb2ops.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#include <linux/slab.h>
88
#include "glob.h"
9-
#include "smb2pdu.h"
109

1110
#include "auth.h"
1211
#include "connection.h"
@@ -199,7 +198,7 @@ void init_smb2_1_server(struct ksmbd_conn *conn)
199198
conn->cmds = smb2_0_server_cmds;
200199
conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
201200
conn->max_credits = SMB2_MAX_CREDITS;
202-
conn->signing_algorithm = SIGNING_ALG_HMAC_SHA256;
201+
conn->signing_algorithm = SIGNING_ALG_HMAC_SHA256_LE;
203202

204203
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
205204
conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
@@ -217,7 +216,7 @@ void init_smb3_0_server(struct ksmbd_conn *conn)
217216
conn->cmds = smb2_0_server_cmds;
218217
conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
219218
conn->max_credits = SMB2_MAX_CREDITS;
220-
conn->signing_algorithm = SIGNING_ALG_AES_CMAC;
219+
conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
221220

222221
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
223222
conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
@@ -242,7 +241,7 @@ void init_smb3_02_server(struct ksmbd_conn *conn)
242241
conn->cmds = smb2_0_server_cmds;
243242
conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
244243
conn->max_credits = SMB2_MAX_CREDITS;
245-
conn->signing_algorithm = SIGNING_ALG_AES_CMAC;
244+
conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
246245

247246
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
248247
conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
@@ -267,7 +266,7 @@ int init_smb3_11_server(struct ksmbd_conn *conn)
267266
conn->cmds = smb2_0_server_cmds;
268267
conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
269268
conn->max_credits = SMB2_MAX_CREDITS;
270-
conn->signing_algorithm = SIGNING_ALG_AES_CMAC;
269+
conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
271270

272271
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
273272
conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;

0 commit comments

Comments
 (0)