Skip to content

Commit fc85be7

Browse files
committed
lib: check frame_size is >= INT32_MAX
When parsing a frame header, validate that the frame_size is less than or equal to INT32_MAX. Given frame_max is limited between 0 and INT32_MAX in amqp_login and friends, this does not change the API. This prevents a potential buffer overflow when a malicious client sends a frame_size that is close to UINT32_MAX, in which causes an overflow when computing state->target_size resulting in a small value there. A buffer is then allocated with the small amount, then memcopy copies the frame_size writing to memory beyond the end of the buffer.
1 parent 60adf5f commit fc85be7

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

Diff for: librabbitmq/amqp_connection.c

+12-3
Original file line numberDiff line numberDiff line change
@@ -287,12 +287,21 @@ int amqp_handle_input(amqp_connection_state_t state, amqp_bytes_t received_data,
287287
case CONNECTION_STATE_HEADER: {
288288
amqp_channel_t channel;
289289
amqp_pool_t *channel_pool;
290-
/* frame length is 3 bytes in */
290+
uint32_t frame_size;
291+
291292
channel = amqp_d16(amqp_offset(raw_frame, 1));
292293

293-
state->target_size =
294-
amqp_d32(amqp_offset(raw_frame, 3)) + HEADER_SIZE + FOOTER_SIZE;
294+
/* frame length is 3 bytes in */
295+
frame_size = amqp_d32(amqp_offset(raw_frame, 3));
296+
/* To prevent the target_size calculation below from overflowing, check
297+
* that the stated frame_size is smaller than a signed 32-bit. Given
298+
* the library only allows configuring frame_max as an int32_t, and
299+
* frame_size is uint32_t, the math below is safe from overflow. */
300+
if (frame_size >= INT32_MAX) {
301+
return AMQP_STATUS_BAD_AMQP_DATA;
302+
}
295303

304+
state->target_size = frame_size + HEADER_SIZE + FOOTER_SIZE;
296305
if ((size_t)state->frame_max < state->target_size) {
297306
return AMQP_STATUS_BAD_AMQP_DATA;
298307
}

0 commit comments

Comments
 (0)