diff --git a/include/proto/shctx.h b/include/proto/shctx.h index 13e00c753..594a81d52 100644 --- a/include/proto/shctx.h +++ b/include/proto/shctx.h @@ -31,7 +31,8 @@ #endif #endif -int shctx_init(struct shared_context **orig_shctx, int maxblocks, int blocksize, int extra, int shared); +int shctx_init(struct shared_context **orig_shctx, + int maxblocks, int blocksize, int maxobjsz, int extra, int shared); struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx, struct shared_block *last, int data_len); void shctx_row_inc_hot(struct shared_context *shctx, struct shared_block *first); diff --git a/include/types/shctx.h b/include/types/shctx.h index 186f7365d..53dca3f13 100644 --- a/include/types/shctx.h +++ b/include/types/shctx.h @@ -40,6 +40,7 @@ struct shared_context { struct list avail; /* list for active and free blocks */ struct list hot; /* list for locked blocks */ unsigned int nbav; /* number of available blocks */ + int max_obj_size; /* maximum object size. */ void (*free_block)(struct shared_block *first, struct shared_block *block); short int block_size; unsigned char data[0]; diff --git a/src/cache.c b/src/cache.c index a198b4069..c0e895794 100644 --- a/src/cache.c +++ b/src/cache.c @@ -882,7 +882,7 @@ int cfg_post_parse_section_cache() goto out; } - ret_shctx = shctx_init(&shctx, tmp_cache_config->maxblocks, CACHE_BLOCKSIZE, sizeof(struct cache), 1); + ret_shctx = shctx_init(&shctx, tmp_cache_config->maxblocks, CACHE_BLOCKSIZE, -1, sizeof(struct cache), 1); if (ret_shctx < 0) { if (ret_shctx == SHCTX_E_INIT_LOCK) diff --git a/src/shctx.c b/src/shctx.c index 2a149a1d5..604fd7df0 100644 --- a/src/shctx.c +++ b/src/shctx.c @@ -43,6 +43,13 @@ struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx, if (data_len > shctx->nbav * shctx->block_size) goto out; + /* Check the object size limit. */ + if (shctx->max_obj_size > 0) { + if ((first && first->len + data_len > shctx->max_obj_size) || + (!first && data_len > shctx->max_obj_size)) + goto out; + } + /* Note that is nul only if is not nul. */ remain = 1; if (first) { @@ -284,7 +291,8 @@ int shctx_row_data_get(struct shared_context *shctx, struct shared_block *first, * Returns: -1 on alloc failure, if it performs context alloc, * and 0 if cache is already allocated. */ -int shctx_init(struct shared_context **orig_shctx, int maxblocks, int blocksize, int extra, int shared) +int shctx_init(struct shared_context **orig_shctx, int maxblocks, int blocksize, + int maxobjsz, int extra, int shared) { int i; struct shared_context *shctx; @@ -351,6 +359,7 @@ int shctx_init(struct shared_context **orig_shctx, int maxblocks, int blocksize, LIST_INIT(&shctx->hot); shctx->block_size = blocksize; + shctx->max_obj_size = maxobjsz; /* init the free blocks after the shared context struct */ cur = (void *)shctx + sizeof(struct shared_context) + extra; diff --git a/src/ssl_sock.c b/src/ssl_sock.c index ee713692b..140f406b5 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -4786,7 +4786,7 @@ int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf) } if (!ssl_shctx && global.tune.sslcachesize) { alloc_ctx = shctx_init(&ssl_shctx, global.tune.sslcachesize, - sizeof(struct sh_ssl_sess_hdr) + SHSESS_BLOCK_MIN_SIZE, + sizeof(struct sh_ssl_sess_hdr) + SHSESS_BLOCK_MIN_SIZE, -1, sizeof(*sh_ssl_sess_tree), ((global.nbthread > 1) || (!global_ssl.private_cache && (global.nbproc > 1))) ? 1 : 0); if (alloc_ctx < 0) {