Skip to content
Snippets Groups Projects
Commit 879b7026 authored by Konstantin Osipov's avatar Konstantin Osipov
Browse files

Fix a bug with a crash when slab alloc arena is full.

When the slab alloc arena is fully used, and we try to
truncate a space, we could crash, since

a) we never check return value of salloc()
b) we used to salloc() an iterator for truncate(), and
it would return NULL, and we would try to access it without a check.

The fix is:

- to throw exceptions directly from salloc()
- to not use salloc() for iterators, since we still should
be able to truncate a namespace when the slab alloc arena is
full.
parent 59d244fc
No related branches found
No related tags found
No related merge requests found
...@@ -34,7 +34,7 @@ struct tbuf; ...@@ -34,7 +34,7 @@ struct tbuf;
bool salloc_init(size_t size, size_t minimal, double factor); bool salloc_init(size_t size, size_t minimal, double factor);
void salloc_destroy(void); void salloc_destroy(void);
void *salloc(size_t size); void *salloc(size_t size, const char *what);
void sfree(void *ptr); void sfree(void *ptr);
void slab_validate(); void slab_validate();
void slab_stat(struct tbuf *buf); void slab_stat(struct tbuf *buf);
......
...@@ -224,7 +224,7 @@ void ...@@ -224,7 +224,7 @@ void
hash_iterator_free(struct iterator *iterator) hash_iterator_free(struct iterator *iterator)
{ {
assert(iterator->next == hash_iterator_next); assert(iterator->next == hash_iterator_next);
sfree(iterator); free(iterator);
} }
...@@ -285,7 +285,7 @@ hash_iterator_free(struct iterator *iterator) ...@@ -285,7 +285,7 @@ hash_iterator_free(struct iterator *iterator)
- (struct iterator *) allocIterator - (struct iterator *) allocIterator
{ {
struct hash_iterator *it = salloc(sizeof(struct hash_iterator)); struct hash_iterator *it = malloc(sizeof(struct hash_iterator));
if (it) { if (it) {
memset(it, 0, sizeof(struct hash_iterator)); memset(it, 0, sizeof(struct hash_iterator));
it->base.next = hash_iterator_next; it->base.next = hash_iterator_next;
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include "tree.h" #include "tree.h"
#include "box.h" #include "box.h"
#include "tuple.h" #include "tuple.h"
#include <salloc.h>
#include <pickle.h> #include <pickle.h>
/* {{{ Utilities. *************************************************/ /* {{{ Utilities. *************************************************/
...@@ -801,7 +800,7 @@ tree_iterator_free(struct iterator *iterator) ...@@ -801,7 +800,7 @@ tree_iterator_free(struct iterator *iterator)
if (it->iter) if (it->iter)
sptree_index_iterator_free(it->iter); sptree_index_iterator_free(it->iter);
sfree(it); free(it);
} }
/* }}} */ /* }}} */
...@@ -926,7 +925,7 @@ tree_iterator_free(struct iterator *iterator) ...@@ -926,7 +925,7 @@ tree_iterator_free(struct iterator *iterator)
- (struct iterator *) allocIterator - (struct iterator *) allocIterator
{ {
struct tree_iterator *it struct tree_iterator *it
= salloc(sizeof(struct tree_iterator) + SIZEOF_SPARSE_PARTS(key_def)); = malloc(sizeof(struct tree_iterator) + SIZEOF_SPARSE_PARTS(key_def));
if (it) { if (it) {
memset(it, 0, sizeof(struct tree_iterator)); memset(it, 0, sizeof(struct tree_iterator));
......
...@@ -39,10 +39,7 @@ struct box_tuple * ...@@ -39,10 +39,7 @@ struct box_tuple *
tuple_alloc(size_t size) tuple_alloc(size_t size)
{ {
size_t total = sizeof(struct box_tuple) + size; size_t total = sizeof(struct box_tuple) + size;
struct box_tuple *tuple = salloc(total); struct box_tuple *tuple = salloc(total, "tuple");
if (tuple == NULL)
tnt_raise(LoggedError, :ER_MEMORY_ISSUE, total, "slab allocator", "tuple");
tuple->flags = tuple->refs = 0; tuple->flags = tuple->refs = 0;
tuple->bsize = size; tuple->bsize = size;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <util.h> #include <util.h>
#include <tbuf.h> #include <tbuf.h>
#include <say.h> #include <say.h>
#include "exception.h"
#define SLAB_ALIGN_PTR(ptr) (void *)((uintptr_t)(ptr) & ~(SLAB_SIZE - 1)) #define SLAB_ALIGN_PTR(ptr) (void *)((uintptr_t)(ptr) & ~(SLAB_SIZE - 1))
...@@ -258,17 +259,18 @@ valid_item(struct slab *slab, void *item) ...@@ -258,17 +259,18 @@ valid_item(struct slab *slab, void *item)
#endif #endif
void * void *
salloc(size_t size) salloc(size_t size, const char *what)
{ {
struct slab_class *class; struct slab_class *class;
struct slab *slab; struct slab *slab;
struct slab_item *item; struct slab_item *item;
if ((class = class_for(size)) == NULL) if ((class = class_for(size)) == NULL ||
return NULL; (slab = slab_of(class)) == NULL) {
if ((slab = slab_of(class)) == NULL) tnt_raise(LoggedError, :ER_MEMORY_ISSUE, size,
return NULL; "slab allocator", what);
}
if (slab->free == NULL) { if (slab->free == NULL) {
assert(valid_item(slab, slab->brk)); assert(valid_item(slab, slab->brk));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment