#2214 new defect

DOS defect concerning forged shares

Reported by: rcv Owned by: daira
Priority: major Milestone: soon
Component: code-encoding Version: 1.9.2
Keywords: DOS security verify tahoe-check Cc:
Launchpad Bug:

Description

It is fundamental assumption that when performing the "Verify every bit" checker operation, the verifier will report a corrupt share as a corrupt share and will report a good share as a good share.

However, when dealing with an immutable file, a certain type of "forged" share tricks the verifier into believing the forged share is good. This leads to several unpleasant consequences.

First. Using the verify-every-bit, the user may be wrongly told that their file is healthy, when it is actually unhealthy.

Second. Even if the user knows the file is unhealthy, it is difficult to persuade Tahoe-LAFS to repair the file via the Web or CLI interface.

Third. Depending on the extent of the forgery, attempts to read the file are sometimes met with the dreaded insufficient shares message.

I consider this a form of DOS. There are some mitigating factors, but overall I think this defect is about as severe as #1528.

How to create such a forged share? Simply rename (or copy) a known good share to a different share number. For example, if your storage server is assigned share number 6 in a 3 of 10 distribution, copy that share to shares 0 through 5 and 7 through 10.

One may say that a rogue storage server can delete their shares at any time. True, but normally a verify-every-bit cannot be defeated by a rogue storage server. If the storage server has tampered with the share, the verifier will detect the tamper and attempt to repair the share. If the storage server has deleted the share, the verifier will detect the deletion and attempt to repair the share. If the storage server has presented share number x as share number y, the verifier should detect the forgery and attempt to repair the share.


Demonstration of failure mode:

A sample file (defect.txt) was placed on the public test grid, encoded with k=30, n=31. [The large number of shares is irrelevant, but there were many active storage nodes, and I wanted my node to contain at least two shares.] My storage server was assigned shares 4 and 20. I swapped them with each other. [Later, I placed good copies of shares 0-3, 5-19, and 21-30 on my storage server to protect against other storage nodes leaving the grid.] The readcap for the sample file is: URI:CHK:jrlysuyd6334z3hzpvspsvbpam:gchyqggiohotsvy44cdng6qzxyvvqcfthrud57tml5abxjuljaca:30:31:2235

Verify every bit reports the following. (Surprisingly, shares 4 and 20 were not flagged as corrupt.)


File Check Results for SI=em3llebitvmuhbisp62laknrqe Healthy : Healthy

  • Report:
  • Share Counts: need 30-of-31, have 31
  • Hosts with good shares: 14
  • Corrupt shares: none
  • Wrong Shares: 0
  • Good Shares (sorted in share order):

Attempting to fetch the share gives the following report. (Not surprisingly, shares 4 and 20 are not available.)


NotEnoughSharesError?: This indicates that some servers were unavailable, or that shares have been lost to server departure, hard drive failure, or disk corruption. You should perform a filecheck on this object to learn more.

The full error message is: ran out of shares: complete=sh0,sh1,sh2,sh3,sh5,sh6,sh7,sh8,sh9,sh10,sh11,sh12,sh13,sh14,sh15,sh16,sh17,sh18,sh19,sh21,sh22,sh23,sh24,sh25,sh26,sh27,sh28,sh29,sh30 pending= overdue= unused=Share(sh15-on-tjnj7znu),Share(sh13-on-q7cs354n),Share(sh29-on-q7cs354n),Share(sh14-on-yec63zgr),Share(sh30-on-yec63zgr),Share(sh11-on-sw653ebi),Share(sh27-on-sw653ebi),Share(sh10-on-p742cj66),Share(sh26-on-p742cj66),Share(sh7-on-eyk2eslf),Share(sh23-on-eyk2eslf),Share(sh6-on-27wpeurw),Share(sh22-on-27wpeurw),Share(sh0-on-ra3o4edq),Share(sh16-on-ra3o4edq),Share(sh2-on-uy5th4nz),Share(sh18-on-uy5th4nz),Share(sh1-on-xvwei6mc),Share(sh17-on-xvwei6mc),Share(sh9-on-nszizgf5),Share(sh25-on-nszizgf5),Share(sh5-on-cyuiutio),Share(sh21-on-cyuiutio),Share(sh3-on-oygrircp),Share(sh19-on-oygrircp) need 30. Last failure: [Failure instance: Traceback: <type 'exceptions.AssertionError?'>: /usr/lib/python2.6/dist-packages/twisted/internet/base.py:1165:run /usr/lib/python2.6/dist-packages/twisted/internet/base.py:1174:mainLoop /usr/lib/python2.6/dist-packages/twisted/internet/base.py:796:runUntilCurrent /usr/local/lib/python2.6/dist-packages/foolscap-0.6.4-py2.6.egg/foolscap/eventual.py:26:_turn --- <exception caught here> --- /usr/local/lib/python2.6/dist-packages/allmydata/immutable/downloader/share.py:206:loop /usr/local/lib/python2.6/dist-packages/allmydata/immutable/downloader/share.py:254:_do_loop /usr/local/lib/python2.6/dist-packages/allmydata/immutable/downloader/share.py:323:_get_satisfaction /usr/local/lib/python2.6/dist-packages/allmydata/immutable/downloader/share.py:859:set_block_hash_root /usr/local/lib/python2.6/dist-packages/allmydata/hashtree.py:375:set_hashes


Change History (7)

comment:1 Changed at 2014-04-14T22:48:38Z by daira

  • Component changed from unknown to code-encoding
  • Priority changed from critical to major

comment:2 Changed at 2014-04-15T13:21:23Z by daira

  • Keywords verify tahoe-check added

comment:3 Changed at 2015-01-29T19:48:39Z by daira

  • Milestone changed from undecided to 1.12.0

comment:4 Changed at 2016-03-22T05:02:25Z by warner

  • Milestone changed from 1.12.0 to 1.13.0

Milestone renamed

comment:5 Changed at 2016-06-28T18:17:14Z by warner

  • Milestone changed from 1.13.0 to 1.14.0

renaming milestone

comment:6 Changed at 2020-06-30T14:45:13Z by exarkun

  • Milestone changed from 1.14.0 to 1.15.0

Moving open issues out of closed milestones.

comment:7 Changed at 2021-03-30T18:40:19Z by meejah

  • Milestone changed from 1.15.0 to soon

Ticket retargeted after milestone closed

Note: See TracTickets for help on using tickets.