Skip to content

Commit b311c1b

Browse files
committed
Merge tag '6.11-rc4-server-fixes' of git://git.samba.org/ksmbd
Pull smb server fixes from Steve French: - important reconnect fix - fix for memcpy issues on mount - two minor cleanup patches * tag '6.11-rc4-server-fixes' of git://git.samba.org/ksmbd: ksmbd: Replace one-element arrays with flexible-array members ksmbd: fix spelling mistakes in documentation ksmbd: fix race condition between destroy_previous_session() and smb2 operations() ksmbd: Use unsafe_memcpy() for ntlm_negotiate
2 parents 0108b7b + 7c525dd commit b311c1b

File tree

6 files changed

+67
-22
lines changed

6 files changed

+67
-22
lines changed

Documentation/filesystems/smb/ksmbd.rst

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ KSMBD architecture
1313
The subset of performance related operations belong in kernelspace and
1414
the other subset which belong to operations which are not really related with
1515
performance in userspace. So, DCE/RPC management that has historically resulted
16-
into number of buffer overflow issues and dangerous security bugs and user
16+
into a number of buffer overflow issues and dangerous security bugs and user
1717
account management are implemented in user space as ksmbd.mountd.
1818
File operations that are related with performance (open/read/write/close etc.)
1919
in kernel space (ksmbd). This also allows for easier integration with VFS
@@ -24,8 +24,8 @@ ksmbd (kernel daemon)
2424

2525
When the server daemon is started, It starts up a forker thread
2626
(ksmbd/interface name) at initialization time and open a dedicated port 445
27-
for listening to SMB requests. Whenever new clients make request, Forker
28-
thread will accept the client connection and fork a new thread for dedicated
27+
for listening to SMB requests. Whenever new clients make a request, the Forker
28+
thread will accept the client connection and fork a new thread for a dedicated
2929
communication channel between the client and the server. It allows for parallel
3030
processing of SMB requests(commands) from clients as well as allowing for new
3131
clients to make new connections. Each instance is named ksmbd/1~n(port number)
@@ -34,12 +34,12 @@ thread can decide to pass through the commands to the user space (ksmbd.mountd),
3434
currently DCE/RPC commands are identified to be handled through the user space.
3535
To further utilize the linux kernel, it has been chosen to process the commands
3636
as workitems and to be executed in the handlers of the ksmbd-io kworker threads.
37-
It allows for multiplexing of the handlers as the kernel take care of initiating
37+
It allows for multiplexing of the handlers as the kernel takes care of initiating
3838
extra worker threads if the load is increased and vice versa, if the load is
39-
decreased it destroys the extra worker threads. So, after connection is
40-
established with client. Dedicated ksmbd/1..n(port number) takes complete
39+
decreased it destroys the extra worker threads. So, after the connection is
40+
established with the client. Dedicated ksmbd/1..n(port number) takes complete
4141
ownership of receiving/parsing of SMB commands. Each received command is worked
42-
in parallel i.e., There can be multiple clients commands which are worked in
42+
in parallel i.e., there can be multiple client commands which are worked in
4343
parallel. After receiving each command a separated kernel workitem is prepared
4444
for each command which is further queued to be handled by ksmbd-io kworkers.
4545
So, each SMB workitem is queued to the kworkers. This allows the benefit of load
@@ -49,9 +49,9 @@ performance by handling client commands in parallel.
4949
ksmbd.mountd (user space daemon)
5050
--------------------------------
5151

