From 33006cdf9c038dca9b3d4c148a509de851a66ea9 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 29 Mar 2017 14:02:19 -0700 Subject: ovl: Use designated initializers Prepare to mark sensitive kernel structures for randomization by making sure they're using designated initializers. These were identified during allyesconfig builds of x86, arm, and arm64, with most initializer fixes extracted from grsecurity. For these cases, use { }, which will be zero-filled, instead of undesignated NULLs. Signed-off-by: Kees Cook Signed-off-by: Miklos Szeredi --- fs/overlayfs/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/overlayfs/util.c') diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 1953986ee6bc..35b8959db5ee 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -101,7 +101,7 @@ void ovl_path_lower(struct dentry *dentry, struct path *path) { struct ovl_entry *oe = dentry->d_fsdata; - *path = oe->numlower ? oe->lowerstack[0] : (struct path) { NULL, NULL }; + *path = oe->numlower ? oe->lowerstack[0] : (struct path) { }; } enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path) -- cgit v1.2.3 From 7bcd74b98d7bac3e5149894caaf72de6989af7f0 Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Wed, 22 Mar 2017 08:42:21 -0400 Subject: ovl: check if all layers are on the same fs Some features can only work when all layers are on the same fs. Test this condition during mount time, so features can check them later. Add helper ovl_same_sb() to return the common super block in case all layers are on the same fs. Signed-off-by: Amir Goldstein Signed-off-by: Miklos Szeredi --- fs/overlayfs/overlayfs.h | 1 + fs/overlayfs/ovl_entry.h | 2 ++ fs/overlayfs/super.c | 8 ++++++++ fs/overlayfs/util.c | 7 +++++++ 4 files changed, 18 insertions(+) (limited to 'fs/overlayfs/util.c') diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 741dc0b6931f..c851158324e2 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -151,6 +151,7 @@ int ovl_want_write(struct dentry *dentry); void ovl_drop_write(struct dentry *dentry); struct dentry *ovl_workdir(struct dentry *dentry); const struct cred *ovl_override_creds(struct super_block *sb); +struct super_block *ovl_same_sb(struct super_block *sb); struct ovl_entry *ovl_alloc_entry(unsigned int numlower); bool ovl_dentry_remote(struct dentry *dentry); bool ovl_dentry_weird(struct dentry *dentry); diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index 59614faa14c3..b2023ddb8532 100644 --- a/fs/overlayfs/ovl_entry.h +++ b/fs/overlayfs/ovl_entry.h @@ -29,6 +29,8 @@ struct ovl_fs { const struct cred *creator_cred; bool tmpfile; wait_queue_head_t copyup_wq; + /* sb common to all layers */ + struct super_block *same_sb; }; /* private information held for every overlayfs dentry */ diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 6faefa54cb5e..9828b7de8999 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -914,11 +914,19 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) ufs->lower_mnt[ufs->numlower] = mnt; ufs->numlower++; + + /* Check if all lower layers are on same sb */ + if (i == 0) + ufs->same_sb = mnt->mnt_sb; + else if (ufs->same_sb != mnt->mnt_sb) + ufs->same_sb = NULL; } /* If the upper fs is nonexistent, we mark overlayfs r/o too */ if (!ufs->upper_mnt) sb->s_flags |= MS_RDONLY; + else if (ufs->upper_mnt->mnt_sb != ufs->same_sb) + ufs->same_sb = NULL; if (remote) sb->s_d_op = &ovl_reval_dentry_operations; diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 35b8959db5ee..2bd4c264ccbe 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -41,6 +41,13 @@ const struct cred *ovl_override_creds(struct super_block *sb) return override_creds(ofs->creator_cred); } +struct super_block *ovl_same_sb(struct super_block *sb) +{ + struct ovl_fs *ofs = sb->s_fs_info; + + return ofs->same_sb; +} + struct ovl_entry *ovl_alloc_entry(unsigned int numlower) { size_t size = offsetof(struct ovl_entry, lowerstack[numlower]); -- cgit v1.2.3 From 595485033db2c24178257698254fd4182fdb4123 Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Sun, 23 Apr 2017 23:12:34 +0300 Subject: ovl: set the ORIGIN type flag For directory entries, non zero oe->numlower implies OVL_TYPE_MERGE. Define a new type flag OVL_TYPE_ORIGIN to indicate that an entry holds a reference to its lower copy up origin. For directory entries ORIGIN := MERGE && UPPER. For non-dir entries ORIGIN means that a lower type dentry has been recently copied up or that we were able to find the copy up origin from overlay.origin xattr. Signed-off-by: Amir Goldstein Signed-off-by: Miklos Szeredi --- fs/overlayfs/overlayfs.h | 2 ++ fs/overlayfs/util.c | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'fs/overlayfs/util.c') diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 77405e27cd64..98af19828695 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -13,10 +13,12 @@ enum ovl_path_type { __OVL_PATH_UPPER = (1 << 0), __OVL_PATH_MERGE = (1 << 1), + __OVL_PATH_ORIGIN = (1 << 2), }; #define OVL_TYPE_UPPER(type) ((type) & __OVL_PATH_UPPER) #define OVL_TYPE_MERGE(type) ((type) & __OVL_PATH_MERGE) +#define OVL_TYPE_ORIGIN(type) ((type) & __OVL_PATH_ORIGIN) #define OVL_XATTR_PREFIX XATTR_TRUSTED_PREFIX "overlay." #define OVL_XATTR_OPAQUE OVL_XATTR_PREFIX "opaque" diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 2bd4c264ccbe..1c1b6ea7bf7c 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -83,11 +83,13 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry) type = __OVL_PATH_UPPER; /* - * Non-dir dentry can hold lower dentry from previous - * location. + * Non-dir dentry can hold lower dentry of its copy up origin. */ - if (oe->numlower && d_is_dir(dentry)) - type |= __OVL_PATH_MERGE; + if (oe->numlower) { + type |= __OVL_PATH_ORIGIN; + if (d_is_dir(dentry)) + type |= __OVL_PATH_MERGE; + } } else { if (oe->numlower > 1) type |= __OVL_PATH_MERGE; -- cgit v1.2.3