You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/08/19 19:09:15 UTC
svn commit: r1515516 - /subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
Author: stefan2
Date: Mon Aug 19 17:09:15 2013
New Revision: 1515516
URL: http://svn.apache.org/r1515516
Log:
Make the revprop access robust against corrupted pack files that
claim to cover / contain revision ranges either not packed or outside
the current shard. This is to prevent manifest index overflows
further down the road.
* subversion/libsvn_fs_fs/fs_fs.c
(same_shard): new utility
(parse_packed_revprops): verify revprop pack file revision range
Modified:
subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
Modified: subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c?rev=1515516&r1=1515515&r2=1515516&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c Mon Aug 19 17:09:15 2013
@@ -3752,6 +3752,17 @@ get_revprop_packname(svn_fs_t *fs,
return SVN_NO_ERROR;
}
+/* Return TRUE, if revision R1 and R2 refer to the same shard in FS.
+ */
+static svn_boolean_t
+same_shard(svn_fs_t *fs,
+ svn_revnum_t r1,
+ svn_revnum_t r2)
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+ return (r1 / ffd->max_files_per_dir) == (r2 / ffd->max_files_per_dir);
+}
+
/* Given FS and the full packed file content in REVPROPS->PACKED_REVPROPS,
* fill the START_REVISION, SIZES, OFFSETS members. Also, make
* PACKED_REVPROPS point to the first serialized revprop.
@@ -3783,6 +3794,25 @@ parse_packed_revprops(svn_fs_t *fs,
SVN_ERR(read_number_from_stream(&first_rev, NULL, stream, iterpool));
SVN_ERR(read_number_from_stream(&count, NULL, stream, iterpool));
+ /* Check revision range for validity. */
+ if ( !same_shard(fs, revprops->revision, first_rev)
+ || !same_shard(fs, revprops->revision, first_rev + count - 1)
+ || count < 1)
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ _("Revprop pack for revision r%ld"
+ " contains revprops for r%ld .. r%ld"),
+ revprops->revision, first_rev,
+ first_rev + count -1);
+
+ /* Since start & end are in the same shard, it is enough to just test
+ * the FIRST_REV for being actually packed. That will also cover the
+ * special case of rev 0 never being packed. */
+ if (!is_packed_revprop(fs, first_rev))
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ _("Revprop pack for revision r%ld"
+ " starts at non-packed revisions r%ld"),
+ revprops->revision, first_rev);
+
/* make PACKED_REVPROPS point to the first char after the header.
* This is where the serialized revprops are. */
header_end = strstr(uncompressed->data, "\n\n");