[trusty,1/1] UBUNTU: SAUCE: ensure that upper/lower layers are valid before checking permissions
diff mbox

Message ID 1434565069-30669-3-git-send-email-apw@canonical.com
State New
Headers show

Commit Message

Andy Whitcroft June 17, 2015, 6:17 p.m. UTC
When removing a directory which was only on the lower layer and was empty
on that lower layer we will attempt to confirm we are permitted to write
to the upper layer when we have no upper layer.  Leading to a panic.

  [10531.508838] BUG: unable to handle kernel NULL pointer dereference at 0000000000000030
  [10531.508889] IP: [<ffffffffa08bed80>] ovl_dentry_root_may+0x30/0x60 [overlayfs]

BugLink: http://bugs.launchpad.net/bugs/1465998
Signed-off-by: Andy Whitcroft <apw@canonical.com>
---
 fs/overlayfs/readdir.c | 34 ++++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 14 deletions(-)

Patch
diff mbox

diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index 82269ff..f9896b2 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -324,13 +324,16 @@  static int ovl_iterate(struct file *file, struct dir_context *ctx)
 		ovl_path_lower(file->f_path.dentry, &lowerpath);
 		ovl_path_upper(file->f_path.dentry, &upperpath);
 
-		res = ovl_dentry_root_may(file->f_path.dentry, &upperpath, MAY_READ);
-		if (res)
-			return res;
-		res = ovl_dentry_root_may(file->f_path.dentry, &lowerpath, MAY_READ);
-		if (res)
-			return res;
-
+		if (upperpath.dentry) {
+			res = ovl_dentry_root_may(file->f_path.dentry, &upperpath, MAY_READ);
+			if (res)
+				return res;
+		}
+		if (lowerpath.dentry) {
+			res = ovl_dentry_root_may(file->f_path.dentry, &lowerpath, MAY_READ);
+			if (res)
+				return res;
+		}
 		res = ovl_dir_read_merged(&upperpath, &lowerpath, &od->cache);
 		if (res) {
 			ovl_cache_free(&od->cache);
@@ -475,13 +478,16 @@  static int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list)
 	ovl_path_upper(dentry, &upperpath);
 	ovl_path_lower(dentry, &lowerpath);
 
-	err = ovl_dentry_root_may(dentry, &upperpath, MAY_READ);
-	if (err)
-		return err;
-	err = ovl_dentry_root_may(dentry, &lowerpath, MAY_READ);
-	if (err)
-		return err;
-
+	if (upperpath.dentry) {
+		err = ovl_dentry_root_may(dentry, &upperpath, MAY_READ);
+		if (err)
+			return err;
+	}
+	if (lowerpath.dentry) {
+		err = ovl_dentry_root_may(dentry, &lowerpath, MAY_READ);
+		if (err)
+			return err;
+	}
 	err = ovl_dir_read_merged(&upperpath, &lowerpath, list);
 	if (err)
 		return err;