52-
ksmbd.mountd is userspace process to, transfer user account and password that
52+
ksmbd.mountd is a userspace process to, transfer the user account and password that
5353
are registered using ksmbd.adduser (part of utils for user space). Further it
54-
allows sharing information parameters that parsed from smb.conf to ksmbd in
54+
allows sharing information parameters that are parsed from smb.conf to ksmbd in
5555
kernel. For the execution part it has a daemon which is continuously running
5656
and connected to the kernel interface using netlink socket, it waits for the
5757
requests (dcerpc and share/user info). It handles RPC calls (at a minimum few
@@ -124,7 +124,7 @@ How to run
124124
1. Download ksmbd-tools(https://github.com/cifsd-team/ksmbd-tools/releases) and
125125
compile them.
126126

127-
- Refer README(https://github.com/cifsd-team/ksmbd-tools/blob/master/README.md)
127+
- Refer to README(https://github.com/cifsd-team/ksmbd-tools/blob/master/README.md)
128128
to know how to use ksmbd.mountd/adduser/addshare/control utils
129129

130130
$ ./autogen.sh
@@ -133,7 +133,7 @@ How to run
133133

134134
2. Create /usr/local/etc/ksmbd/ksmbd.conf file, add SMB share in ksmbd.conf file.
135135

136-
- Refer ksmbd.conf.example in ksmbd-utils, See ksmbd.conf manpage
136+
- Refer to ksmbd.conf.example in ksmbd-utils, See ksmbd.conf manpage
137137
for details to configure shares.
138138

139139
$ man ksmbd.conf
@@ -145,7 +145,7 @@ How to run
145145
$ man ksmbd.adduser
146146
$ sudo ksmbd.adduser -a <Enter USERNAME for SMB share access>
147147

148-
4. Insert ksmbd.ko module after build your kernel. No need to load module
148+
4. Insert the ksmbd.ko module after you build your kernel. No need to load the module
149149
if ksmbd is built into the kernel.
150150

151151
- Set ksmbd in menuconfig(e.g. $ make menuconfig)
@@ -175,7 +175,7 @@ Each layer
175175
1. Enable all component prints
176176
# sudo ksmbd.control -d "all"
177177

178-
2. Enable one of components (smb, auth, vfs, oplock, ipc, conn, rdma)
178+
2. Enable one of the components (smb, auth, vfs, oplock, ipc, conn, rdma)
179179
# sudo ksmbd.control -d "smb"
180180

181181
3. Show what prints are enabled.

fs/smb/server/connection.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,43 @@ void ksmbd_all_conn_set_status(u64 sess_id, u32 status)
165165
up_read(&conn_list_lock);
166166
}
167167

168-
void ksmbd_conn_wait_idle(struct ksmbd_conn *conn, u64 sess_id)
168+
void ksmbd_conn_wait_idle(struct ksmbd_conn *conn)
169169
{
170170
wait_event(conn->req_running_q, atomic_read(&conn->req_running) < 2);
171171
}
172172

173+
int ksmbd_conn_wait_idle_sess_id(struct ksmbd_conn *curr_conn, u64 sess_id)
174+
{
175+
struct ksmbd_conn *conn;
176+
int rc, retry_count = 0, max_timeout = 120;
177+
int rcount = 1;
178+
179+
retry_idle:
180+
if (retry_count >= max_timeout)
181+
return -EIO;
182+
183+
down_read(&conn_list_lock);
184+
list_for_each_entry(conn, &conn_list, conns_list) {
185+
if (conn->binding || xa_load(&conn->sessions, sess_id)) {
186+
if (conn == curr_conn)
187+
rcount = 2;
188+
if (atomic_read(&conn->req_running) >= rcount) {
189+
rc = wait_event_timeout(conn->req_running_q,
190+
atomic_read(&conn->req_running) < rcount,
191+
HZ);
192+
if (!rc) {
193+
up_read(&conn_list_lock);
194+
retry_count++;
195+
goto retry_idle;
196+
}
197+
}
198+
}
199+
}
200+
up_read(&conn_list_lock);
201+
202+
return 0;
203+
}
204+
173205
int ksmbd_conn_write(struct ksmbd_work *work)
174206
{
175207
struct ksmbd_conn *conn = work->conn;

fs/smb/server/connection.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ extern struct list_head conn_list;
145145
extern struct rw_semaphore conn_list_lock;
146146

147147
bool ksmbd_conn_alive(struct ksmbd_conn *conn);
148-
void ksmbd_conn_wait_idle(struct ksmbd_conn *conn, u64 sess_id);
148+
void ksmbd_conn_wait_idle(struct ksmbd_conn *conn);
149+
int ksmbd_conn_wait_idle_sess_id(struct ksmbd_conn *curr_conn, u64 sess_id);
149150
struct ksmbd_conn *ksmbd_conn_alloc(void);
150151
void ksmbd_conn_free(struct ksmbd_conn *conn);
151152
bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);

fs/smb/server/mgmt/user_session.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ void destroy_previous_session(struct ksmbd_conn *conn,
311311
{
312312
struct ksmbd_session *prev_sess;
313313
struct ksmbd_user *prev_user;
314+
int err;
314315

315316
down_write(&sessions_table_lock);
316317
down_write(&conn->session_lock);
@@ -325,8 +326,16 @@ void destroy_previous_session(struct ksmbd_conn *conn,
325326
memcmp(user->passkey, prev_user->passkey, user->passkey_sz))
326327
goto out;
327328

329+
ksmbd_all_conn_set_status(id, KSMBD_SESS_NEED_RECONNECT);
330+
err = ksmbd_conn_wait_idle_sess_id(conn, id);
331+
if (err) {
332+
ksmbd_all_conn_set_status(id, KSMBD_SESS_NEED_NEGOTIATE);
333+
goto out;
334+
}
335+
328336
ksmbd_destroy_file_table(&prev_sess->file_table);
329337
prev_sess->state = SMB2_SESSION_EXPIRED;
338+
ksmbd_all_conn_set_status(id, KSMBD_SESS_NEED_NEGOTIATE);
330339
ksmbd_launch_ksmbd_durable_scavenger();
331340
out:
332341
up_write(&conn->session_lock);

fs/smb/server/smb2pdu.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,7 +1370,8 @@ static int ntlm_negotiate(struct ksmbd_work *work,
13701370
}
13711371

13721372
sz = le16_to_cpu(rsp->SecurityBufferOffset);
1373-
memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len);
1373+
unsafe_memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len,
1374+
/* alloc is larger than blob, see smb2_allocate_rsp_buf() */);
13741375
rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len);
13751376

13761377
out:
@@ -1453,7 +1454,9 @@ static int ntlm_authenticate(struct ksmbd_work *work,
14531454
return -ENOMEM;
14541455

14551456
sz = le16_to_cpu(rsp->SecurityBufferOffset);
1456-
memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len);
1457+
unsafe_memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob,
1458+
spnego_blob_len,
1459+
/* alloc is larger than blob, see smb2_allocate_rsp_buf() */);
14571460
rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len);
14581461
kfree(spnego_blob);
14591462
}
@@ -2210,7 +2213,7 @@ int smb2_session_logoff(struct ksmbd_work *work)
22102213
ksmbd_conn_unlock(conn);
22112214

