diff options
author | Jonathan Nieder <jrnieder@gmail.com> | 2011-05-27 05:44:27 -0500 |
---|---|---|
committer | Jonathan Nieder <jrnieder@gmail.com> | 2011-06-15 02:32:50 -0500 |
commit | 3ac10b2e3fd6d858621f796160d251ad34affc20 (patch) | |
tree | a8a247ae4053480219c6c2dad47c9466a888c0f0 /vcs-svn | |
parent | vcs-svn: guard against overflow when computing preimage length (diff) | |
download | tgif-3ac10b2e3fd6d858621f796160d251ad34affc20.tar.xz |
vcs-svn: avoid hangs from corrupt deltas
A corrupt Subversion-format delta can request reads past the end of
the preimage. Set sliding_view::max_off so such corruption is caught
when it appears rather than blocking in an impossible-to-fulfill
read() when input is coming from a socket or pipe.
Inspired-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Diffstat (limited to 'vcs-svn')
-rw-r--r-- | vcs-svn/fast_export.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c index 96a75d51d1..97f5fdf489 100644 --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@ -198,8 +198,7 @@ static long apply_delta(off_t len, struct line_buffer *input, const char *old_data, uint32_t old_mode) { long ret; - off_t preimage_len = 0; - struct sliding_view preimage = SLIDING_VIEW_INIT(&report_buffer, -1); + struct sliding_view preimage = SLIDING_VIEW_INIT(&report_buffer, 0); FILE *out; if (init_postimage() || !(out = buffer_tmpfile_rewind(&postimage))) @@ -211,19 +210,23 @@ static long apply_delta(off_t len, struct line_buffer *input, printf("cat-blob %s\n", old_data); fflush(stdout); response = get_response_line(); - if (parse_cat_response_line(response, &preimage_len)) + if (parse_cat_response_line(response, &preimage.max_off)) die("invalid cat-blob response: %s", response); + check_preimage_overflow(preimage.max_off, 1); } if (old_mode == REPO_MODE_LNK) { strbuf_addstr(&preimage.buf, "link "); - check_preimage_overflow(preimage_len, strlen("link ")); - preimage_len += strlen("link "); + check_preimage_overflow(preimage.max_off, strlen("link ")); + preimage.max_off += strlen("link "); + check_preimage_overflow(preimage.max_off, 1); } if (svndiff0_apply(input, len, &preimage, out)) die("cannot apply delta"); if (old_data) { /* Read the remainder of preimage and trailing newline. */ - if (move_window(&preimage, preimage_len, 1)) + assert(!signed_add_overflows(preimage.max_off, 1)); + preimage.max_off++; /* room for newline */ + if (move_window(&preimage, preimage.max_off - 1, 1)) die("cannot seek to end of input"); if (preimage.buf.buf[0] != '\n') die("missing newline after cat-blob response"); |