* [PATCH AUTOSEL 4.9 12/24] kasan, slub: move kasan_poison_slab hook before page_address
[not found] <20190313191647.160171-1-sashal@kernel.org>
@ 2019-03-13 19:16 ` Sasha Levin
2019-03-13 19:16 ` [PATCH AUTOSEL 4.9 13/24] tmpfs: fix link accounting when a tmpfile is linked in Sasha Levin
` (2 subsequent siblings)
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2019-03-13 19:16 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Andrey Konovalov, Alexander Potapenko, Andrey Ryabinin,
Catalin Marinas, Christoph Lameter, David Rientjes,
Dmitry Vyukov, Evgeniy Stepanov, Joonsoo Kim, Kostya Serebryany,
Pekka Enberg, Qian Cai, Vincenzo Frascino, Andrew Morton,
Linus Torvalds, Sasha Levin, linux-mm
From: Andrey Konovalov <andreyknvl@google.com>
[ Upstream commit a71012242837fe5e67d8c999cfc357174ed5dba0 ]
With tag based KASAN page_address() looks at the page flags to see whether
the resulting pointer needs to have a tag set. Since we don't want to set
a tag when page_address() is called on SLAB pages, we call
page_kasan_tag_reset() in kasan_poison_slab(). However in allocate_slab()
page_address() is called before kasan_poison_slab(). Fix it by changing
the order.
[andreyknvl@google.com: fix compilation error when CONFIG_SLUB_DEBUG=n]
Link: http://lkml.kernel.org/r/ac27cc0bbaeb414ed77bcd6671a877cf3546d56e.1550066133.git.andreyknvl@google.com
Link: http://lkml.kernel.org/r/cd895d627465a3f1c712647072d17f10883be2a1.1549921721.git.andreyknvl@google.com
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Evgeniy Stepanov <eugenis@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Qian Cai <cai@lca.pw>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/slub.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/mm/slub.c b/mm/slub.c
index 131dee87a67c..979400b1a781 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1052,6 +1052,16 @@ static void setup_object_debug(struct kmem_cache *s, struct page *page,
init_tracking(s, object);
}
+static void setup_page_debug(struct kmem_cache *s, void *addr, int order)
+{
+ if (!(s->flags & SLAB_POISON))
+ return;
+
+ metadata_access_enable();
+ memset(addr, POISON_INUSE, PAGE_SIZE << order);
+ metadata_access_disable();
+}
+
static inline int alloc_consistency_checks(struct kmem_cache *s,
struct page *page,
void *object, unsigned long addr)
@@ -1269,6 +1279,8 @@ unsigned long kmem_cache_flags(unsigned long object_size,
#else /* !CONFIG_SLUB_DEBUG */
static inline void setup_object_debug(struct kmem_cache *s,
struct page *page, void *object) {}
+static inline void setup_page_debug(struct kmem_cache *s,
+ void *addr, int order) {}
static inline int alloc_debug_processing(struct kmem_cache *s,
struct page *page, void *object, unsigned long addr) { return 0; }
@@ -1584,12 +1596,11 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
if (page_is_pfmemalloc(page))
SetPageSlabPfmemalloc(page);
- start = page_address(page);
+ kasan_poison_slab(page);
- if (unlikely(s->flags & SLAB_POISON))
- memset(start, POISON_INUSE, PAGE_SIZE << order);
+ start = page_address(page);
- kasan_poison_slab(page);
+ setup_page_debug(s, start, order);
shuffle = shuffle_freelist(s, page);
--
2.19.1
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH AUTOSEL 4.9 13/24] tmpfs: fix link accounting when a tmpfile is linked in
[not found] <20190313191647.160171-1-sashal@kernel.org>
2019-03-13 19:16 ` [PATCH AUTOSEL 4.9 12/24] kasan, slub: move kasan_poison_slab hook before page_address Sasha Levin
@ 2019-03-13 19:16 ` Sasha Levin
2019-03-13 19:16 ` [PATCH AUTOSEL 4.9 14/24] kasan, slab: fix conflicts with CONFIG_HARDENED_USERCOPY Sasha Levin
2019-03-13 19:16 ` [PATCH AUTOSEL 4.9 15/24] kasan, slab: make freelist stored without tags Sasha Levin
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2019-03-13 19:16 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Darrick J. Wong, Hugh Dickins, Andrew Morton, Linus Torvalds,
Sasha Levin, linux-mm
From: "Darrick J. Wong" <darrick.wong@oracle.com>
[ Upstream commit 1062af920c07f5b54cf5060fde3339da6df0cf6b ]
tmpfs has a peculiarity of accounting hard links as if they were
separate inodes: so that when the number of inodes is limited, as it is
by default, a user cannot soak up an unlimited amount of unreclaimable
dcache memory just by repeatedly linking a file.
But when v3.11 added O_TMPFILE, and the ability to use linkat() on the
fd, we missed accommodating this new case in tmpfs: "df -i" shows that
an extra "inode" remains accounted after the file is unlinked and the fd
closed and the actual inode evicted. If a user repeatedly links
tmpfiles into a tmpfs, the limit will be hit (ENOSPC) even after they
are deleted.
Just skip the extra reservation from shmem_link() in this case: there's
a sense in which this first link of a tmpfile is then cheaper than a
hard link of another file, but the accounting works out, and there's
still good limiting, so no need to do anything more complicated.
Link: http://lkml.kernel.org/r/alpine.LSU.2.11.1902182134370.7035@eggly.anvils
Fixes: f4e0c30c191 ("allow the temp files created by open() to be linked to")
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Hugh Dickins <hughd@google.com>
Reported-by: Matej Kupljen <matej.kupljen@gmail.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index 9b17bd4cbc5e..214773472530 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2902,10 +2902,14 @@ static int shmem_link(struct dentry *old_dentry, struct inode *dir, struct dentr
* No ordinary (disk based) filesystem counts links as inodes;
* but each new link needs a new dentry, pinning lowmem, and
* tmpfs dentries cannot be pruned until they are unlinked.
+ * But if an O_TMPFILE file is linked into the tmpfs, the
+ * first link must skip that, to get the accounting right.
*/
- ret = shmem_reserve_inode(inode->i_sb);
- if (ret)
- goto out;
+ if (inode->i_nlink) {
+ ret = shmem_reserve_inode(inode->i_sb);
+ if (ret)
+ goto out;
+ }
dir->i_size += BOGO_DIRENT_SIZE;
inode->i_ctime = dir->i_ctime = dir->i_mtime = current_time(inode);
--
2.19.1
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH AUTOSEL 4.9 14/24] kasan, slab: fix conflicts with CONFIG_HARDENED_USERCOPY
[not found] <20190313191647.160171-1-sashal@kernel.org>
2019-03-13 19:16 ` [PATCH AUTOSEL 4.9 12/24] kasan, slub: move kasan_poison_slab hook before page_address Sasha Levin
2019-03-13 19:16 ` [PATCH AUTOSEL 4.9 13/24] tmpfs: fix link accounting when a tmpfile is linked in Sasha Levin
@ 2019-03-13 19:16 ` Sasha Levin
2019-03-13 19:16 ` [PATCH AUTOSEL 4.9 15/24] kasan, slab: make freelist stored without tags Sasha Levin
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2019-03-13 19:16 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Andrey Konovalov, Alexander Potapenko, Andrey Ryabinin,
Catalin Marinas, Dmitry Vyukov, Evgeniy Stepanov,
Kostya Serebryany, Vincenzo Frascino, Andrew Morton,
Linus Torvalds, Sasha Levin, linux-mm
From: Andrey Konovalov <andreyknvl@google.com>
[ Upstream commit 219667c23c68eb3dbc0d5662b9246f28477fe529 ]
Similarly to commit 96fedce27e13 ("kasan: make tag based mode work with
CONFIG_HARDENED_USERCOPY"), we need to reset pointer tags in
__check_heap_object() in mm/slab.c before doing any pointer math.
Link: http://lkml.kernel.org/r/9a5c0f958db10e69df5ff9f2b997866b56b7effc.1550602886.git.andreyknvl@google.com
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Tested-by: Qian Cai <cai@lca.pw>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Evgeniy Stepanov <eugenis@google.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/slab.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mm/slab.c b/mm/slab.c
index 354a09deecff..b30b58de793b 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -4461,6 +4461,8 @@ const char *__check_heap_object(const void *ptr, unsigned long n,
unsigned int objnr;
unsigned long offset;
+ ptr = kasan_reset_tag(ptr);
+
/* Find and validate object. */
cachep = page->slab_cache;
objnr = obj_to_index(cachep, page, (void *)ptr);
--
2.19.1
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH AUTOSEL 4.9 15/24] kasan, slab: make freelist stored without tags
[not found] <20190313191647.160171-1-sashal@kernel.org>
` (2 preceding siblings ...)
2019-03-13 19:16 ` [PATCH AUTOSEL 4.9 14/24] kasan, slab: fix conflicts with CONFIG_HARDENED_USERCOPY Sasha Levin
@ 2019-03-13 19:16 ` Sasha Levin
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2019-03-13 19:16 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Andrey Konovalov, Alexander Potapenko, Andrey Ryabinin,
Catalin Marinas, Dmitry Vyukov, Evgeniy Stepanov,
Kostya Serebryany, Vincenzo Frascino, Andrew Morton,
Linus Torvalds, Sasha Levin, linux-mm
From: Andrey Konovalov <andreyknvl@google.com>
[ Upstream commit 51dedad06b5f6c3eea7ec1069631b1ef7796912a ]
Similarly to "kasan, slub: move kasan_poison_slab hook before
page_address", move kasan_poison_slab() before alloc_slabmgmt(), which
calls page_address(), to make page_address() return value to be
non-tagged. This, combined with calling kasan_reset_tag() for off-slab
slab management object, leads to freelist being stored non-tagged.
Link: http://lkml.kernel.org/r/dfb53b44a4d00de3879a05a9f04c1f55e584f7a1.1550602886.git.andreyknvl@google.com
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Tested-by: Qian Cai <cai@lca.pw>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Evgeniy Stepanov <eugenis@google.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/slab.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/mm/slab.c b/mm/slab.c
index b30b58de793b..cb1f38e72b4e 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2405,6 +2405,7 @@ static void *alloc_slabmgmt(struct kmem_cache *cachep,
/* Slab management obj is off-slab. */
freelist = kmem_cache_alloc_node(cachep->freelist_cache,
local_flags, nodeid);
+ freelist = kasan_reset_tag(freelist);
if (!freelist)
return NULL;
} else {
@@ -2717,6 +2718,13 @@ static struct page *cache_grow_begin(struct kmem_cache *cachep,
offset *= cachep->colour_off;
+ /*
+ * Call kasan_poison_slab() before calling alloc_slabmgmt(), so
+ * page_address() in the latter returns a non-tagged pointer,
+ * as it should be for slab pages.
+ */
+ kasan_poison_slab(page);
+
/* Get slab management. */
freelist = alloc_slabmgmt(cachep, page, offset,
local_flags & ~GFP_CONSTRAINT_MASK, page_node);
@@ -2725,7 +2733,6 @@ static struct page *cache_grow_begin(struct kmem_cache *cachep,
slab_map_pages(cachep, page, freelist);
- kasan_poison_slab(page);
cache_init_objs(cachep, page);
if (gfpflags_allow_blocking(local_flags))
--
2.19.1
^ permalink raw reply [flat|nested] 4+ messages in thread