[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