mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 06:31:52 +00:00
Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs fix from Miklos Szeredi: "This fixes a regression introduced in this cycle" * 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: fix possible use after free on redirect dir lookup
This commit is contained in:
commit
56ef18829e
@ -154,29 +154,38 @@ out_err:
|
||||
static int ovl_lookup_layer(struct dentry *base, struct ovl_lookup_data *d,
|
||||
struct dentry **ret)
|
||||
{
|
||||
const char *s = d->name.name;
|
||||
/* Counting down from the end, since the prefix can change */
|
||||
size_t rem = d->name.len - 1;
|
||||
struct dentry *dentry = NULL;
|
||||
int err;
|
||||
|
||||
if (*s != '/')
|
||||
if (d->name.name[0] != '/')
|
||||
return ovl_lookup_single(base, d, d->name.name, d->name.len,
|
||||
0, "", ret);
|
||||
|
||||
while (*s++ == '/' && !IS_ERR_OR_NULL(base) && d_can_lookup(base)) {
|
||||
while (!IS_ERR_OR_NULL(base) && d_can_lookup(base)) {
|
||||
const char *s = d->name.name + d->name.len - rem;
|
||||
const char *next = strchrnul(s, '/');
|
||||
size_t slen = strlen(s);
|
||||
size_t thislen = next - s;
|
||||
bool end = !next[0];
|
||||
|
||||
if (WARN_ON(slen > d->name.len) ||
|
||||
WARN_ON(strcmp(d->name.name + d->name.len - slen, s)))
|
||||
/* Verify we did not go off the rails */
|
||||
if (WARN_ON(s[-1] != '/'))
|
||||
return -EIO;
|
||||
|
||||
err = ovl_lookup_single(base, d, s, next - s,
|
||||
d->name.len - slen, next, &base);
|
||||
err = ovl_lookup_single(base, d, s, thislen,
|
||||
d->name.len - rem, next, &base);
|
||||
dput(dentry);
|
||||
if (err)
|
||||
return err;
|
||||
dentry = base;
|
||||
s = next;
|
||||
if (end)
|
||||
break;
|
||||
|
||||
rem -= thislen + 1;
|
||||
|
||||
if (WARN_ON(rem >= d->name.len))
|
||||
return -EIO;
|
||||
}
|
||||
*ret = dentry;
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user