Skip to content

Commit 39a154f

Browse files
Paulo Alcantarasmfrench
authored andcommitted
cifs: protect access of TCP_Server_Info::{dstaddr,hostname}
Use the appropriate locks to protect access of hostname and dstaddr fields in cifs_tree_connect() as they might get changed by other tasks. Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Reviewed-by: Enzo Matsumiya <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 775e44d commit 39a154f

File tree

2 files changed

+13
-11
lines changed

2 files changed

+13
-11
lines changed

fs/cifs/dfs.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ static int update_server_fullpath(struct TCP_Server_Info *server, struct cifs_sb
327327
return rc;
328328
}
329329

330-
static int target_share_matches_server(struct TCP_Server_Info *server, const char *tcp_host,
331-
size_t tcp_host_len, char *share, bool *target_match)
330+
static int target_share_matches_server(struct TCP_Server_Info *server, char *share,
331+
bool *target_match)
332332
{
333333
int rc = 0;
334334
const char *dfs_host;
@@ -338,13 +338,16 @@ static int target_share_matches_server(struct TCP_Server_Info *server, const cha
338338
extract_unc_hostname(share, &dfs_host, &dfs_host_len);
339339

340340
/* Check if hostnames or addresses match */
341-
if (dfs_host_len != tcp_host_len || strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
342-
cifs_dbg(FYI, "%s: %.*s doesn't match %.*s\n", __func__, (int)dfs_host_len,
343-
dfs_host, (int)tcp_host_len, tcp_host);
341+
cifs_server_lock(server);
342+
if (dfs_host_len != strlen(server->hostname) ||
343+
strncasecmp(dfs_host, server->hostname, dfs_host_len)) {
344+
cifs_dbg(FYI, "%s: %.*s doesn't match %s\n", __func__,
345+
(int)dfs_host_len, dfs_host, server->hostname);
344346
rc = match_target_ip(server, dfs_host, dfs_host_len, target_match);
345347
if (rc)
346348
cifs_dbg(VFS, "%s: failed to match target ip: %d\n", __func__, rc);
347349
}
350+
cifs_server_unlock(server);
348351
return rc;
349352
}
350353

@@ -358,13 +361,9 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t
358361
struct cifs_ses *root_ses = CIFS_DFS_ROOT_SES(tcon->ses);
359362
struct cifs_tcon *ipc = root_ses->tcon_ipc;
360363
char *share = NULL, *prefix = NULL;
361-
const char *tcp_host;
362-
size_t tcp_host_len;
363364
struct dfs_cache_tgt_iterator *tit;
364365
bool target_match;
365366

366-
extract_unc_hostname(server->hostname, &tcp_host, &tcp_host_len);
367-
368367
tit = dfs_cache_get_tgt_iterator(tl);
369368
if (!tit) {
370369
rc = -ENOENT;
@@ -387,8 +386,7 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t
387386
break;
388387
}
389388

390-
rc = target_share_matches_server(server, tcp_host, tcp_host_len, share,
391-
&target_match);
389+
rc = target_share_matches_server(server, share, &target_match);
392390
if (rc)
393391
break;
394392
if (!target_match) {
@@ -497,7 +495,9 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
497495
}
498496

499497
if (tcon->ipc) {
498+
cifs_server_lock(server);
500499
scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname);
500+
cifs_server_unlock(server);
501501
rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc);
502502
goto out;
503503
}

fs/cifs/misc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,7 +1277,9 @@ int match_target_ip(struct TCP_Server_Info *server,
12771277
if (rc < 0)
12781278
return rc;
12791279

1280+
spin_lock(&server->srv_lock);
12801281
*result = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, (struct sockaddr *)&ss);
1282+
spin_unlock(&server->srv_lock);
12811283
cifs_dbg(FYI, "%s: ip addresses match: %u\n", __func__, *result);
12821284
return 0;
12831285
}

0 commit comments

Comments
 (0)