Skip to content

Commit

Permalink
Fix possible buffer overflows on 32 bit systems
Browse files Browse the repository at this point in the history
Comparing pointers after adding lengths is dangerous, since the length can overflow the pointer, so that the comparison leads to wrong results.
Comparing lengths only fixes this issue.

This lead to segfault in the following spec on x86:

	it "should raise an error at grabage COPY format" do
		expect{ decoder.decode("123\t \0\\\t\\") }
			.to raise_error(ArgumentError, /premature.*at position: 7$/)
	end
  • Loading branch information
larskanis committed Oct 20, 2023
1 parent 90879fa commit fb3fba9
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions ext/pg_copy_coder.c
Original file line number Diff line number Diff line change
Expand Up @@ -795,26 +795,26 @@ pg_bin_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tupl
cur_ptr = input_line;
line_end_ptr = input_line + len;

if (cur_ptr + 11 <= line_end_ptr && memcmp(cur_ptr, BinarySignature, 11) == 0){
if (line_end_ptr - cur_ptr >= 11 && memcmp(cur_ptr, BinarySignature, 11) == 0){
/* binary COPY header signature detected -> just drop it */
int ext_bytes;
cur_ptr += 11;

/* read flags */
if (cur_ptr + 4 > line_end_ptr) goto length_error;
if (line_end_ptr - cur_ptr < 4 ) goto length_error;
cur_ptr += 4;

/* read header extensions */
if (cur_ptr + 4 > line_end_ptr) goto length_error;
if (line_end_ptr - cur_ptr < 4 ) goto length_error;
ext_bytes = read_nbo32(cur_ptr);
if (ext_bytes < 0) goto length_error;
cur_ptr += 4;
if (cur_ptr + ext_bytes > line_end_ptr) goto length_error;
if (line_end_ptr - cur_ptr < ext_bytes ) goto length_error;
cur_ptr += ext_bytes;
}

/* read row header */
if (cur_ptr + 2 > line_end_ptr) goto length_error;
if (line_end_ptr - cur_ptr < 2 ) goto length_error;
nfields = read_nbo16(cur_ptr);
cur_ptr += 2;

Expand All @@ -830,7 +830,7 @@ pg_bin_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tupl
VALUE field_value;

/* read field size */
if (cur_ptr + 4 > line_end_ptr) goto length_error;
if (line_end_ptr - cur_ptr < 4 ) goto length_error;
input_len = read_nbo32(cur_ptr);
cur_ptr += 4;

Expand All @@ -839,7 +839,7 @@ pg_bin_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tupl
/* NULL indicator */
rb_ary_push(array, Qnil);
} else {
if (cur_ptr + input_len > line_end_ptr) goto length_error;
if (line_end_ptr - cur_ptr < input_len ) goto length_error;

/* copy input data to field_str */
PG_RB_STR_ENSURE_CAPA( field_str, input_len, output_ptr, end_capa_ptr );
Expand Down

0 comments on commit fb3fba9

Please sign in to comment.