Skip to content

Commit

Permalink
Handle bundle-add hash failures
Browse files Browse the repository at this point in the history
Fixes #252
Fixes #370
Fixes #371
When failing to add bundle with a file with the wrong hash remove the
file and fall back to the verify_fix_path. Improve warnings so they
don't look like errors until they are actually errors.

Add tests so we don't regress in this regard.

Signed-off-by: Matthew Johnson <[email protected]>
  • Loading branch information
matthewrsj committed Jan 29, 2018
1 parent 88eea5f commit 7483535
Show file tree
Hide file tree
Showing 28 changed files with 197 additions and 14 deletions.
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ BATS = \
test/functional/bundleadd/add-existing/test.bats \
test/functional/bundleadd/add-multiple/test.bats \
test/functional/bundleadd/add-rc/test.bats \
test/functional/bundleadd/bad-hash/test.bats \
test/functional/bundleadd/bad-hash-state/test.bats \
test/functional/bundleadd/boot-file/test.bats \
test/functional/bundleadd/boot-skip/test.bats \
test/functional/bundleadd/include/test.bats \
Expand Down
18 changes: 11 additions & 7 deletions src/bundle.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,32 +730,36 @@ static int install_bundles(struct list *bundles, struct list **subs, int current
* Do not install any files to the system until the hash has been
* verified. The verify_fix_path also verifies the hashes. */
char *hashpath;
char *fullpath; // for the error messages
iter = list_head(to_install_files);
while (iter) {
file = iter->data;
iter = iter->next;

string_or_die(&hashpath, "%s/staged/%s", state_dir, file->hash);
string_or_die(&fullpath, "%s%s", path_prefix, file->filename);

if (access(hashpath, F_OK) < 0) {
/* fallback to verify_fix_path below, which will check the hash
* itself */
free_string(&hashpath);
free_string(&fullpath);
continue;
}

ret = verify_file(file, hashpath);
if (!ret) {
fprintf(stderr, "Error: hash check failed for %s\n", fullpath);
fprintf(stderr, "Warning: hash check failed for %s\n", file->filename);
fprintf(stderr, " will attempt to download fullfile for %s\n", file->filename);
ret = swupd_rm(hashpath);
if (ret) {
fprintf(stderr, "Error: could not remove bad file %s\n", hashpath);
ret = EBUNDLE_INSTALL;
free_string(&hashpath);
goto out;
}
// successfully removed, continue and check the next file
free_string(&hashpath);
free_string(&fullpath);
goto out;
continue;
}
free_string(&hashpath);
free_string(&fullpath);
}

iter = list_head(to_install_files);
Expand Down
4 changes: 2 additions & 2 deletions src/helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -808,9 +808,9 @@ int verify_fix_path(char *targetpath, struct manifest *target_MoM)
if (verify_file(file, target)) {
continue;
}
fprintf(stderr, "Hash did not match for path : %s\n", path);
fprintf(stderr, "Hash did not match for path : %s ... fixing\n", path);
} else if (ret == -1 && errno == ENOENT) {
fprintf(stderr, "Path %s is missing on the file system\n", path);
fprintf(stderr, "Path %s is missing on the file system ... fixing\n", path);
} else {
goto end;
}
Expand Down
5 changes: 5 additions & 0 deletions test/functional/bundleadd/bad-hash-state/lines-checked
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Installing bundle(s) files...
Warning: hash check failed for /testfile
will attempt to download fullfile for /testfile
Path /testfile is missing on the file system ... fixing
Bundle(s) installation done.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test file
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
NAME="Clear Linux Software for Intel Architecture"
VERSION=1
ID=clear-linux-os
VERSION_ID=10
PRETTY_NAME="Clear Linux Software for Intel Architecture"
ANSI_COLOR="1;35"
HOME_URL="https://clearlinux.org"
SUPPORT_URL="https://clearlinux.org"
BUG_REPORT_URL="https://bugs.clearlinux.org/jira"
Empty file.
44 changes: 44 additions & 0 deletions test/functional/bundleadd/bad-hash-state/test.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env bats

load "../../swupdlib"

f_hash="ffbe308091534f3b47b876b241166c4c6d0665204977274093f74851380d49b5"

setup() {
# set up state directory with bad hash file and pack hint
clean_test_dir
sudo mkdir -p $DIR/state/staged
sudo rm -f "$DIR/state/staged/$f_hash"
sudo sh -c "echo \"test file MODIFIED\" > $DIR/state/staged/$f_hash"
sudo touch $DIR/state/pack-test-bundle-from-0-to-10.tar
chown_root -R $DIR/state
sudo chmod -R 0700 $DIR/state

# set up web dir
create_manifest_tar 10 MoM
sign_manifest_mom 10
create_manifest_tar 10 os-core
create_manifest_tar 10 test-bundle
create_fullfile_tar 10 $f_hash
tar -C $DIR/web-dir/10 -cf $DIR/web-dir/10/pack-test-bundle-from-0.tar staged/$f_hash

# clean up test dir
sudo rm -f "$DIR/target-dir/testfile"
}

teardown() {
clean_tars 10
}

@test "bundle-add add bundle with bad hash in state dir" {
# sanity check, the test is invalid if this exists now
[ ! -f "$DIR/target-dir/testfile" ]
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle"

check_lines "$output"
[ "$status" -eq 0 ]
# the corrected file should exist on the filesystem now
[ -f "$DIR/target-dir/testfile" ]
}

# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
MANIFEST 3
version: 10
previous: 0
filecount: 1
timestamp: 1451940175
contentsize: 13805671819

M... 0f026bc0017b676ad1eed7db682408007171cc1c148c39c069f91d740be784d7 10 os-core
M... f88a494e5c91a07758ef75910ba6cadb166082e3f0ed68a656eefec06c9503eb 10 test-bundle
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
MANIFEST 3
version: 10
previous: 0
filecount: 7
timestamp: 1451936779
contentsize: 17929151

D... cde33514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr
D... dde33514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr/lib
D... ede33514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr/lib/kernel
D... cde13514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr/share
D... cde23514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr/share/clear
D... cde43514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr/share/clear/bundles
F... b85f1dc2c2317a20f47a36d3257313b131124ffa6d4f19bb060d43014fd386b0 10 /usr/share/clear/bundles/os-core
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
MANIFEST 3
version: 10
previous: 0
filecount: 1
timestamp: 1451936779
contentsize: 17929151

F... ffbe308091534f3b47b876b241166c4c6d0665204977274093f74851380d49b5 10 /testfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test file
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test file
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10
6 changes: 6 additions & 0 deletions test/functional/bundleadd/bad-hash/lines-checked
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Extracting test-bundle pack for version 10
Installing bundle(s) files...
Warning: hash check failed for /testfile
will attempt to download fullfile for /testfile
Path /testfile is missing on the file system ... fixing
REGEXP:File content hash mismatch for .*
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
NAME="Clear Linux Software for Intel Architecture"
VERSION=1
ID=clear-linux-os
VERSION_ID=10
PRETTY_NAME="Clear Linux Software for Intel Architecture"
ANSI_COLOR="1;35"
HOME_URL="https://clearlinux.org"
SUPPORT_URL="https://clearlinux.org"
BUG_REPORT_URL="https://bugs.clearlinux.org/jira"
Empty file.
35 changes: 35 additions & 0 deletions test/functional/bundleadd/bad-hash/test.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bats

load "../../swupdlib"

# expected hash listed in manifest, but not acutal hash of file
# also file name in staged directory
f_hash="e6d85023c5e619eb43d5cfbfdbdec784afef5a82ffa54e8c93bda3e0883360a3"

setup() {
clean_test_dir
create_manifest_tar 10 MoM
sign_manifest_mom 10
create_manifest_tar 10 os-core
create_manifest_tar 10 test-bundle
create_fullfile_tar 10 $f_hash
chown_root "$DIR/web-dir/10/staged/$f_hash"
tar -C "$DIR/web-dir/10" -cf "$DIR/web-dir/10/pack-test-bundle-from-0.tar" staged/$f_hash
}

teardown() {
clean_tars 10
revert_chown_root "$DIR/web-dir/10/staged/$f_hash"
}

@test "bundle-add add bundle containing file with different hash from what is listed in manifest" {
run sudo sh -c "$SWUPD bundle-add $SWUPD_OPTS test-bundle"

# downloaded fullfile had a bad hash - immediately fatal with a 1 return code
[ "$status" -eq 1 ]
check_lines "$output"
# the bad hash file should not exist on the system
[ ! -f "$DIR/target-dir/testfile" ]
}

# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
9 changes: 9 additions & 0 deletions test/functional/bundleadd/bad-hash/web-dir/10/Manifest.MoM
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
MANIFEST 3
version: 10
previous: 0
filecount: 1
timestamp: 1451940175
contentsize: 13805671819

M... 0f026bc0017b676ad1eed7db682408007171cc1c148c39c069f91d740be784d7 10 os-core
M... bacb42d324b642f45ae4323c462e29acb4344987f430b9b55f70e96443f967c9 10 test-bundle
14 changes: 14 additions & 0 deletions test/functional/bundleadd/bad-hash/web-dir/10/Manifest.os-core
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
MANIFEST 3
version: 10
previous: 0
filecount: 7
timestamp: 1451936779
contentsize: 17929151

D... cde33514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr
D... dde33514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr/lib
D... ede33514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr/lib/kernel
D... cde13514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr/share
D... cde23514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr/share/clear
D... cde43514c151abb2b01448be290ab1d5212952571d15e3533cadc15ff82f2cd5 10 /usr/share/clear/bundles
F... b85f1dc2c2317a20f47a36d3257313b131124ffa6d4f19bb060d43014fd386b0 10 /usr/share/clear/bundles/os-core
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
MANIFEST 3
version: 10
previous: 0
filecount: 1
timestamp: 1451936779
contentsize: 17929151

F... e6d85023c5e619eb43d5cfbfdbdec784afef5a82ffa54e8c93bda3e0883360a3 10 /testfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test file MODIFIED1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test file MODIFIED1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10
2 changes: 1 addition & 1 deletion test/functional/bundleadd/fix-missing-file/lines-checked
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ Downloading packs
Retry #3 downloading subscribed packs
Downloading packs
Installing bundle(s) files
Path /foo is missing on the file system
Path /foo is missing on the file system fixing
Calling post-update helper scripts
Bundle(s) installation done
2 changes: 1 addition & 1 deletion test/functional/bundleadd/verify-fix-path/lines-checked
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Extracting test-bundle pack for version 10
Installing bundle(s) files...
REGEXP:Update target directory does not exist: .*/usr/bin. Trying to fix it
Path /usr/bin is missing on the file system
Path /usr/bin is missing on the file system ... fixing
Bundle(s) installation done.
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ File /usr/bin/foo was not in a pack
Finishing download of update content...
Staging file content
REGEXP:^Update target directory does not exist: .*/target-dir/usr/bin. Trying to fix it$
Hash did not match for path : /usr
Path /usr/bin is missing on the file system
Hash did not match for path : /usr ... fixing
Path /usr/bin is missing on the file system ... fixing
Applying update
Update was applied.
Update successful. System updated from version 10 to version 100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ File /usr/bin/foo was not in a pack
Finishing download of update content...
Staging file content
REGEXP:^Update target directory does not exist: .*/target-dir/usr/bin. Trying to fix it$
Path /usr/bin is missing on the file system
Path /usr/bin is missing on the file system ... fixing
Applying update
Update was applied.
Update successful. System updated from version 10 to version 100
Expand Down

0 comments on commit 7483535

Please sign in to comment.