Skip to content

Commit 8565bdf

Browse files
committed
Merge tag '6.6-rc2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull smb client fixes from Steve French: "Six smb3 client fixes, including three for stable, from the SMB plugfest (testing event) this week: - Reparse point handling fix (found when investigating dir enumeration when fifo in dir) - Fix excessive thread creation for dir lease cleanup - UAF fix in negotiate path - remove duplicate error message mapping and fix confusing warning message - add dynamic trace point to improve debugging RDMA connection attempts" * tag '6.6-rc2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: smb3: fix confusing debug message smb: client: handle STATUS_IO_REPARSE_TAG_NOT_HANDLED smb3: remove duplicate error mapping cifs: Fix UAF in cifs_demultiplex_thread() smb3: do not start laundromat thread when dir leases disabled smb3: Add dynamic trace points for RDMA (smbdirect) reconnect
2 parents 5a4de7d + c8ebf07 commit 8565bdf

File tree

11 files changed

+60
-27
lines changed

11 files changed

+60
-27
lines changed

fs/smb/client/cached_dir.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,9 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
452452
struct cached_fid *cfid, *q;
453453
LIST_HEAD(entry);
454454

455+
if (cfids == NULL)
456+
return;
457+
455458
spin_lock(&cfids->cfid_list_lock);
456459
list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
457460
list_move(&cfid->entry, &entry);
@@ -651,6 +654,9 @@ void free_cached_dirs(struct cached_fids *cfids)
651654
struct cached_fid *cfid, *q;
652655
LIST_HEAD(entry);
653656

657+
if (cfids == NULL)
658+
return;
659+
654660
if (cfids->laundromat) {
655661
kthread_stop(cfids->laundromat);
656662
cfids->laundromat = NULL;

fs/smb/client/cifsglob.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1807,6 +1807,7 @@ static inline bool is_retryable_error(int error)
18071807
#define MID_RETRY_NEEDED 8 /* session closed while this request out */
18081808
#define MID_RESPONSE_MALFORMED 0x10
18091809
#define MID_SHUTDOWN 0x20
1810+
#define MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */
18101811

18111812
/* Flags */
18121813
#define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */
@@ -1943,7 +1944,7 @@ require use of the stronger protocol */
19431944
* cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once
19441945
* ->can_cache_brlcks
19451946
* cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc
1946-
* cached_fid->fid_mutex cifs_tcon->crfid tconInfoAlloc
1947+
* cached_fid->fid_mutex cifs_tcon->crfid tcon_info_alloc
19471948
* cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo
19481949
* cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo
19491950
* ->invalidHandle initiate_cifs_search

fs/smb/client/cifsproto.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ extern int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses);
512512

513513
extern struct cifs_ses *sesInfoAlloc(void);
514514
extern void sesInfoFree(struct cifs_ses *);
515-
extern struct cifs_tcon *tconInfoAlloc(void);
515+
extern struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled);
516516
extern void tconInfoFree(struct cifs_tcon *);
517517

518518
extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,

fs/smb/client/connect.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,7 +1882,8 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
18821882
}
18831883
}
18841884

1885-
tcon = tconInfoAlloc();
1885+
/* no need to setup directory caching on IPC share, so pass in false */
1886+
tcon = tcon_info_alloc(false);
18861887
if (tcon == NULL)
18871888
return -ENOMEM;
18881889

@@ -2492,7 +2493,10 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
24922493
goto out_fail;
24932494
}
24942495

2495-
tcon = tconInfoAlloc();
2496+
if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING)
2497+
tcon = tcon_info_alloc(true);
2498+
else
2499+
tcon = tcon_info_alloc(false);
24962500
if (tcon == NULL) {
24972501
rc = -ENOMEM;
24982502
goto out_fail;

fs/smb/client/misc.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,18 +113,22 @@ sesInfoFree(struct cifs_ses *buf_to_free)
113113
}
114114

