Commit 6e42aec7 authored by Matthias Kaehlcke's avatar Matthias Kaehlcke Committed by Kees Cook
Browse files

LoadPin: Require file with verity root digests to have a header



LoadPin expects the file with trusted verity root digests to be
an ASCII file with one digest (hex value) per line. A pinned
root could contain files that meet these format requirements,
even though the hex values don't represent trusted root
digests.

Add a new requirement to the file format which consists in
the first line containing a fixed string. This prevents
attackers from feeding files with an otherwise valid format
to LoadPin.

Suggested-by: default avatarSarthak Kukreti <sarthakkukreti@chromium.org>
Signed-off-by: default avatarMatthias Kaehlcke <mka@chromium.org>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20220906181725.1.I3f51d1bb0014e5a5951be4ad3c5ad7c7ca1dfc32@changeid
parent 916ef623
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -33,4 +33,9 @@ config SECURITY_LOADPIN_VERITY
	  on the LoadPin securityfs entry 'dm-verity'. The ioctl
	  expects a file descriptor of a file with verity digests as
	  parameter. The file must be located on the pinned root and
	  contain one digest per line.
	  start with the line:

	  # LOADPIN_TRUSTED_VERITY_ROOT_DIGESTS

	  This is followed by the verity digests, with one digest per
	  line.
+15 −1
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@
#include <linux/dm-verity-loadpin.h>
#include <uapi/linux/loadpin.h>

#define VERITY_DIGEST_FILE_HEADER "# LOADPIN_TRUSTED_VERITY_ROOT_DIGESTS"

static void report_load(const char *origin, struct file *file, char *operation)
{
	char *cmdline, *pathname;
@@ -292,9 +294,21 @@ static int read_trusted_verity_root_digests(unsigned int fd)

	p = strim(data);
	while ((d = strsep(&p, "\n")) != NULL) {
		int len = strlen(d);
		int len;
		struct dm_verity_loadpin_trusted_root_digest *trd;

		if (d == data) {
			/* first line, validate header */
			if (strcmp(d, VERITY_DIGEST_FILE_HEADER)) {
				rc = -EPROTO;
				goto err;
			}

			continue;
		}

		len = strlen(d);

		if (len % 2) {
			rc = -EPROTO;
			goto err;