diff mbox series

[v2,23/23] mm/sl[au]b: check if large object is valid in __ksize()

Message ID 20220414085727.643099-24-42.hyeyoo@gmail.com (mailing list archive)
State New
Headers show
Series common kmalloc for SLUB and SLAB v2 | expand

Commit Message

Hyeonggon Yoo April 14, 2022, 8:57 a.m. UTC
__ksize() returns size of objects allocated from slab allocator.
When invalid object is passed to __ksize(), returning zero
prevents further memory corruption and makes caller be able to
check if there is an error.

If address of large object is not beginning of folio or size of
the folio is too small, it must be invalid. Return zero in such cases.

Suggested-by: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
---
 mm/slab_common.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Comments

Christoph Lameter April 14, 2022, 9:58 a.m. UTC | #1
On Thu, 14 Apr 2022, Hyeonggon Yoo wrote:

> If address of large object is not beginning of folio or size of
> the folio is too small, it must be invalid. Return zero in such cases.

This looks like a slab usage error on the part of the caller that would
benefit from a kernel log entry. A warning or an error?
Hyeonggon Yoo April 14, 2022, 11:46 a.m. UTC | #2
On Thu, Apr 14, 2022 at 11:58:01AM +0200, Christoph Lameter wrote:
> On Thu, 14 Apr 2022, Hyeonggon Yoo wrote:
> 
> > If address of large object is not beginning of folio or size of
> > the folio is too small, it must be invalid. Return zero in such cases.
> 
> This looks like a slab usage error on the part of the caller that would
> benefit from a kernel log entry. A warning or an error?


I think a WARN_ON() would be sufficient. here, will do in v3.
Thanks!
diff mbox series

Patch

diff --git a/mm/slab_common.c b/mm/slab_common.c
index 8facade42bdd..a14f9990b159 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -994,8 +994,12 @@  size_t __ksize(const void *object)
 
 	folio = virt_to_folio(object);
 
-	if (unlikely(!folio_test_slab(folio)))
+	if (unlikely(!folio_test_slab(folio))) {
+		if (object != folio_address(folio) ||
+				folio_size(folio) <= KMALLOC_MAX_CACHE_SIZE)
+			return 0;
 		return folio_size(folio);
+	}
 
 	return slab_ksize(folio_slab(folio)->slab_cache);
 }