Add request size validation
This commit is contained in:
@@ -38,6 +38,8 @@
|
|||||||
#define MSGR_SENDP_HDR 1
|
#define MSGR_SENDP_HDR 1
|
||||||
#define MSGR_SENDP_FREE 2
|
#define MSGR_SENDP_FREE 2
|
||||||
|
|
||||||
|
#define MAX_SIMPLE_PAYLOAD_SIZE 1048576
|
||||||
|
|
||||||
struct msgr_sendp_t
|
struct msgr_sendp_t
|
||||||
{
|
{
|
||||||
osd_op_t *op;
|
osd_op_t *op;
|
||||||
@@ -181,9 +183,12 @@ public:
|
|||||||
timerfd_manager_t *tfd = NULL;
|
timerfd_manager_t *tfd = NULL;
|
||||||
ring_loop_i *ringloop = NULL;
|
ring_loop_i *ringloop = NULL;
|
||||||
bool has_sendmsg_zc = false;
|
bool has_sendmsg_zc = false;
|
||||||
// osd_num_t is only for logging and asserts
|
|
||||||
uint64_t next_client_id = 1;
|
uint64_t next_client_id = 1;
|
||||||
osd_num_t osd_num;
|
// osd_num = 0 for client messenger, osd_num > 0 for OSD messenger
|
||||||
|
osd_num_t osd_num = 0;
|
||||||
|
uint32_t clean_entry_bitmap_size = 0;
|
||||||
|
uint32_t bs_block_size = 0;
|
||||||
|
uint32_t max_write_request_size = 0;
|
||||||
robin_hood::unordered_flat_map<uint64_t, osd_client_t*> clients;
|
robin_hood::unordered_flat_map<uint64_t, osd_client_t*> clients;
|
||||||
robin_hood::unordered_flat_map<uint64_t, osd_client_t*> osd_peers;
|
robin_hood::unordered_flat_map<uint64_t, osd_client_t*> osd_peers;
|
||||||
robin_hood::unordered_flat_map<int, osd_client_t*> clients_by_fd;
|
robin_hood::unordered_flat_map<int, osd_client_t*> clients_by_fd;
|
||||||
@@ -249,7 +254,7 @@ protected:
|
|||||||
bool handle_read(int result, osd_client_t *cl);
|
bool handle_read(int result, osd_client_t *cl);
|
||||||
bool handle_read_buffer(osd_client_t *cl, void *curbuf, int remain);
|
bool handle_read_buffer(osd_client_t *cl, void *curbuf, int remain);
|
||||||
bool handle_finished_read(osd_client_t *cl);
|
bool handle_finished_read(osd_client_t *cl);
|
||||||
void handle_op_hdr(osd_client_t *cl);
|
bool handle_op_hdr(osd_client_t *cl);
|
||||||
bool handle_reply_hdr(osd_client_t *cl);
|
bool handle_reply_hdr(osd_client_t *cl);
|
||||||
void handle_reply_ready(osd_op_t *op);
|
void handle_reply_ready(osd_op_t *op);
|
||||||
void handle_immediate_ops();
|
void handle_immediate_ops();
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ struct __attribute__((visibility("default"))) osd_op_t
|
|||||||
// bitmap, bitmap_len, bmp_data are only meaningful for reads
|
// bitmap, bitmap_len, bmp_data are only meaningful for reads
|
||||||
void *bitmap = NULL;
|
void *bitmap = NULL;
|
||||||
unsigned bitmap_len = 0;
|
unsigned bitmap_len = 0;
|
||||||
unsigned bmp_data = 0;
|
size_t bmp_data = 0;
|
||||||
void *bitmap_buf = NULL;
|
void *bitmap_buf = NULL;
|
||||||
void *rmw_buf = NULL;
|
void *rmw_buf = NULL;
|
||||||
osd_primary_op_data_t* op_data = NULL;
|
osd_primary_op_data_t* op_data = NULL;
|
||||||
|
|||||||
@@ -231,7 +231,11 @@ bool osd_messenger_t::handle_finished_read(osd_client_t *cl)
|
|||||||
}
|
}
|
||||||
cl->read_op_id++;
|
cl->read_op_id++;
|
||||||
}
|
}
|
||||||
handle_op_hdr(cl);
|
if (!handle_op_hdr(cl))
|
||||||
|
{
|
||||||
|
stop_client(cl->client_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -262,7 +266,7 @@ bool osd_messenger_t::handle_finished_read(osd_client_t *cl)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void osd_messenger_t::handle_op_hdr(osd_client_t *cl)
|
bool osd_messenger_t::handle_op_hdr(osd_client_t *cl)
|
||||||
{
|
{
|
||||||
osd_op_t *cur_op = cl->read_op;
|
osd_op_t *cur_op = cl->read_op;
|
||||||
if (cur_op->req.hdr.opcode == OSD_OP_SEC_READ)
|
if (cur_op->req.hdr.opcode == OSD_OP_SEC_READ)
|
||||||
@@ -274,7 +278,16 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl)
|
|||||||
{
|
{
|
||||||
if (cur_op->req.sec_rw.attr_len > 0)
|
if (cur_op->req.sec_rw.attr_len > 0)
|
||||||
{
|
{
|
||||||
if (cur_op->req.sec_rw.attr_len > sizeof(unsigned))
|
if (cur_op->req.sec_rw.attr_len > clean_entry_bitmap_size)
|
||||||
|
{
|
||||||
|
if (log_level > 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: peer %ju secondary write request attr_len too large (%u > %u bytes), stopping\n", cl->client_id,
|
||||||
|
cur_op->req.sec_rw.attr_len, clean_entry_bitmap_size);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (cur_op->req.sec_rw.attr_len > sizeof(cur_op->bmp_data))
|
||||||
cur_op->bitmap = cur_op->rmw_buf = malloc_or_die(cur_op->req.sec_rw.attr_len);
|
cur_op->bitmap = cur_op->rmw_buf = malloc_or_die(cur_op->req.sec_rw.attr_len);
|
||||||
else
|
else
|
||||||
cur_op->bitmap = &cur_op->bmp_data;
|
cur_op->bitmap = &cur_op->bmp_data;
|
||||||
@@ -282,6 +295,15 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl)
|
|||||||
}
|
}
|
||||||
if (cur_op->req.sec_rw.len > 0)
|
if (cur_op->req.sec_rw.len > 0)
|
||||||
{
|
{
|
||||||
|
if (cur_op->req.sec_rw.len > bs_block_size)
|
||||||
|
{
|
||||||
|
if (log_level > 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: peer %ju secondary write request size too large (%u > %u bytes), stopping\n", cl->client_id,
|
||||||
|
cur_op->req.sec_rw.len, bs_block_size);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.sec_rw.len);
|
cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.sec_rw.len);
|
||||||
cl->recv_list.push_back(cur_op->buf, cur_op->req.sec_rw.len);
|
cl->recv_list.push_back(cur_op->buf, cur_op->req.sec_rw.len);
|
||||||
}
|
}
|
||||||
@@ -292,6 +314,15 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl)
|
|||||||
{
|
{
|
||||||
if (cur_op->req.sec_stab.len > 0)
|
if (cur_op->req.sec_stab.len > 0)
|
||||||
{
|
{
|
||||||
|
if (cur_op->req.sec_stab.len > MAX_SIMPLE_PAYLOAD_SIZE)
|
||||||
|
{
|
||||||
|
if (log_level > 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: peer %ju stabilize request size too large (%lu > %u bytes), stopping\n", cl->client_id,
|
||||||
|
cur_op->req.sec_stab.len, MAX_SIMPLE_PAYLOAD_SIZE);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.sec_stab.len);
|
cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.sec_stab.len);
|
||||||
cl->recv_list.push_back(cur_op->buf, cur_op->req.sec_stab.len);
|
cl->recv_list.push_back(cur_op->buf, cur_op->req.sec_stab.len);
|
||||||
}
|
}
|
||||||
@@ -301,6 +332,15 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl)
|
|||||||
{
|
{
|
||||||
if (cur_op->req.sec_read_bmp.len > 0)
|
if (cur_op->req.sec_read_bmp.len > 0)
|
||||||
{
|
{
|
||||||
|
if (cur_op->req.sec_read_bmp.len > MAX_SIMPLE_PAYLOAD_SIZE)
|
||||||
|
{
|
||||||
|
if (log_level > 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: peer %ju sec_read_bmp request size too large (%lu > %u bytes), stopping\n", cl->client_id,
|
||||||
|
cur_op->req.sec_read_bmp.len, MAX_SIMPLE_PAYLOAD_SIZE);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.sec_read_bmp.len);
|
cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.sec_read_bmp.len);
|
||||||
cl->recv_list.push_back(cur_op->buf, cur_op->req.sec_read_bmp.len);
|
cl->recv_list.push_back(cur_op->buf, cur_op->req.sec_read_bmp.len);
|
||||||
}
|
}
|
||||||
@@ -310,6 +350,15 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl)
|
|||||||
{
|
{
|
||||||
if (cur_op->req.rw.len > 0)
|
if (cur_op->req.rw.len > 0)
|
||||||
{
|
{
|
||||||
|
if (cur_op->req.rw.len > max_write_request_size)
|
||||||
|
{
|
||||||
|
if (log_level > 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: peer %ju write request size too large (%u > %u bytes), stopping\n", cl->client_id,
|
||||||
|
cur_op->req.rw.len, max_write_request_size);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.rw.len);
|
cur_op->buf = memalign_or_die(MEM_ALIGNMENT, cur_op->req.rw.len);
|
||||||
cl->recv_list.push_back(cur_op->buf, cur_op->req.rw.len);
|
cl->recv_list.push_back(cur_op->buf, cur_op->req.rw.len);
|
||||||
}
|
}
|
||||||
@@ -319,6 +368,15 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl)
|
|||||||
{
|
{
|
||||||
if (cur_op->req.show_conf.json_len > 0)
|
if (cur_op->req.show_conf.json_len > 0)
|
||||||
{
|
{
|
||||||
|
if (cur_op->req.show_conf.json_len > MAX_SIMPLE_PAYLOAD_SIZE)
|
||||||
|
{
|
||||||
|
if (log_level > 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: peer %ju show_config request length too large (%lu > %u bytes), stopping\n", cl->client_id,
|
||||||
|
cur_op->req.show_conf.json_len, MAX_SIMPLE_PAYLOAD_SIZE);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
cur_op->buf = malloc_or_die(cur_op->req.show_conf.json_len+1);
|
cur_op->buf = malloc_or_die(cur_op->req.show_conf.json_len+1);
|
||||||
((uint8_t*)cur_op->buf)[cur_op->req.show_conf.json_len] = 0;
|
((uint8_t*)cur_op->buf)[cur_op->req.show_conf.json_len] = 0;
|
||||||
cl->recv_list.push_back(cur_op->buf, cur_op->req.show_conf.json_len);
|
cl->recv_list.push_back(cur_op->buf, cur_op->req.show_conf.json_len);
|
||||||
@@ -344,6 +402,7 @@ void osd_messenger_t::handle_op_hdr(osd_client_t *cl)
|
|||||||
cl->read_op = NULL;
|
cl->read_op = NULL;
|
||||||
cl->read_state = 0;
|
cl->read_state = 0;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool osd_messenger_t::handle_reply_hdr(osd_client_t *cl)
|
bool osd_messenger_t::handle_reply_hdr(osd_client_t *cl)
|
||||||
|
|||||||
@@ -192,6 +192,9 @@ void osd_t::parse_config(bool init)
|
|||||||
if (!bs_bitmap_granularity)
|
if (!bs_bitmap_granularity)
|
||||||
bs_bitmap_granularity = DEFAULT_BITMAP_GRANULARITY;
|
bs_bitmap_granularity = DEFAULT_BITMAP_GRANULARITY;
|
||||||
clean_entry_bitmap_size = bs_block_size / bs_bitmap_granularity / 8;
|
clean_entry_bitmap_size = bs_block_size / bs_bitmap_granularity / 8;
|
||||||
|
msgr.bs_block_size = bs_block_size;
|
||||||
|
msgr.clean_entry_bitmap_size = clean_entry_bitmap_size;
|
||||||
|
msgr.max_write_request_size = MAX_DATA_BLOCK_SIZE; // will be changed after pool config
|
||||||
// immediate_commit
|
// immediate_commit
|
||||||
if (config["immediate_commit"] == "all")
|
if (config["immediate_commit"] == "all")
|
||||||
immediate_commit = IMMEDIATE_ALL;
|
immediate_commit = IMMEDIATE_ALL;
|
||||||
|
|||||||
@@ -427,6 +427,21 @@ void osd_t::on_change_pool_config_hook()
|
|||||||
{
|
{
|
||||||
apply_pg_locks_localize_only();
|
apply_pg_locks_localize_only();
|
||||||
}
|
}
|
||||||
|
msgr.max_write_request_size = 0;
|
||||||
|
for (auto & pc: st_cli->pool_config)
|
||||||
|
{
|
||||||
|
auto & pool_cfg = pc.second;
|
||||||
|
uint32_t pg_data_size = (pool_cfg.scheme == POOL_SCHEME_REPLICATED ? 1 : pool_cfg.pg_size-pool_cfg.parity_chunks);
|
||||||
|
uint32_t pg_block_size = pool_cfg.data_block_size * pg_data_size;
|
||||||
|
if (msgr.max_write_request_size < pg_block_size)
|
||||||
|
{
|
||||||
|
msgr.max_write_request_size = pg_block_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!msgr.max_write_request_size)
|
||||||
|
{
|
||||||
|
msgr.max_write_request_size = MAX_DATA_BLOCK_SIZE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void osd_t::apply_pg_locks_localize_only()
|
void osd_t::apply_pg_locks_localize_only()
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#define FLUSH_BATCH 512
|
#define FLUSH_BATCH 512
|
||||||
#define SELF_CLIENT 0
|
#define SELF_CLIENT 0
|
||||||
|
|
||||||
|
static_assert(FLUSH_BATCH <= MAX_SIMPLE_PAYLOAD_SIZE / sizeof(obj_ver_id));
|
||||||
|
|
||||||
void osd_t::submit_pg_flush_ops(pg_t & pg)
|
void osd_t::submit_pg_flush_ops(pg_t & pg)
|
||||||
{
|
{
|
||||||
pg_flush_batch_t *fb = new pg_flush_batch_t();
|
pg_flush_batch_t *fb = new pg_flush_batch_t();
|
||||||
|
|||||||
Reference in New Issue
Block a user