Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56ef1882 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents eefa9feb 4c7d0c9c
Loading
Loading
Loading
Loading
+18 −9
Original line number Diff line number Diff line
@@ -154,29 +154,38 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
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;