22122215
ksmbd_close_session_fds(work);
2213-
ksmbd_conn_wait_idle(conn, sess_id);
2216+
ksmbd_conn_wait_idle(conn);
22142217

22152218
/*
22162219
* Re-lookup session to validate if session is deleted
@@ -5357,7 +5360,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
53575360
"NTFS", PATH_MAX, conn->local_nls, 0);
53585361
len = len * 2;
53595362
info->FileSystemNameLen = cpu_to_le32(len);
5360-
sz = sizeof(struct filesystem_attribute_info) - 2 + len;
5363+
sz = sizeof(struct filesystem_attribute_info) + len;
53615364
rsp->OutputBufferLength = cpu_to_le32(sz);
53625365
break;
53635366
}
@@ -5383,7 +5386,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
53835386
len = len * 2;
53845387
info->VolumeLabelSize = cpu_to_le32(len);
53855388
info->Reserved = 0;
5386-
sz = sizeof(struct filesystem_vol_info) - 2 + len;
5389+
sz = sizeof(struct filesystem_vol_info) + len;
53875390
rsp->OutputBufferLength = cpu_to_le32(sz);
53885391
break;
53895392
}

fs/smb/server/smb_common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ struct filesystem_attribute_info {
213213
__le32 Attributes;
214214
__le32 MaxPathNameComponentLength;
215215
__le32 FileSystemNameLen;
216-
__le16 FileSystemName[1]; /* do not have to save this - get subset? */
216+
__le16 FileSystemName[]; /* do not have to save this - get subset? */
217217
} __packed;
218218

219219
struct filesystem_device_info {
@@ -226,7 +226,7 @@ struct filesystem_vol_info {
226226
__le32 SerialNumber;
227227
__le32 VolumeLabelSize;
228228
__le16 Reserved;
229-
__le16 VolumeLabel[1];
229+
__le16 VolumeLabel[];
230230
} __packed;
231231

232232
struct filesystem_info {

0 commit comments

Comments
 (0)