115115
struct cifs_tcon *
116-
tconInfoAlloc(void)
116+
tcon_info_alloc(bool dir_leases_enabled)
117117
{
118118
struct cifs_tcon *ret_buf;
119119

120120
ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL);
121121
if (!ret_buf)
122122
return NULL;
123-
ret_buf->cfids = init_cached_dirs();
124-
if (!ret_buf->cfids) {
125-
kfree(ret_buf);
126-
return NULL;
123+
124+
if (dir_leases_enabled == true) {
125+
ret_buf->cfids = init_cached_dirs();
126+
if (!ret_buf->cfids) {
127+
kfree(ret_buf);
128+
return NULL;
129+
}
127130
}
131+
/* else ret_buf->cfids is already set to NULL above */
128132

129133
atomic_inc(&tconInfoAllocCount);
130134
ret_buf->status = TID_NEW;

fs/smb/client/smb2inode.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,9 @@ static int parse_create_response(struct cifs_open_info_data *data,
539539
int rc = 0;
540540

541541
switch (rsp->hdr.Status) {
542+
case STATUS_IO_REPARSE_TAG_NOT_HANDLED:
543+
reparse_point = true;
544+
break;
542545
case STATUS_STOPPED_ON_SYMLINK:
543546
rc = smb2_parse_symlink_response(cifs_sb, iov,
544547
&data->symlink_target);

fs/smb/client/smb2maperror.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,8 +877,6 @@ static const struct status_to_posix_error smb2_error_map_table[] = {
877877
"STATUS_IO_REPARSE_TAG_MISMATCH"},
878878
{STATUS_IO_REPARSE_DATA_INVALID, -EIO,
879879
"STATUS_IO_REPARSE_DATA_INVALID"},
880-
{STATUS_IO_REPARSE_TAG_NOT_HANDLED, -EIO,
881-
"STATUS_IO_REPARSE_TAG_NOT_HANDLED"},
882880
{STATUS_REPARSE_POINT_NOT_RESOLVED, -EIO,
883881
"STATUS_REPARSE_POINT_NOT_RESOLVED"},
884882
{STATUS_DIRECTORY_IS_A_REPARSE_POINT, -EIO,

fs/smb/client/smb2pdu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode)
848848

849849
iov[num].iov_base = create_posix_buf(mode);
850850
if (mode == ACL_NO_MODE)
851-
cifs_dbg(FYI, "Invalid mode\n");
851+
cifs_dbg(FYI, "%s: no mode\n", __func__);
852852
if (iov[num].iov_base == NULL)
853853
return -ENOMEM;
854854
iov[num].iov_len = sizeof(struct create_posix);
@@ -3878,7 +3878,7 @@ void smb2_reconnect_server(struct work_struct *work)
38783878
goto done;
38793879

38803880
/* allocate a dummy tcon struct used for reconnect */
3881-
tcon = tconInfoAlloc();
3881+
tcon = tcon_info_alloc(false);
38823882
if (!tcon) {
38833883
resched = true;
38843884
list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) {

fs/smb/client/smbdirect.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,10 +1401,13 @@ int smbd_reconnect(struct TCP_Server_Info *server)
14011401
server->smbd_conn = smbd_get_connection(
14021402
server, (struct sockaddr *) &server->dstaddr);
14031403

1404-
if (server->smbd_conn)
1404+
if (server->smbd_conn) {
14051405
cifs_dbg(VFS, "RDMA transport re-established\n");
1406-
1407-
return server->smbd_conn ? 0 : -ENOENT;
1406+
trace_smb3_smbd_connect_done(server->hostname, server->conn_id, &server->dstaddr);
1407+
return 0;
1408+
}
1409+
trace_smb3_smbd_connect_err(server->hostname, server->conn_id, &server->dstaddr);
1410+
return -ENOENT;
14081411
}
14091412

14101413
static void destroy_caches_and_workqueue(struct smbd_connection *info)

fs/smb/client/trace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,8 @@ DEFINE_EVENT(smb3_connect_class, smb3_##name, \
935935
TP_ARGS(hostname, conn_id, addr))
936936

937937
DEFINE_SMB3_CONNECT_EVENT(connect_done);
938+
DEFINE_SMB3_CONNECT_EVENT(smbd_connect_done);
939+
DEFINE_SMB3_CONNECT_EVENT(smbd_connect_err);
938940

939941
DECLARE_EVENT_CLASS(smb3_connect_err_class,
940942
TP_PROTO(char *hostname, __u64 conn_id,

0 commit comments

Comments
 (0)