Author: philip
Date: Wed Mar 14 14:24:36 2018
New Revision: 1826720
URL: http://svn.apache.org/viewvc?rev=1826720&view=rev
Log:
Add a checksum length verification to the FSFS checksum code. This
may have prevented the issue 4722 checksum bug by making the problem
much more visible: it would have failed lots of successful commits
that only succeeded by ignoring the length error.
* subversion/libsvn_fs_fs/cached_data.c
(rep_read_contents): This is now a READ_FULL_FN for svn_stream_t
and a short read is EOF at which point the length can be checked.
When originally written the code was a READ_FN and a short read
was not necessarily EOF.
Modified:
subversion/trunk/subversion/libsvn_fs_fs/cached_data.c
Modified: subversion/trunk/subversion/libsvn_fs_fs/cached_data.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/cached_data.c?rev=1826720&r1=1826719&r2=1826720&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/cached_data.c Wed Mar 14 14:24:36
2018
@@ -2103,13 +2103,14 @@ skip_contents(struct rep_read_baton *bat
/* BATON is of type `rep_read_baton'; read the next *LEN bytes of the
representation and store them in *BUF. Sum as we read and verify
- the MD5 sum at the end. */
+ the MD5 sum at the end. This is a READ_FULL_FN for svn_stream_t. */
static svn_error_t *
rep_read_contents(void *baton,
char *buf,
apr_size_t *len)
{
struct rep_read_baton *rb = baton;
+ apr_size_t len_requested = *len;
/* Get data from the fulltext cache for as long as we can. */
if (rb->fulltext_cache)
@@ -2150,6 +2151,12 @@ rep_read_contents(void *baton,
if (rb->current_fulltext)
svn_stringbuf_appendbytes(rb->current_fulltext, buf, *len);
+ /* This is a FULL_READ_FN so a short read implies EOF. */
+ rb->off += *len;
+ if (*len < len_requested && rb->off != rb->len)
+ return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+ _("Length mismatch while reading representation"));
+
/* Perform checksumming. We want to check the checksum as soon as
the last byte of data is read, in case the caller never performs
a short read, but we don't want to finalize the MD5 context
@@ -2157,7 +2164,6 @@ rep_read_contents(void *baton,
if (!rb->checksum_finalized)
{
SVN_ERR(svn_checksum_update(rb->md5_checksum_ctx, buf, *len));
- rb->off += *len;
if (rb->off == rb->len)
{
svn_checksum_t *md5_checksum;