mirror of
https://github.com/torvalds/linux.git
synced 2026-09-11 20:13:02 +02:00
smb: client: fill cache fields after populating cache in copy_ref_data()
In copy_ref_data(), struct cache_entry *ce has its fields populated at the beginning of the function. Later, if alloc_target fails with an ERR_PTR, free_tgts() is called on the cache, leaving the cache metadata populated without any targets. Critically, this extends ce->etime, making the cache appear valid for longer without any targets. Also, free_tgts() does not set ce->numtgts to zero. On error, when the cache is freed, ce->numtgts is not zeroed, and other cache users may attempt to access nonexistent entries. Update fields after copying targets to prevent partial-state updates. Set ce->numtgts to zero at the end of free_tgts(). Signed-off-by: Fredric Cover <fredric.cover.lkernel@gmail.com> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
This commit is contained in:
parent
d806d5a85d
commit
42d3358bf1
|
|
@ -123,6 +123,7 @@ static inline void free_tgts(struct cache_entry *ce)
|
|||
kfree(t);
|
||||
}
|
||||
|
||||
ce->numtgts = 0;
|
||||
WRITE_ONCE(ce->tgthint, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -388,13 +389,6 @@ static int copy_ref_data(const struct dfs_info3_param *refs, int numrefs,
|
|||
struct cache_dfs_tgt *target;
|
||||
int i;
|
||||
|
||||
ce->ttl = max_t(int, refs[0].ttl, CACHE_MIN_TTL);
|
||||
ce->etime = get_expire_time(ce->ttl);
|
||||
ce->srvtype = refs[0].server_type;
|
||||
ce->hdr_flags = refs[0].flags;
|
||||
ce->ref_flags = refs[0].ref_flag;
|
||||
ce->path_consumed = refs[0].path_consumed;
|
||||
|
||||
for (i = 0; i < numrefs; i++) {
|
||||
struct cache_dfs_tgt *t;
|
||||
|
||||
|
|
@ -409,12 +403,19 @@ static int copy_ref_data(const struct dfs_info3_param *refs, int numrefs,
|
|||
} else {
|
||||
list_add_tail(&t->list, &ce->tlist);
|
||||
}
|
||||
ce->numtgts++;
|
||||
}
|
||||
|
||||
target = list_first_entry_or_null(&ce->tlist, struct cache_dfs_tgt,
|
||||
list);
|
||||
|
||||
WRITE_ONCE(ce->tgthint, target);
|
||||
ce->ttl = max_t(int, refs[0].ttl, CACHE_MIN_TTL);
|
||||
ce->etime = get_expire_time(ce->ttl);
|
||||
ce->srvtype = refs[0].server_type;
|
||||
ce->hdr_flags = refs[0].flags;
|
||||
ce->ref_flags = refs[0].ref_flag;
|
||||
ce->path_consumed = refs[0].path_consumed;
|
||||
ce->numtgts = numrefs;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -634,7 +635,6 @@ static int update_cache_entry_locked(struct cache_entry *ce, const struct dfs_in
|
|||
}
|
||||
|
||||
free_tgts(ce);
|
||||
ce->numtgts = 0;
|
||||
|
||||
rc = copy_ref_data(refs, numrefs, ce, th);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user