Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH small 1/1] lsregion: fix slab_unmap() called on malloced slab
@ 2020-05-14 22:31 Vladislav Shpilevoy
  2020-05-19 16:21 ` Aleksandr Lyapunov
  0 siblings, 1 reply; 4+ messages in thread
From: Vladislav Shpilevoy @ 2020-05-14 22:31 UTC (permalink / raw)
  To: tarantool-patches, korablev

Lsregion allocates slabs using either
- Slab_map() from slab arena, when allocation size is smaller,
  than slab size;
- Using cached slab, stored in the lsregion as a protection from
  oscillation;
- Using malloc(), when requested size is too big.

Malloc() was used when allocation size was >= fixed slab size -
meta size. However free() was used, when real slab size was >
fixed slab size - meta size. So if an allocation was exactly of
size 'fixed slab size - meta size', it was allocated using
malloc(), but freed using slab_unmap(). That lead to a crash, if
'lucky'. But as it is a memory corruption, could lead to anything.
---
Branch: http://github.com/tarantool/small/tree/gerold103/fix-lsregion-crash-or-leak

This led to at least leaks in vinyl. Since it used lsregion very
extensively for 0 level of LSM trees.

 small/lsregion.c | 2 +-
 test/lsregion.c  | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/small/lsregion.c b/small/lsregion.c
index b7f2684..6bcc043 100644
--- a/small/lsregion.c
+++ b/small/lsregion.c
@@ -45,7 +45,7 @@ lsregion_alloc_slow(struct lsregion *lsregion, size_t size, int64_t id)
 	}
 	if ((slab != NULL && size > lslab_unused(slab)) ||
 	    slab == NULL) {
-		if (size + lslab_sizeof() >= slab_size) {
+		if (size + lslab_sizeof() > slab_size) {
 			/* Large allocation, use malloc() */
 			slab_size = size + lslab_sizeof();
 			struct quota *quota = lsregion->arena->quota;
diff --git a/test/lsregion.c b/test/lsregion.c
index 1ed6a3a..90ad060 100644
--- a/test/lsregion.c
+++ b/test/lsregion.c
@@ -140,6 +140,13 @@ test_basic()
 	is(lsregion_slab_count(&allocator), 0,
 	   "slab count after large gc()");
 
+	/*
+	 * Allocate exactly slab size.
+	 */
+	++id;
+	data = lsregion_alloc(&allocator, arena.slab_size - lslab_sizeof(), id);
+	lsregion_gc(&allocator, id);
+
 	lsregion_destroy(&allocator);
 	/* Sic: slabs are cached by arena */
 	is(arena.used, 2 * arena.slab_size, "arena used after destroy");
-- 
2.21.1 (Apple Git-122.3)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Tarantool-patches] [PATCH small 1/1] lsregion: fix slab_unmap() called on malloced slab
  2020-05-14 22:31 [Tarantool-patches] [PATCH small 1/1] lsregion: fix slab_unmap() called on malloced slab Vladislav Shpilevoy
@ 2020-05-19 16:21 ` Aleksandr Lyapunov
  2020-05-23 18:13   ` Konstantin Osipov
  0 siblings, 1 reply; 4+ messages in thread
From: Aleksandr Lyapunov @ 2020-05-19 16:21 UTC (permalink / raw)
  To: Vladislav Shpilevoy, tarantool-patches, korablev

Thank for the patch! nice catch, lgtm!

On 5/15/20 1:31 AM, Vladislav Shpilevoy wrote:
> Lsregion allocates slabs using either
> - Slab_map() from slab arena, when allocation size is smaller,
>    than slab size;
> - Using cached slab, stored in the lsregion as a protection from
>    oscillation;
> - Using malloc(), when requested size is too big.
>
> Malloc() was used when allocation size was >= fixed slab size -
> meta size. However free() was used, when real slab size was >
> fixed slab size - meta size. So if an allocation was exactly of
> size 'fixed slab size - meta size', it was allocated using
> malloc(), but freed using slab_unmap(). That lead to a crash, if
> 'lucky'. But as it is a memory corruption, could lead to anything.
> ---
> Branch: http://github.com/tarantool/small/tree/gerold103/fix-lsregion-crash-or-leak
>
> This led to at least leaks in vinyl. Since it used lsregion very
> extensively for 0 level of LSM trees.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Tarantool-patches] [PATCH small 1/1] lsregion: fix slab_unmap() called on malloced slab
  2020-05-19 16:21 ` Aleksandr Lyapunov
@ 2020-05-23 18:13   ` Konstantin Osipov
  2020-05-24 14:06     ` Vladislav Shpilevoy
  0 siblings, 1 reply; 4+ messages in thread
From: Konstantin Osipov @ 2020-05-23 18:13 UTC (permalink / raw)
  To: Aleksandr Lyapunov; +Cc: tarantool-patches, Vladislav Shpilevoy

* Aleksandr Lyapunov <alyapunov@tarantool.org> [20/05/19 19:24]:
> Thank for the patch! nice catch, lgtm!

Is this cherry-picked to 1.10?

-- 
Konstantin Osipov, Moscow, Russia

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Tarantool-patches] [PATCH small 1/1] lsregion: fix slab_unmap() called on malloced slab
  2020-05-23 18:13   ` Konstantin Osipov
@ 2020-05-24 14:06     ` Vladislav Shpilevoy
  0 siblings, 0 replies; 4+ messages in thread
From: Vladislav Shpilevoy @ 2020-05-24 14:06 UTC (permalink / raw)
  To: Konstantin Osipov, Aleksandr Lyapunov, tarantool-patches, korablev

It is not pushed yet.

On 23/05/2020 20:13, Konstantin Osipov wrote:
> * Aleksandr Lyapunov <alyapunov@tarantool.org> [20/05/19 19:24]:
>> Thank for the patch! nice catch, lgtm!
> 
> Is this cherry-picked to 1.10?

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-24 14:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-14 22:31 [Tarantool-patches] [PATCH small 1/1] lsregion: fix slab_unmap() called on malloced slab Vladislav Shpilevoy
2020-05-19 16:21 ` Aleksandr Lyapunov
2020-05-23 18:13   ` Konstantin Osipov
2020-05-24 14:06     ` Vladislav Shpilevoy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox