Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow usage of unsafe hashes for reading and adding content #4751

Merged
merged 10 commits into from
Mar 5, 2018

Conversation

Kubuxu
Copy link
Member

@Kubuxu Kubuxu commented Mar 1, 2018

Should be done

@ghost ghost assigned Kubuxu Mar 1, 2018
@ghost ghost added the status/in-progress In progress label Mar 1, 2018
@Kubuxu Kubuxu force-pushed the feat/safe-cid branch 2 times, most recently from 27eb665 to e643269 Compare March 1, 2018 21:13
@Kubuxu
Copy link
Member Author

Kubuxu commented Mar 1, 2018

Short observations:
node.Exchange is not used directly to get blocks

  • it is passed to blockservice
  • commands/add.go uses it directly but passes it to blockservice. //hash security 001
  • thus blocked the blockservice

@Kubuxu
Copy link
Member Author

Kubuxu commented Mar 1, 2018

Random failure in bitswap:

21:15:20.663 ERROR    bitswap: nil cid in GetBlock get.go:18
--- FAIL: TestBasicBitswap (0.01s)
	bitswap_test.go:318: Test a one node trying to get one block from another
	bitswap_test.go:361: stat node 0
	bitswap_test.go:363: stat node 1
	bitswap_test.go:296: mismatch in blocks sent: 0 vs 1
	bitswap_test.go:300: mismatch in blocks recvd: 1 vs 2
	bitswap_test.go:304: mismatch in data sent: 0 vs 1
	bitswap_test.go:308: mismatch in data recvd: 1 vs 2
	bitswap_test.go:365: stat node 2
	bitswap_test.go:372: [Block QmTTA2daxGqo5denp6SwLzzkLJm3fuisYEi9CoWsuHpzfb]
FAIL
FAIL	github.com/ipfs/go-ipfs/exchange/bitswap	4.173s

Passes locally

@Kubuxu
Copy link
Member Author

Kubuxu commented Mar 1, 2018

Sharness has passed. Restarting tests to make them green.
Ignoring the codeclimate, most of this code should be reverted when go-cid can be propagated.

@Kubuxu Kubuxu requested review from Stebalien and magik6k March 1, 2018 21:55
@whyrusleeping
Copy link
Member

Lets not call the package removeme. Lets just put it in thirdparty (Which is already synonymous for removeme at this point).

@@ -149,6 +155,13 @@ func (s *blockService) AddBlock(o blocks.Block) error {
}

func (s *blockService) AddBlocks(bs []blocks.Block) error {
//hash security
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency, add a space before the word hash

Copy link
Member

@magik6k magik6k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code LGTM, could use some tests.

Travis fail looks random

@ghost ghost assigned magik6k Mar 2, 2018
@magik6k
Copy link
Member

magik6k commented Mar 2, 2018

@whyrusleeping
Kubuxu here (I'm at Magik's atm) thus I'm using his account.
I've added some sharness tests.

I think there might be one issue with this whole code, GC might be failing when there are insecure blocks in the bockstore.
I won't have time to fix it today, I can try fixing it tomorrow morning.

@kevina
Copy link
Contributor

kevina commented Mar 2, 2018

Regarding GC, if a block can not be read it is unsafe to continue as that block could potentially point to other blocks that should not be removed.

There are two solutions (1) somehow allow reading of blocks with insecure hashes, (2) force a repo migration, have the the tool check for insecure blocks and then refuse to upgrade until those blocks are dealt with by the user, the tool should also check if the insure blocks point to secure blocks and inform the user of the situation. We could also also provide a separate tool that will automatically convert insecure hashes to a secure hash of there choosing.

Copy link
Member

@Stebalien Stebalien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as a stop-gap, this looks good to me (modulo a few more comments for grepability).

}

func getBlock(ctx context.Context, c *cid.Cid, bs blockstore.Blockstore, f exchange.Fetcher) (blocks.Block, error) {
err := verifcid.ValidateCid(c)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add // hash security comment for future grep.

@@ -258,7 +258,7 @@ You can now check what blocks have been created by:
exch = offline.Exchange(addblockstore)
}

bserv := blockservice.New(addblockstore, exch)
bserv := blockservice.New(addblockstore, exch) // hash security 001
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need the hash security comment?

Copy link
Member

@magik6k magik6k Mar 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only place n.Exchnage is used standalone. ~Kubuxu

@magik6k magik6k force-pushed the feat/safe-cid branch 2 times, most recently from edd60bf to 6e613d3 Compare March 2, 2018 22:59
@kevina
Copy link
Contributor

kevina commented Mar 2, 2018

As this code still allows the use of CID's with insecure hashes, a potentially easy solution to the GC problem allow the reading of insecure hashes, but disallow the publishing or writing of insecure hashes. This will also provide a gentler upgrade path for the rare case when a user has a repo with insecure hashes.

Another solution to just the GC problem is to allow the reading of insecure hashes in the local blockstore, but not the blockservice. This may also allow the user to read them locally, but I am not sure as I think the blockservice is always used even in offline mode. I am also unsure if this will prevent the publishing of insecure hashes.

A third solution is to put a special case in the GC code that will dig out the underlying blockstore and use that directly. I like this solution the least.

kevina
kevina previously requested changes Mar 3, 2018
Copy link
Contributor

@kevina kevina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things will break badly in the unlikely event that there are blocks with an insecure hash in the repo. See my other comments.

@kevina
Copy link
Contributor

kevina commented Mar 3, 2018

@Kubuxu @whyrusleeping as I said in IRC I can take over this P.R. if it will help.

