[Rpm-maint] [PATCH 5/5] Fix handling of zero-length file digests

Stefan Berger stefanb at linux.vnet.ibm.com
Mon Apr 25 22:33:31 UTC 2016


From: Stefan Berger <stefanb at us.ibm.com>

Do not try to convert a zero-length file digest to a binary representation.
Zero-length file digests may stem from directory entries and symbolic links.
Return an empty signature in this case.

Returning an empty signature results in the ima.so plugin getting a sequence
of zeroes that it would write into security.ima xattr. Check for a signature
consisting of only zeroes and do not write it into the filesystem.

Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
---
 lib/rpmsignfiles.c |  4 ++++
 plugins/ima.c      | 36 +++++++++++++++++++++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/lib/rpmsignfiles.c b/lib/rpmsignfiles.c
index 97a5be4..3cd2b1a 100644
--- a/lib/rpmsignfiles.c
+++ b/lib/rpmsignfiles.c
@@ -82,6 +82,10 @@ const char *key, char *keypass)
 
     /* convert file digest hex to binary */
     memset(digest, 0, diglen);
+    /* some entries don't have a digest - we return an empty signature */
+    if (strlen(fdigest) != diglen * 2)
+        return strdup("");
+
     for (int i = 0; i < diglen; ++i, fdigest += 2)
 	digest[i] = (rnibble(fdigest[0]) << 4) | rnibble(fdigest[1]);
 
diff --git a/plugins/ima.c b/plugins/ima.c
index 0dfdd8b..2b998d0 100644
--- a/plugins/ima.c
+++ b/plugins/ima.c
@@ -12,6 +12,40 @@
 
 #define XATTR_NAME_IMA "security.ima"
 
+/* security.ima signature header */
+struct signature_v2_hdr {
+	uint8_t type;
+	uint8_t version;
+	uint8_t hash_algo;
+	uint32_t keyid;
+	uint16_t sig_size;
+	uint8_t sig[0];
+} __attribute__((PACKED));
+
+static const struct signature_v2_hdr zero_hdr = {
+	.type = 0,
+	.version = 0,
+	.hash_algo = 0,
+	.keyid = 0,
+	.sig_size = 0,
+};
+
+/*
+ * check_zero_hdr: Check the signature for a zero header
+ *
+ * Check whether the given signature has a header with all zeros
+ *
+ * Returns -1 in case the signature is too short to compare
+ * (invalid signature), 0 in case the header is not only zeroes,
+ * and 1 if it is only zeroes.
+ */
+static int check_zero_hdr(const unsigned char *fsig, size_t siglen)
+{
+	if (siglen < sizeof(zero_hdr))
+		return -1;
+	return (memcmp(fsig, &zero_hdr, sizeof(zero_hdr)) == 0);
+}
+
 static rpmRC ima_psm_post(rpmPlugin plugin, rpmte te, int res)
 {
 	rpmfi fi = rpmteFI(te);
@@ -30,7 +64,7 @@ static rpmRC ima_psm_post(rpmPlugin plugin, rpmte te, int res)
 	    if (!(rpmfiFFlags(fi) & RPMFILE_CONFIG)) {
 		fpath = rpmfiFN(fi);
 		fsig = rpmfiFSignature(fi, &len);
-		if (fsig) {
+		if (fsig && (check_zero_hdr(fsig, len) == 0)) {
 		    lsetxattr(fpath, XATTR_NAME_IMA, fsig, len, 0);
 		}
 	    }
-- 
2.5.5



More information about the Rpm-maint mailing list