Uploaded image for project: 'Subversion'
  1. Subversion
  2. SVN-4708

WC can't detect local mods after modify working file during commit.



    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 1.9.6, 1.9.7, 1.10.0-alpha3
    • None
    • libsvn_wc
    • None


      Saving changes to a working file during a commit process that includes that file can leave the WC in a slightly corrupted state: the working file may be out-of-date w.r.t. what's committed and in the repository, and yet "svn status" locally claims there is no modification.

      See discussion "Data corruption bug in WC, apparently due to race condition?" on SVN Dev mailing list, starting with this message (plus a slight clarification in an immediate followup post from the same author):

      From: Karl Fogel
      To: Subversion Dev
      Subject: Data corruption bug in WC, apparently due to race condition?
      Date: Thu, 27 Jul 2017 01:21:54 -0500
      Message-ID: <871sp2tn5p.fsf@floss>

      at this message link:


      Philip Martin confirmed and found a reliable reproduction recipe:

      From: Philip Martin
      To: Karl Fogel
      Cc: Subversion Dev
      Subject: Re: Data corruption bug in WC, apparently due to race condition?
      Date: Thu, 27 Jul 2017 18:56:37 +0100
      Message-ID: <87zibpn4q2.fsf@codematters.co.uk>



      I will just copy Philip's reproduction recipe here:

      The post-commit processing on the client side is not checking for
      modifications before recording filesize/timestamp in the nodes table in

      In first terminal:

      $ svnadmin create repo
      $ svnmucc -mm put <(echo foo) file://`pwd`/repo/f
      $ svn co file://`pwd`/repo wc
      $ echo bar > wc/f
      $ gdb --arg svn ci -mm wc
      (gdb) b svn_client__do_commit
      (gdb) r
      hit breakpoint
      (gdb) fin
      run to end of svn_client__do_commit

      Switch to second terminal:

      $ svn st wc
      L wc
      M wc/f
      $ cat wc/.svn/pristine//
      $ echo zigzag > wc/f

      Switch back to first terminal:

      (gdb) c
      (gdb) q

      I believe that reproduces the problem:

      $ svn cat -r1 wc/f
      $ svn cat -r2 wc/f
      $ cat wc/f
      $ sqlite3 wc/.svn/wc.db "select translated_size from nodes where local_relpath='f'"
      $ svn st wc
      $ touch wc/f # to break timestamp
      $ svn st wc
      M wc/f

      To fix this we would need to have the client's post-commit processing do
      a full-text comparison to catch modifications before storing the
      timestamp/size in .svn/wc.db. Avoid a race is a bit tricky, perhaps:

      1) stat() to get timestamp/filesize
      2) full-text compare to ensure text is unchanged
      3) stat() to ensure timestamp/filesize is unchanged
      4) store timestamp/filesize

      There's some more followup discussion in the thread (note: crossing a month boundary into August, so you may need to do some manual stepping to find all of the discussion). The consensus of the thread is, if I understand it correctly, that this is real bug and it is 100% fixable – that is, it's not a matter of shrinking the window for the race condition, but of getting rid of it altogether.




            Unassigned Unassigned
            kfogel Karl Fogel
            0 Vote for this issue
            1 Start watching this issue