From: Greg Kroah-Hartman Date: Thu, 15 Sep 2016 17:18:59 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v4.4.22~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fbe2441053a114647f754516800f53da0124b2fe;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: ext4-use-__gfp_nofail-in-ext4_free_blocks.patch fscrypto-add-authorization-check-for-setting-encryption-policy.patch --- diff --git a/queue-4.4/ext4-use-__gfp_nofail-in-ext4_free_blocks.patch b/queue-4.4/ext4-use-__gfp_nofail-in-ext4_free_blocks.patch new file mode 100644 index 00000000000..23382021ff8 --- /dev/null +++ b/queue-4.4/ext4-use-__gfp_nofail-in-ext4_free_blocks.patch @@ -0,0 +1,197 @@ +From adb7ef600cc9d9d15ecc934cc26af5c1379777df Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Sun, 13 Mar 2016 17:29:06 -0400 +Subject: ext4: use __GFP_NOFAIL in ext4_free_blocks() + +From: Konstantin Khlebnikov + +commit adb7ef600cc9d9d15ecc934cc26af5c1379777df upstream. + +This might be unexpected but pages allocated for sbi->s_buddy_cache are +charged to current memory cgroup. So, GFP_NOFS allocation could fail if +current task has been killed by OOM or if current memory cgroup has no +free memory left. Block allocator cannot handle such failures here yet. + +Signed-off-by: Konstantin Khlebnikov +Signed-off-by: Theodore Ts'o +Cc: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/mballoc.c | 47 ++++++++++++++++++++++++++++------------------- + 1 file changed, 28 insertions(+), 19 deletions(-) + +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -815,7 +815,7 @@ static void mb_regenerate_buddy(struct e + * for this page; do not hold this lock when calling this routine! + */ + +-static int ext4_mb_init_cache(struct page *page, char *incore) ++static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp) + { + ext4_group_t ngroups; + int blocksize; +@@ -848,7 +848,7 @@ static int ext4_mb_init_cache(struct pag + /* allocate buffer_heads to read bitmaps */ + if (groups_per_page > 1) { + i = sizeof(struct buffer_head *) * groups_per_page; +- bh = kzalloc(i, GFP_NOFS); ++ bh = kzalloc(i, gfp); + if (bh == NULL) { + err = -ENOMEM; + goto out; +@@ -983,7 +983,7 @@ out: + * are on the same page e4b->bd_buddy_page is NULL and return value is 0. + */ + static int ext4_mb_get_buddy_page_lock(struct super_block *sb, +- ext4_group_t group, struct ext4_buddy *e4b) ++ ext4_group_t group, struct ext4_buddy *e4b, gfp_t gfp) + { + struct inode *inode = EXT4_SB(sb)->s_buddy_cache; + int block, pnum, poff; +@@ -1002,7 +1002,7 @@ static int ext4_mb_get_buddy_page_lock(s + block = group * 2; + pnum = block / blocks_per_page; + poff = block % blocks_per_page; +- page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); ++ page = find_or_create_page(inode->i_mapping, pnum, gfp); + if (!page) + return -ENOMEM; + BUG_ON(page->mapping != inode->i_mapping); +@@ -1016,7 +1016,7 @@ static int ext4_mb_get_buddy_page_lock(s + + block++; + pnum = block / blocks_per_page; +- page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); ++ page = find_or_create_page(inode->i_mapping, pnum, gfp); + if (!page) + return -ENOMEM; + BUG_ON(page->mapping != inode->i_mapping); +@@ -1042,7 +1042,7 @@ static void ext4_mb_put_buddy_page_lock( + * calling this routine! + */ + static noinline_for_stack +-int ext4_mb_init_group(struct super_block *sb, ext4_group_t group) ++int ext4_mb_init_group(struct super_block *sb, ext4_group_t group, gfp_t gfp) + { + + struct ext4_group_info *this_grp; +@@ -1062,7 +1062,7 @@ int ext4_mb_init_group(struct super_bloc + * The call to ext4_mb_get_buddy_page_lock will mark the + * page accessed. + */ +- ret = ext4_mb_get_buddy_page_lock(sb, group, &e4b); ++ ret = ext4_mb_get_buddy_page_lock(sb, group, &e4b, gfp); + if (ret || !EXT4_MB_GRP_NEED_INIT(this_grp)) { + /* + * somebody initialized the group +@@ -1072,7 +1072,7 @@ int ext4_mb_init_group(struct super_bloc + } + + page = e4b.bd_bitmap_page; +- ret = ext4_mb_init_cache(page, NULL); ++ ret = ext4_mb_init_cache(page, NULL, gfp); + if (ret) + goto err; + if (!PageUptodate(page)) { +@@ -1091,7 +1091,7 @@ int ext4_mb_init_group(struct super_bloc + } + /* init buddy cache */ + page = e4b.bd_buddy_page; +- ret = ext4_mb_init_cache(page, e4b.bd_bitmap); ++ ret = ext4_mb_init_cache(page, e4b.bd_bitmap, gfp); + if (ret) + goto err; + if (!PageUptodate(page)) { +@@ -1109,8 +1109,8 @@ err: + * calling this routine! + */ + static noinline_for_stack int +-ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, +- struct ext4_buddy *e4b) ++ext4_mb_load_buddy_gfp(struct super_block *sb, ext4_group_t group, ++ struct ext4_buddy *e4b, gfp_t gfp) + { + int blocks_per_page; + int block; +@@ -1140,7 +1140,7 @@ ext4_mb_load_buddy(struct super_block *s + * we need full data about the group + * to make a good selection + */ +- ret = ext4_mb_init_group(sb, group); ++ ret = ext4_mb_init_group(sb, group, gfp); + if (ret) + return ret; + } +@@ -1168,11 +1168,11 @@ ext4_mb_load_buddy(struct super_block *s + * wait for it to initialize. + */ + page_cache_release(page); +- page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); ++ page = find_or_create_page(inode->i_mapping, pnum, gfp); + if (page) { + BUG_ON(page->mapping != inode->i_mapping); + if (!PageUptodate(page)) { +- ret = ext4_mb_init_cache(page, NULL); ++ ret = ext4_mb_init_cache(page, NULL, gfp); + if (ret) { + unlock_page(page); + goto err; +@@ -1204,11 +1204,12 @@ ext4_mb_load_buddy(struct super_block *s + if (page == NULL || !PageUptodate(page)) { + if (page) + page_cache_release(page); +- page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); ++ page = find_or_create_page(inode->i_mapping, pnum, gfp); + if (page) { + BUG_ON(page->mapping != inode->i_mapping); + if (!PageUptodate(page)) { +- ret = ext4_mb_init_cache(page, e4b->bd_bitmap); ++ ret = ext4_mb_init_cache(page, e4b->bd_bitmap, ++ gfp); + if (ret) { + unlock_page(page); + goto err; +@@ -1247,6 +1248,12 @@ err: + return ret; + } + ++static int ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, ++ struct ext4_buddy *e4b) ++{ ++ return ext4_mb_load_buddy_gfp(sb, group, e4b, GFP_NOFS); ++} ++ + static void ext4_mb_unload_buddy(struct ext4_buddy *e4b) + { + if (e4b->bd_bitmap_page) +@@ -2047,7 +2054,7 @@ static int ext4_mb_good_group(struct ext + + /* We only do this if the grp has never been initialized */ + if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) { +- int ret = ext4_mb_init_group(ac->ac_sb, group); ++ int ret = ext4_mb_init_group(ac->ac_sb, group, GFP_NOFS); + if (ret) + return ret; + } +@@ -4808,7 +4815,9 @@ do_more: + #endif + trace_ext4_mballoc_free(sb, inode, block_group, bit, count_clusters); + +- err = ext4_mb_load_buddy(sb, block_group, &e4b); ++ /* __GFP_NOFAIL: retry infinitely, ignore TIF_MEMDIE and memcg limit. */ ++ err = ext4_mb_load_buddy_gfp(sb, block_group, &e4b, ++ GFP_NOFS|__GFP_NOFAIL); + if (err) + goto error_return; + +@@ -5210,7 +5219,7 @@ int ext4_trim_fs(struct super_block *sb, + grp = ext4_get_group_info(sb, group); + /* We only do this if the grp has never been initialized */ + if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) { +- ret = ext4_mb_init_group(sb, group); ++ ret = ext4_mb_init_group(sb, group, GFP_NOFS); + if (ret) + break; + } diff --git a/queue-4.4/fscrypto-add-authorization-check-for-setting-encryption-policy.patch b/queue-4.4/fscrypto-add-authorization-check-for-setting-encryption-policy.patch new file mode 100644 index 00000000000..4ca7467a9b7 --- /dev/null +++ b/queue-4.4/fscrypto-add-authorization-check-for-setting-encryption-policy.patch @@ -0,0 +1,55 @@ +From 163ae1c6ad6299b19e22b4a35d5ab24a89791a98 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Thu, 8 Sep 2016 10:57:08 -0700 +Subject: fscrypto: add authorization check for setting encryption policy + +From: Eric Biggers + +commit 163ae1c6ad6299b19e22b4a35d5ab24a89791a98 upstream. + +On an ext4 or f2fs filesystem with file encryption supported, a user +could set an encryption policy on any empty directory(*) to which they +had readonly access. This is obviously problematic, since such a +directory might be owned by another user and the new encryption policy +would prevent that other user from creating files in their own directory +(for example). + +Fix this by requiring inode_owner_or_capable() permission to set an +encryption policy. This means that either the caller must own the file, +or the caller must have the capability CAP_FOWNER. + +(*) Or also on any regular file, for f2fs v4.6 and later and ext4 + v4.8-rc1 and later; a separate bug fix is coming for that. + +Signed-off-by: Eric Biggers +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/crypto_policy.c | 3 +++ + fs/f2fs/crypto_policy.c | 3 +++ + 2 files changed, 6 insertions(+) + +--- a/fs/ext4/crypto_policy.c ++++ b/fs/ext4/crypto_policy.c +@@ -102,6 +102,9 @@ static int ext4_create_encryption_contex + int ext4_process_policy(const struct ext4_encryption_policy *policy, + struct inode *inode) + { ++ if (!inode_owner_or_capable(inode)) ++ return -EACCES; ++ + if (policy->version != 0) + return -EINVAL; + +--- a/fs/f2fs/crypto_policy.c ++++ b/fs/f2fs/crypto_policy.c +@@ -89,6 +89,9 @@ static int f2fs_create_encryption_contex + int f2fs_process_policy(const struct f2fs_encryption_policy *policy, + struct inode *inode) + { ++ if (!inode_owner_or_capable(inode)) ++ return -EACCES; ++ + if (policy->version != 0) + return -EINVAL; + diff --git a/queue-4.4/series b/queue-4.4/series new file mode 100644 index 00000000000..1ba56ea6350 --- /dev/null +++ b/queue-4.4/series @@ -0,0 +1,2 @@ +ext4-use-__gfp_nofail-in-ext4_free_blocks.patch +fscrypto-add-authorization-check-for-setting-encryption-policy.patch