ports/134091: [PATCH] svn_hacks.1.2.diff crashes subversion

Giorgos Keramidas keramida at FreeBSD.org
Wed Apr 29 13:00:05 UTC 2009

>Number:         134091
>Category:       ports
>Synopsis:       [PATCH] svn_hacks.1.2.diff crashes subversion
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 29 13:00:04 UTC 2009
>Originator:     Giorgos Keramidas
>Release:        FreeBSD 8.0-CURRENT i386
<organization of PR author (multiple lines)>
System: FreeBSD kobe 8.0-CURRENT FreeBSD 8.0-CURRENT #0: \
Sun Apr 26 05:48:02 EEST 2009 build at kobe:/usr/obj/usr/src/sys/KOBE i386


The svn_hacks.1.2.diff patch crashes subversion when a tag is created.


Running the following shell script shows the core dump in action, and
leaves an `svn.core' file in `B/svn.core':


    set -e

    svnadmin create svn-repo

    mkdir proj
    cd proj
    mkdir trunk
    mkdir tags
    cd ..

    svn import -m "init project repository" proj $svnurl

    echo % add filename with spaces
    svn co $svnurl/trunk B
    cd B
    echo hello > 'letter .txt'
    svn add 'letter .txt'
    svn ci -m hello

    echo % append to filename with spaces
    echo world >> 'letter .txt'
    svn ci -m world

    echo % create tag
    svn copy -m "tag v0.1" $svnurl/trunk $svnurl/tags/v0.1

    echo % append once more
    echo 'nice day today!' >> 'letter .txt'
    svn ci -m "nice day"
    cd ..

    echo % append after tagging and add a new file
    cd B
    echo "see second letter" >> 'letter .txt'
    echo "nice to meet you" > letter2.txt
    svn add letter2.txt
    svn ci -m "second letter"

    echo % second tag
    svn copy -m "tag v0.2" $svnurl/trunk $svnurl/tags/v0.2

    echo % append to second letter
    echo "blah-blah-blah" >> letter2.txt
    svn ci -m "work in progress"
    cd ..

Running the script with subversion-freebsd patched by svn_hacks.1.2.diff
results in:

    keramida at kobe:/tmp/svncore$ sh test.sh
    Adding         proj/trunk
    Adding         proj/tags

    Committed revision 1.
    % add filename with spaces
    Checked out revision 1.
    A         letter .txt
    Adding         letter .txt
    Transmitting file data .
    Committed revision 2.
    % append to filename with spaces
    Sending        letter .txt
    Transmitting file data .
    Committed revision 3.
    % create tag
    Segmentation fault (core dumped)
    keramida at kobe:/tmp/svncore$ find . -name svn.core
    keramida at kobe:/tmp/svncore$

and the core dump backtrace is:

    #0  strstr (s=0x4 <Address 0x4 out of bounds>, find=0x806e78a "R:") at /usr/src/lib/libc/string/strstr.c:54
    54                                      if ((sc = *s++) == '\0')
    [New Thread 28a01140 (LWP 100167)]
    (gdb) bt
    #0  strstr (s=0x4 <Address 0x4 out of bounds>, find=0x806e78a "R:") at /usr/src/lib/libc/string/strstr.c:54
    #1  0x0805c3cc in cleanmsg ()
    #2  0x0805d1f9 in svn_cl__get_log_message ()
    #3  0x280bf4d2 in svn_client__get_log_msg () from /usr/local/lib/libsvn_client-1.so.0
    #4  0x280c4a96 in repos_to_repos_copy () from /usr/local/lib/libsvn_client-1.so.0
    #5  0x280c5997 in try_copy () from /usr/local/lib/libsvn_client-1.so.0
    #6  0x280c6383 in svn_client_copy5 () from /usr/local/lib/libsvn_client-1.so.0
    #7  0x0804edca in svn_cl__copy ()
    #8  0x08054c79 in main ()

The problem seems to be a use before initialization of the `log_msg'
pointer in the (patched) version of util.c:svn_cl__get_log_message() in
subversion-1.6.0/subversion/svn/util.c.  near line 743 of the patched
version we have:

      truncate_buffer_at_prefix(&(log_msg_buf->len), log_msg_buf->data,
      cleanmsg(NULL, (char*)*log_msg);

So we prepare the log message in log_msg_buf->data, but then we try to
cleanmsg() the (uninitialized so far) pointer at *log_msg.

I've renamed svn_hacks.1.2.diff to svn_hacks.1.3.diff and changed only
the cleanmsg() call to use:

      cleanmsg(NULL, (char *)log_msg_buf->data);

This seems to work slightly better, and now I can run the test script
without any core dumps.


A git-style patch that renames svn_hacks_1.2.diff to svn_hacks_1.3.diff
and patches the subversion ports to use it, and bumps PORTREVISION to 3
is attached below:

diff --git a/devel/subversion-freebsd/Makefile b/devel/subversion-freebsd/Makefile
--- a/devel/subversion-freebsd/Makefile
+++ b/devel/subversion-freebsd/Makefile
@@ -16,7 +16,7 @@
 #PATCH_SITES=		http://lev.serebryakov.spb.ru/download/
-PATCHFILES+=		svn_hacks_1.2.diff
+PATCHFILES+=		svn_hacks_1.3.diff
 CONFLICTS?=	subversion-[0-9]* subversion-devel-[0-9]*
diff --git a/devel/subversion/Makefile.common b/devel/subversion/Makefile.common
--- a/devel/subversion/Makefile.common
+++ b/devel/subversion/Makefile.common
@@ -6,7 +6,7 @@
 PORTNAME=	subversion
 MASTER_SITES=	http://subversion.tigris.org/downloads/:main \
diff --git a/devel/subversion/distinfo b/devel/subversion/distinfo
--- a/devel/subversion/distinfo
+++ b/devel/subversion/distinfo
@@ -7,6 +7,6 @@
 MD5 (subversion/svn-book.pdf) = a2d503ce36f6a72a8f136a127f3e14d3
 SHA256 (subversion/svn-book.pdf) = 64e483cd27be6752eb8dfc1b00749f8dc46adfc4fb1ab1356dd8e2406d878225
 SIZE (subversion/svn-book.pdf) = 1671317
-MD5 (subversion/svn_hacks_1.2.diff) = 8b08322abd3d1c0fa4f3dcacf4fff26c
-SHA256 (subversion/svn_hacks_1.2.diff) = 0743ecdbb3848d73c8c3a8d9832f93ab986deb6ff2b7bf2b19e1b5f4f3c6eb70
-SIZE (subversion/svn_hacks_1.2.diff) = 18098
+MD5 (subversion/svn_hacks_1.3.diff) = 1650e5a5396ba4c3ab2245b5c99de1ef
+SHA256 (subversion/svn_hacks_1.3.diff) = 03875664103edfa5b962bb50e6c8c0878ad53eaac202444418e2a491068588bc
+SIZE (subversion/svn_hacks_1.3.diff) = 18108


The changes from svn_hacks_1.2.diff to svn_hacks_1.3.diff are ...

diff --git a/distfiles/subversion/svn_hacks_1.2.diff b/distfiles/subversion/svn_hacks_1.3.diff
rename from distfiles/subversion/svn_hacks_1.2.diff
rename to distfiles/subversion/svn_hacks_1.3.diff
--- a/distfiles/subversion/svn_hacks_1.2.diff
+++ b/distfiles/subversion/svn_hacks_1.3.diff
@@ -449,7 +449,7 @@
           that follows it.  */
        truncate_buffer_at_prefix(&(log_msg_buf->len), log_msg_buf->data,
-+      cleanmsg(NULL, (char*)*log_msg);
++      cleanmsg(NULL, (char *)log_msg_buf->data);
        /* Make a string from a stringbuf, sharing the data allocation. */
        log_msg_str->data = log_msg_buf->data;

More information about the freebsd-ports-bugs mailing list