Hi,
I've noticed that the svn_fs_fs__get_changes function currently invokes
undefined behavior when there is no CHANGES_CACHE present. According to the
fs_fs_data_t contract, this is a perfectly valid situation (see
subversion\libsvn_fs_fs\fs.h around trunk@1549686):
[[[
/* Private (non-shared) FSFS-specific data for each svn_fs_t object.
Any caches in here may be NULL. */
]]]
However, explicitly setting the CHANGES_CACHE to NULL leads to a massive amount
of failing tests (1085 fails on my 64-bit Ubuntu machine, some of them are
segfaults). This erroneous behavior was introduced in r1512904 [1] and happens
due to the usage of the uninitialized variable FOUND when the CHANGES_CACHE
is absent. The behavior in this case is undefined and that will likely lead to
a crash. Here is a tip from valgrind:
[[[
Conditional jump or move depends on uninitialised value(s)
at 0x4852AF: svn_fs_fs__get_changes (cached_data.c:2183)
by 0x469E4C: svn_fs_fs__paths_changed (transaction.c:889)
by 0x475CDE: fs_paths_changed (tree.c:3291)
by 0x44DCE7: svn_fs_paths_changed2 (fs-loader.c:1006)
...
Use of uninitialised value of size 8
at 0x469E8C: svn_fs_fs__paths_changed (transaction.c:892)
by 0x475CDE: fs_paths_changed (tree.c:3291)
by 0x44DCE7: svn_fs_paths_changed2 (fs-loader.c:1006)
...
]]]
This happens with both FSFS and FSX, so I've attached two patches to fix this
issue (these patches fix the svn_fs_fs__get_changes and svn_fs_x__get_changes
functions accordingly).
[1] http://svn.apache.org/viewvc?view=revision&revision=r1512904
Thanks and regards,
Evgeny Kotkov
Index: subversion/libsvn_fs_fs/cached_data.c
===================================================================
--- subversion/libsvn_fs_fs/cached_data.c (revision 1549686)
+++ subversion/libsvn_fs_fs/cached_data.c (working copy)
@@ -2177,8 +2177,14 @@ svn_fs_fs__get_changes(apr_array_header_t **change
/* try cache lookup first */
if (ffd->changes_cache)
- SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache,
- &rev, pool));
+ {
+ SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache,
+ &rev, pool));
+ }
+ else
+ {
+ found = FALSE;
+ }
if (!found)
{
Avoid undefined behavior (and crashing) within svn_fs_fs__get_changes when
there is no changes cache. Caches in fs_fs_data_t are optional by design:
[[[
/* Private (non-shared) FSFS-specific data for each svn_fs_t object.
Any caches in here may be NULL. */
]]]
Follow-up to r1512904.
* subversion/libsvn_fs_fs/cached_data.c
(svn_fs_fs__get_changes): Avoid possible uninitialized variable access by
setting FOUND to FALSE in case we do not have a CHANGES_CACHE.
Patch by: Evgeny Kotkov <evgeny.kotkov{_AT_}visualsvn.com>
Index: subversion/libsvn_fs_x/cached_data.c
===================================================================
--- subversion/libsvn_fs_x/cached_data.c (revision 1549686)
+++ subversion/libsvn_fs_x/cached_data.c (working copy)
@@ -2335,6 +2335,10 @@ svn_fs_x__get_changes(apr_array_header_t **changes
SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache,
&rev, pool));
}
+ else
+ {
+ found = FALSE;
+ }
if (!found)
{
Avoid undefined behavior (and crashing) within svn_fs_x__get_changes when
there are no changes and changes container caches. Caches in fs_x_data_t are
optional by design:
[[[
/* Private (non-shared) FSX-specific data for each svn_fs_t object.
Any caches in here may be NULL. */
]]]
Follow-up to r1508041.
* subversion/libsvn_fs_x/cached_data.c
(svn_fs_x__get_changes): Avoid possible uninitialized variable access by
setting FOUND to FALSE in case we do not have CHANGES_CACHE and
CHANGES_CONTAINER_CACHE.
Patch by: Evgeny Kotkov <evgeny.kotkov{_AT_}visualsvn.com>