Skip to content

Commit

Permalink
verity: check after activation for any corruption
Browse files Browse the repository at this point in the history
ActivateByVolumeKey does check for corruption via the dm_status task
after activation, but if it finds that it was corrupted, it only logs
that to stderr and returns 0 anyway.

For cases where corruption can be detected immediately, we want to fail
the mounting, so we add a second check of the same task after activating
the device (or after checking the hash on an existing device), and fail
early.

Signed-off-by: Michael McCracken <[email protected]>
  • Loading branch information
mikemccracken committed Sep 26, 2024
1 parent ad93e06 commit 872badb
Showing 1 changed file with 49 additions and 3 deletions.
52 changes: 49 additions & 3 deletions squashfs/verity.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ package squashfs
// #include <errno.h>
// #include <libdevmapper.h>
/*
int get_verity_params(char *device, char **params)
int get_verity_params(char *device, char **params, int task_type)
{
struct dm_task *dmt;
struct dm_info dmi;
int r;
uint64_t start, length;
char *type, *tmpParams;
dmt = dm_task_create(DM_DEVICE_TABLE);
dmt = dm_task_create(task_type);
if (!dmt)
return 1;
Expand Down Expand Up @@ -59,6 +59,16 @@ out:
dm_task_destroy(dmt);
return r;
}
int get_verity_table_params(char *device, char **params)
{
return get_verity_params(device, params, DM_DEVICE_TABLE);
}
int get_verity_status_params(char *device, char **params)
{
return get_verity_params(device, params, DM_DEVICE_STATUS);
}
*/
import "C"

Expand Down Expand Up @@ -369,6 +379,17 @@ func HostMount(squashfs string, mountpoint string, rootHash string) error {
return err
}
}

// we have to check `dmsetup status $device` here because
// ActivateByVolumeKey will return some errors but will only WARN to
// stderr if corruption was found just after activation. It will
// reliably return success for a corrupted image, and we need to check
// the same thing it checks for its warning.
err = ConfirmExistingVerityDeviceCurrentValidity(verityDevPath, rootHash)
if err != nil {
return err

Check warning on line 390 in squashfs/verity.go

View check run for this annotation

Codecov / codecov/patch

squashfs/verity.go#L388-L390

Added lines #L388 - L390 were not covered by tests
}

} else {
loopDev, err = losetup.Attach(squashfs, 0, true)
if err != nil {
Expand Down Expand Up @@ -497,7 +518,7 @@ func ConfirmExistingVerityDeviceHash(devicePath string, rootHash string, allowVe

var cParams *C.char

rc := C.get_verity_params(cDevice, &cParams)
rc := C.get_verity_table_params(cDevice, &cParams)

Check warning on line 521 in squashfs/verity.go

View check run for this annotation

Codecov / codecov/patch

squashfs/verity.go#L521

Added line #L521 was not covered by tests
if rc != 0 {
if allowVerityFailure {
return nil
Expand All @@ -520,3 +541,28 @@ func ConfirmExistingVerityDeviceHash(devicePath string, rootHash string, allowVe

return nil
}

func ConfirmExistingVerityDeviceCurrentValidity(devicePath string, rootHash string) error {
device := filepath.Base(devicePath)
cDevice := C.CString(device)
defer C.free(unsafe.Pointer(cDevice))

Check warning on line 548 in squashfs/verity.go

View check run for this annotation

Codecov / codecov/patch

squashfs/verity.go#L545-L548

Added lines #L545 - L548 were not covered by tests

var cParams *C.char

Check warning on line 550 in squashfs/verity.go

View check run for this annotation

Codecov / codecov/patch

squashfs/verity.go#L550

Added line #L550 was not covered by tests

rc := C.get_verity_status_params(cDevice, &cParams)
if rc != 0 {
return errors.Errorf("problem getting dm params from %v: %v", device, rc)

Check warning on line 554 in squashfs/verity.go

View check run for this annotation

Codecov / codecov/patch

squashfs/verity.go#L552-L554

Added lines #L552 - L554 were not covered by tests
}
defer C.free(unsafe.Pointer(cParams))

Check warning on line 556 in squashfs/verity.go

View check run for this annotation

Codecov / codecov/patch

squashfs/verity.go#L556

Added line #L556 was not covered by tests

params := C.GoString(cParams)

Check warning on line 558 in squashfs/verity.go

View check run for this annotation

Codecov / codecov/patch

squashfs/verity.go#L558

Added line #L558 was not covered by tests

if len(params) != 1 {
return errors.Errorf("invalid params for dm status for %q: %+v", device, params)

Check warning on line 561 in squashfs/verity.go

View check run for this annotation

Codecov / codecov/patch

squashfs/verity.go#L560-L561

Added lines #L560 - L561 were not covered by tests
}
// valid values are "C": corruption has been found, or "V": no corruption found, yet.
if params != "V" {
return errors.Errorf("verity reports corruption on device %q", device)

Check warning on line 565 in squashfs/verity.go

View check run for this annotation

Codecov / codecov/patch

squashfs/verity.go#L564-L565

Added lines #L564 - L565 were not covered by tests
}
return nil

Check warning on line 567 in squashfs/verity.go

View check run for this annotation

Codecov / codecov/patch

squashfs/verity.go#L567

Added line #L567 was not covered by tests
}

0 comments on commit 872badb

Please sign in to comment.