summaryrefslogtreecommitdiff
path: root/extstore.c
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2019-04-27 00:56:01 -0700
committerdormando <dormando@rydia.net>2019-04-27 00:56:01 -0700
commitf8dc1ab092df00d96eaba7e5213989cd739fb91d (patch)
tree322190abbbde28b4c265e8003afa483b6e7fe03f /extstore.c
parent8caa4146a5e6a492f2c85cb9467dc6fdc9b8311e (diff)
downloadmemcached-f8dc1ab092df00d96eaba7e5213989cd739fb91d.tar.gz
extstore: fix segfault if page_count is too high.
leaked into a runtime bug :( fixes #482
Diffstat (limited to 'extstore.c')
-rw-r--r--extstore.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/extstore.c b/extstore.c
index cbfd4d6..9cd7ed8 100644
--- a/extstore.c
+++ b/extstore.c
@@ -200,6 +200,9 @@ const char *extstore_err(enum extstore_res res) {
case EXTSTORE_INIT_PAGE_WBUF_ALIGNMENT:
rv = "page_size and wbuf_size must be divisible by 1024*1024*2";
break;
+ case EXTSTORE_INIT_TOO_MANY_PAGES:
+ rv = "page_count must total to < 65536. Increase page_size or lower path sizes";
+ break;
case EXTSTORE_INIT_OOM:
rv = "failed calloc for engine";
break;
@@ -247,6 +250,7 @@ void *extstore_init(struct extstore_conf_file *fh, struct extstore_conf *cf,
}
e->page_size = cf->page_size;
+ uint64_t temp_page_count = 0;
for (f = fh; f != NULL; f = f->next) {
f->fd = open(f->file, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (f->fd < 0) {
@@ -257,10 +261,17 @@ void *extstore_init(struct extstore_conf_file *fh, struct extstore_conf *cf,
free(e);
return NULL;
}
- e->page_count += f->page_count;
+ temp_page_count += f->page_count;
f->offset = 0;
}
+ if (temp_page_count >= UINT16_MAX) {
+ *res = EXTSTORE_INIT_TOO_MANY_PAGES;
+ free(e);
+ return NULL;
+ }
+ e->page_count = temp_page_count;
+
e->pages = calloc(e->page_count, sizeof(store_page));
if (e->pages == NULL) {
*res = EXTSTORE_INIT_OOM;