Skip to content

Commit

Permalink
verity: check after activation for any corruption (#18)
Browse files Browse the repository at this point in the history
* verity: check after activation for any corruption

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]>

* verity: also check corruption in existing mounts

If we are mounting a mol where one of the atoms already been mounted,
then we should check the already-mounted devices for any corruption
reported by devicemapper as well, and at least fail to mount the new
image using them.

Signed-off-by: Michael McCracken <[email protected]>

---------

Signed-off-by: Michael McCracken <[email protected]>
  • Loading branch information
mikemccracken authored Sep 28, 2024
1 parent 08706c7 commit 820120d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
4 changes: 4 additions & 0 deletions molecule.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ func (m Molecule) mountUnderlyingAtoms() error {
if err != nil {
return err
}
err = squashfs.ConfirmExistingVerityDeviceCurrentValidity(mountpoint.Source)
if err != nil {
return err
}
}
continue
}
Expand Down
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)
if err != nil {
return err
}

} 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)
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) error {
device := filepath.Base(devicePath)
cDevice := C.CString(device)
defer C.free(unsafe.Pointer(cDevice))

var cParams *C.char

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

params := C.GoString(cParams)

if len(params) != 1 {
return errors.Errorf("invalid params for dm status for %q: %+v", device, params)
}
// 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)
}
return nil
}

0 comments on commit 820120d

Please sign in to comment.