Merge branch 'dhowells' (patches from DavidH)

Merge misc fixes from David Howells.

Two afs fixes and a key refcounting fix.

* dhowells:
  afs: Fix afs_lookup() to not clobber the version on a new dentry
  afs: Fix use-after-loss-of-ref
  keys: Fix request_key() cache
This commit is contained in:
Linus Torvalds 2020-01-14 09:56:31 -08:00
commit e033e7d4a8
3 changed files with 13 additions and 21 deletions

View File

@ -908,6 +908,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags) unsigned int flags)
{ {
struct afs_vnode *dvnode = AFS_FS_I(dir); struct afs_vnode *dvnode = AFS_FS_I(dir);
struct afs_fid fid = {};
struct inode *inode; struct inode *inode;
struct dentry *d; struct dentry *d;
struct key *key; struct key *key;
@ -951,21 +952,18 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
afs_stat_v(dvnode, n_lookup); afs_stat_v(dvnode, n_lookup);
inode = afs_do_lookup(dir, dentry, key); inode = afs_do_lookup(dir, dentry, key);
key_put(key); key_put(key);
if (inode == ERR_PTR(-ENOENT)) { if (inode == ERR_PTR(-ENOENT))
inode = afs_try_auto_mntpt(dentry, dir); inode = afs_try_auto_mntpt(dentry, dir);
} else {
dentry->d_fsdata = if (!IS_ERR_OR_NULL(inode))
(void *)(unsigned long)dvnode->status.data_version; fid = AFS_FS_I(inode)->fid;
}
d = d_splice_alias(inode, dentry); d = d_splice_alias(inode, dentry);
if (!IS_ERR_OR_NULL(d)) { if (!IS_ERR_OR_NULL(d)) {
d->d_fsdata = dentry->d_fsdata; d->d_fsdata = dentry->d_fsdata;
trace_afs_lookup(dvnode, &d->d_name, trace_afs_lookup(dvnode, &d->d_name, &fid);
inode ? AFS_FS_I(inode) : NULL);
} else { } else {
trace_afs_lookup(dvnode, &dentry->d_name, trace_afs_lookup(dvnode, &dentry->d_name, &fid);
IS_ERR_OR_NULL(inode) ? NULL
: AFS_FS_I(inode));
} }
return d; return d;
} }

View File

@ -915,9 +915,9 @@ TRACE_EVENT(afs_call_state,
TRACE_EVENT(afs_lookup, TRACE_EVENT(afs_lookup,
TP_PROTO(struct afs_vnode *dvnode, const struct qstr *name, TP_PROTO(struct afs_vnode *dvnode, const struct qstr *name,
struct afs_vnode *vnode), struct afs_fid *fid),
TP_ARGS(dvnode, name, vnode), TP_ARGS(dvnode, name, fid),
TP_STRUCT__entry( TP_STRUCT__entry(
__field_struct(struct afs_fid, dfid ) __field_struct(struct afs_fid, dfid )
@ -928,13 +928,7 @@ TRACE_EVENT(afs_lookup,
TP_fast_assign( TP_fast_assign(
int __len = min_t(int, name->len, 23); int __len = min_t(int, name->len, 23);
__entry->dfid = dvnode->fid; __entry->dfid = dvnode->fid;
if (vnode) { __entry->fid = *fid;
__entry->fid = vnode->fid;
} else {
__entry->fid.vid = 0;
__entry->fid.vnode = 0;
__entry->fid.unique = 0;
}
memcpy(__entry->name, name->name, __len); memcpy(__entry->name, name->name, __len);
__entry->name[__len] = 0; __entry->name[__len] = 0;
), ),

View File

@ -175,8 +175,8 @@ void exit_creds(struct task_struct *tsk)
put_cred(cred); put_cred(cred);
#ifdef CONFIG_KEYS_REQUEST_CACHE #ifdef CONFIG_KEYS_REQUEST_CACHE
key_put(current->cached_requested_key); key_put(tsk->cached_requested_key);
current->cached_requested_key = NULL; tsk->cached_requested_key = NULL;
#endif #endif
} }