Skip to content

Commit

Permalink
ksmbd: add missing compound request handing in some commands
Browse files Browse the repository at this point in the history
This patch add the compound request handling to the some commands.
Existing clients do not send these commands as compound requests,
but ksmbd should consider that they may come.

Cc: stable@vger.kernel.org
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
  • Loading branch information
namjaejeon authored and Steve French committed Jun 26, 2023
1 parent 98422bd commit 7b7d709
Showing 1 changed file with 53 additions and 25 deletions.
78 changes: 53 additions & 25 deletions fs/smb/server/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1914,14 +1914,16 @@ int smb2_sess_setup(struct ksmbd_work *work)
int smb2_tree_connect(struct ksmbd_work *work)
{
struct ksmbd_conn *conn = work->conn;
struct smb2_tree_connect_req *req = smb2_get_msg(work->request_buf);
struct smb2_tree_connect_rsp *rsp = smb2_get_msg(work->response_buf);
struct smb2_tree_connect_req *req;
struct smb2_tree_connect_rsp *rsp;
struct ksmbd_session *sess = work->sess;
char *treename = NULL, *name = NULL;
struct ksmbd_tree_conn_status status;
struct ksmbd_share_config *share;
int rc = -EINVAL;

WORK_BUFFERS(work, req, rsp);

treename = smb_strndup_from_utf16(req->Buffer,
le16_to_cpu(req->PathLength), true,
conn->local_nls);
Expand Down Expand Up @@ -2090,19 +2092,19 @@ static int smb2_create_open_flags(bool file_present, __le32 access,
*/
int smb2_tree_disconnect(struct ksmbd_work *work)
{
struct smb2_tree_disconnect_rsp *rsp = smb2_get_msg(work->response_buf);
struct smb2_tree_disconnect_rsp *rsp;
struct smb2_tree_disconnect_req *req;
struct ksmbd_session *sess = work->sess;
struct ksmbd_tree_connect *tcon = work->tcon;

WORK_BUFFERS(work, req, rsp);

rsp->StructureSize = cpu_to_le16(4);
inc_rfc1001_len(work->response_buf, 4);

ksmbd_debug(SMB, "request\n");

if (!tcon || test_and_set_bit(TREE_CONN_EXPIRE, &tcon->status)) {
struct smb2_tree_disconnect_req *req =
smb2_get_msg(work->request_buf);

ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId);

rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
Expand All @@ -2125,10 +2127,14 @@ int smb2_tree_disconnect(struct ksmbd_work *work)
int smb2_session_logoff(struct ksmbd_work *work)
{
struct ksmbd_conn *conn = work->conn;
struct smb2_logoff_rsp *rsp = smb2_get_msg(work->response_buf);
struct smb2_logoff_req *req;
struct smb2_logoff_rsp *rsp;
struct ksmbd_session *sess;
struct smb2_logoff_req *req = smb2_get_msg(work->request_buf);
u64 sess_id = le64_to_cpu(req->hdr.SessionId);
u64 sess_id;

WORK_BUFFERS(work, req, rsp);

sess_id = le64_to_cpu(req->hdr.SessionId);

rsp->StructureSize = cpu_to_le16(4);
inc_rfc1001_len(work->response_buf, 4);
Expand Down Expand Up @@ -2168,12 +2174,14 @@ int smb2_session_logoff(struct ksmbd_work *work)
*/
static noinline int create_smb2_pipe(struct ksmbd_work *work)
{
struct smb2_create_rsp *rsp = smb2_get_msg(work->response_buf);
struct smb2_create_req *req = smb2_get_msg(work->request_buf);
struct smb2_create_rsp *rsp;
struct smb2_create_req *req;
int id;
int err;
char *name;

WORK_BUFFERS(work, req, rsp);

name = smb_strndup_from_utf16(req->Buffer, le16_to_cpu(req->NameLength),
1, work->conn->local_nls);
if (IS_ERR(name)) {
Expand Down Expand Up @@ -5306,8 +5314,10 @@ int smb2_query_info(struct ksmbd_work *work)
static noinline int smb2_close_pipe(struct ksmbd_work *work)
{
u64 id;
struct smb2_close_req *req = smb2_get_msg(work->request_buf);
struct smb2_close_rsp *rsp = smb2_get_msg(work->response_buf);
struct smb2_close_req *req;
struct smb2_close_rsp *rsp;

WORK_BUFFERS(work, req, rsp);

id = req->VolatileFileId;
ksmbd_session_rpc_close(work->sess, id);
Expand Down Expand Up @@ -5449,6 +5459,9 @@ int smb2_echo(struct ksmbd_work *work)
{
struct smb2_echo_rsp *rsp = smb2_get_msg(work->response_buf);

if (work->next_smb2_rcv_hdr_off)
rsp = ksmbd_resp_buf_next(work);

rsp->StructureSize = cpu_to_le16(4);
rsp->Reserved = 0;
inc_rfc1001_len(work->response_buf, 4);
Expand Down Expand Up @@ -6083,8 +6096,10 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work)
int nbytes = 0, err;
u64 id;
struct ksmbd_rpc_command *rpc_resp;
struct smb2_read_req *req = smb2_get_msg(work->request_buf);
struct smb2_read_rsp *rsp = smb2_get_msg(work->response_buf);
struct smb2_read_req *req;
struct smb2_read_rsp *rsp;

WORK_BUFFERS(work, req, rsp);

id = req->VolatileFileId;

Expand Down Expand Up @@ -6332,14 +6347,16 @@ int smb2_read(struct ksmbd_work *work)
*/
static noinline int smb2_write_pipe(struct ksmbd_work *work)
{
struct smb2_write_req *req = smb2_get_msg(work->request_buf);
struct smb2_write_rsp *rsp = smb2_get_msg(work->response_buf);
struct smb2_write_req *req;
struct smb2_write_rsp *rsp;
struct ksmbd_rpc_command *rpc_resp;
u64 id = 0;
int err = 0, ret = 0;
char *data_buf;
size_t length;

WORK_BUFFERS(work, req, rsp);

length = le32_to_cpu(req->Length);
id = req->VolatileFileId;

Expand Down Expand Up @@ -6608,6 +6625,9 @@ int smb2_cancel(struct ksmbd_work *work)
struct ksmbd_work *iter;
struct list_head *command_list;

if (work->next_smb2_rcv_hdr_off)
hdr = ksmbd_resp_buf_next(work);

ksmbd_debug(SMB, "smb2 cancel called on mid %llu, async flags 0x%x\n",
hdr->MessageId, hdr->Flags);

Expand Down Expand Up @@ -6767,8 +6787,8 @@ static inline bool lock_defer_pending(struct file_lock *fl)
*/
int smb2_lock(struct ksmbd_work *work)
{
struct smb2_lock_req *req = smb2_get_msg(work->request_buf);
struct smb2_lock_rsp *rsp = smb2_get_msg(work->response_buf);
struct smb2_lock_req *req;
struct smb2_lock_rsp *rsp;
struct smb2_lock_element *lock_ele;
struct ksmbd_file *fp = NULL;
struct file_lock *flock = NULL;
Expand All @@ -6785,6 +6805,8 @@ int smb2_lock(struct ksmbd_work *work)
LIST_HEAD(rollback_list);
int prior_lock = 0;

WORK_BUFFERS(work, req, rsp);

ksmbd_debug(SMB, "Received lock request\n");
fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
if (!fp) {
Expand Down Expand Up @@ -7898,8 +7920,8 @@ int smb2_ioctl(struct ksmbd_work *work)
*/
static void smb20_oplock_break_ack(struct ksmbd_work *work)
{
struct smb2_oplock_break *req = smb2_get_msg(work->request_buf);
struct smb2_oplock_break *rsp = smb2_get_msg(work->response_buf);
struct smb2_oplock_break *req;
struct smb2_oplock_break *rsp;
struct ksmbd_file *fp;
struct oplock_info *opinfo = NULL;
__le32 err = 0;
Expand All @@ -7908,6 +7930,8 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
char req_oplevel = 0, rsp_oplevel = 0;
unsigned int oplock_change_type;

WORK_BUFFERS(work, req, rsp);

volatile_id = req->VolatileFid;
persistent_id = req->PersistentFid;
req_oplevel = req->OplockLevel;
Expand Down Expand Up @@ -8042,15 +8066,17 @@ static int check_lease_state(struct lease *lease, __le32 req_state)
static void smb21_lease_break_ack(struct ksmbd_work *work)
{
struct ksmbd_conn *conn = work->conn;
struct smb2_lease_ack *req = smb2_get_msg(work->request_buf);
struct smb2_lease_ack *rsp = smb2_get_msg(work->response_buf);
struct smb2_lease_ack *req;
struct smb2_lease_ack *rsp;
struct oplock_info *opinfo;
__le32 err = 0;
int ret = 0;
unsigned int lease_change_type;
__le32 lease_state;
struct lease *lease;

WORK_BUFFERS(work, req, rsp);

ksmbd_debug(OPLOCK, "smb21 lease break, lease state(0x%x)\n",
le32_to_cpu(req->LeaseState));
opinfo = lookup_lease_in_table(conn, req->LeaseKey);
Expand Down Expand Up @@ -8176,8 +8202,10 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
*/
int smb2_oplock_break(struct ksmbd_work *work)
{
struct smb2_oplock_break *req = smb2_get_msg(work->request_buf);
struct smb2_oplock_break *rsp = smb2_get_msg(work->response_buf);
struct smb2_oplock_break *req;
struct smb2_oplock_break *rsp;

WORK_BUFFERS(work, req, rsp);

switch (le16_to_cpu(req->StructureSize)) {
case OP_BREAK_STRUCT_SIZE_20:
Expand Down

0 comments on commit 7b7d709

Please sign in to comment.