License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
@@ -462,25 +463,23 @@ var verifyPinCmd = &cmds.Command{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
quiet, _, _ := res.Request().Option("quiet").Bool()

outChan, ok := res.Output().(<-chan interface{})
out, err := unwrapOutput(res.Output())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like its being changed to only emit a single output. Whats going on here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to know what is going on also.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The marshaller is called for every message pushed down the channel. I am not sure why the legacy layer is doing this but it prints out all the results.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this is one of the many reasons I've given up on fixing issues with the compat layer and have started just converting commands to use the new system).

# should work online
test_launch_ipfs_daemon
test_cat_get
test_kill_ipfs_daemon
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a test in here that manually puts a bad hash into the datastore, and then runs a gc?

@whyrusleeping
Copy link
Member

This tenatively looks good to me. I'd like to see a few more tests before moving forward though.

@whyrusleeping
Copy link
Member

@Stebalien want to give the gc changes another lookover here?

@Kubuxu
Copy link
Member Author

Kubuxu commented Mar 4, 2018

@whyrusleeping I've added test for general GC but I am unable to test pin set cases. This is because there is no way to add insecure block to pinset.

@kevina
Copy link
Contributor

kevina commented Mar 4, 2018

@Kubuxu if there are insecure hashes will those end up being published?

@Kubuxu
Copy link
Member Author

Kubuxu commented Mar 5, 2018

@kevina you mean by reprovider? Yes but it will continue to work.

@Kubuxu
Copy link
Member Author

Kubuxu commented Mar 5, 2018

@kevina reprovider won't be providing insecure hashes anymore

Copy link
Contributor

@kevina kevina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Please Ignore]

@kevina kevina dismissed their stale review March 5, 2018 02:03

I am not thrilled with the idea of forcing a user to downgrade to read insure hashes, but as a stop-gap measure this will work, especially since it is unlikely that the insure hashes are used much, if at all.

@kevina
Copy link
Contributor

kevina commented Mar 5, 2018

@Kubuxu okay, We should be sure and mark any places where Cid's are verified so that they can cleanly be removed once the strict Cid code lands.

Copy link
Contributor

@hsanjuan hsanjuan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't grow thirdparty, I have to extract these modules and it puts more work on me.

@@ -10,6 +10,7 @@ import (
"io"

exchange "github.com/ipfs/go-ipfs/exchange"
"github.com/ipfs/go-ipfs/thirdparty/verifcid"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not be putting more stuff in thirdparty. If it needs to be re-used across submodules or has interest for other places put it in a different repo, if not, place it in the submodule directly. It complicates extractions afterwards...

Copy link
Member Author

@Kubuxu Kubuxu Mar 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is temporary measure, it will be removed as we are able to propagate go-cid (code comes from PR to go-cid).
The temporary measure was applied because we want to release ASAP and have this behaviour fixed in this release.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then place that code as submodules of blockservice? That way the temporary measure can go together with the temporary code and be fixed with it when it's extracted. Otherwise I will have to do exactly that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hsanjuan the reason I want it in thirdparty is explicitly because it needs to be moved to the cid package as soon as possible. But (as you know) we have a bunch of stuff in-flight that prevents us from bubbling up the cid package without other complications, so its going here for now as a "please remove me"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@whyrusleeping sure, I understand the reasons, but it still introduces a blocker for me.

I'm trying to communicate that if it's placed under blockservice with a "please-remove-me" note it doesn't become a blocker while solving your problem at the same time.

If you say this will be removed from thirdparty right away after the release, OK. I'm just scared that things will take longer though.

@@ -17,6 +17,7 @@ import (
pin "github.com/ipfs/go-ipfs/pin"
repo "github.com/ipfs/go-ipfs/repo"
cfg "github.com/ipfs/go-ipfs/repo/config"
"github.com/ipfs/go-ipfs/thirdparty/verifbs"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This too

@@ -462,25 +463,23 @@ var verifyPinCmd = &cmds.Command{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
quiet, _, _ := res.Request().Option("quiet").Bool()

outChan, ok := res.Output().(<-chan interface{})
out, err := unwrapOutput(res.Output())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this is one of the many reasons I've given up on fixing issues with the compat layer and have started just converting commands to use the new system).

@Stebalien
Copy link
Member

Failure:

  
cp: cannot stat '../t0275-cid-security-data/AFKSEBCGPUJZE.data': No such file or directory
not ok 23 - injecting insecure block
#	
#	    mkdir -p "$IPFS_PATH/blocks/JZ" &&
#	    cp -f ../t0275-cid-security-data/AFKSEBCGPUJZE.data "$IPFS_PATH/blocks/JZ"
#	  

@Kubuxu
Copy link
Member Author

Kubuxu commented Mar 5, 2018

missed file from commit, fixing (I didn't notice the CI failures for some reason).

License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
@Kubuxu
Copy link
Member Author

Kubuxu commented Mar 5, 2018

Fixed

@whyrusleeping
Copy link
Member

Alright, here goes.

@whyrusleeping whyrusleeping merged commit 13887ff into master Mar 5, 2018
@whyrusleeping whyrusleeping deleted the feat/safe-cid branch March 5, 2018 20:25
@ghost ghost removed the status/in-progress In progress label Mar 5, 2018
kevina added a commit that referenced this pull request Jun 24, 2018
This mostly reverts commit 13887ff,
reversing changes made to a544026.

It keeps the fixed to "ipfs pin verify" and a fix to t0050-block.sh to use
a longer block size.
@kevina kevina mentioned this pull request Jun 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants