ovl: Check redirect on index as well
[linux-2.6-microblaze.git] / fs / overlayfs / util.c
index 1aa9e0c..8cfb62c 100644 (file)
@@ -865,3 +865,53 @@ bool ovl_is_metacopy_dentry(struct dentry *dentry)
 
        return (oe->numlower > 1);
 }
+
+char *ovl_get_redirect_xattr(struct dentry *dentry, int padding)
+{
+       int res;
+       char *s, *next, *buf = NULL;
+
+       res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, NULL, 0);
+       if (res < 0) {
+               if (res == -ENODATA || res == -EOPNOTSUPP)
+                       return NULL;
+               goto fail;
+       }
+
+       buf = kzalloc(res + padding + 1, GFP_KERNEL);
+       if (!buf)
+               return ERR_PTR(-ENOMEM);
+
+       if (res == 0)
+               goto invalid;
+
+       res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, buf, res);
+       if (res < 0)
+               goto fail;
+       if (res == 0)
+               goto invalid;
+
+       if (buf[0] == '/') {
+               for (s = buf; *s++ == '/'; s = next) {
+                       next = strchrnul(s, '/');
+                       if (s == next)
+                               goto invalid;
+               }
+       } else {
+               if (strchr(buf, '/') != NULL)
+                       goto invalid;
+       }
+
+       return buf;
+
+err_free:
+       kfree(buf);
+       return ERR_PTR(res);
+fail:
+       pr_warn_ratelimited("overlayfs: failed to get redirect (%i)\n", res);
+       goto err_free;
+invalid:
+       pr_warn_ratelimited("overlayfs: invalid redirect (%s)\n", buf);
+       res = -EINVAL;
+       goto err_free;
+}