[Rpm-maint] [PATCH 3/4] Label ima xattr when signed files are installed

Dmitry Kasatkin d.kasatkin at samsung.com
Wed Oct 22 09:12:58 UTC 2014


On 07/10/14 23:19, fin at linux.vnet.ibm.com wrote:
> From: Fionnuala Gunter <fin at linux.vnet.ibm.com>
>
> This patch creates a new rpm-plugin for IMA and extends the rpm installer.
> When a package with signed files is installed, the file signatures are 
> extracted from the package header, and passed to the IMA plugin. The IMA 
> plugin labels the security.ima xattr with the file signature.
>
> Signed-off-by: Fionnuala Gunter <fin at linux.vnet.ibm.com>
> ---
>  lib/fsm.c           | 23 ++++++++++++++-
>  macros.in           |  1 +
>  plugins/Makefile.am |  4 +++
>  plugins/ima.c       | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 110 insertions(+), 1 deletion(-)
>  create mode 100644 plugins/ima.c
>
> diff --git a/lib/fsm.c b/lib/fsm.c
> index e7c2a3b..dbeeaab 100644
> --- a/lib/fsm.c
> +++ b/lib/fsm.c
> @@ -20,6 +20,7 @@
>  #include "lib/rpmte_internal.h"	/* XXX rpmfs */
>  #include "lib/rpmplugins.h"	/* rpm plugins hooks */
>  #include "lib/rpmug.h"
> +#include "lib/rpmlib.h"
>  
>  #include "debug.h"
>  
> @@ -823,12 +824,22 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
>      char *tid = NULL;
>      const char *suffix;
>      char *fpath = NULL;
> +    Header h = rpmteHeader(te);
> +    struct rpmtd_s sigs;
> +    char *sig = NULL;
>  
>      if (fi == NULL) {
>  	rc = RPMERR_BAD_MAGIC;
>  	goto exit;
>      }
>  
> +    if (h == NULL) {
> +	rc = RPMRC_FAIL;
> +	goto exit;
> +    }
> +
> +    headerGet(h, RPMTAG_FILESIGNATURES, &sigs, HEADERGET_MINMEM);
> +
>      /* transaction id used for temporary path suffix while installing */
>      rasprintf(&tid, ";%08x", (unsigned)rpmtsGetTid(ts));
>  
> @@ -953,9 +964,17 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
>  	if (rc)
>  	    *failedFile = xstrdup(fpath);
>  
> +	/* get file signatures from header */
> +	if (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) {
> +	    sig = rpmtdNextString(&sigs);

What executable bit means?

> +	} else {
> +	    sig = NULL;
> +	    rpmtdNextString(&sigs);
> +	}
> +
>  	/* Run fsm file post hook for all plugins */
>  	rpmpluginsCallFsmFilePost(plugins, fi, fpath,
> -				  sb.st_mode, action, NULL, rc);
> +				  sb.st_mode, action, sig, rc);
>  	fpath = _free(fpath);
>      }
>  
> @@ -965,6 +984,8 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
>  exit:
>  
>      /* No need to bother with close errors on read */
> +    rpmtdFreeData(&sigs);
> +    headerFree(h);
>      rpmfiArchiveClose(fi);
>      rpmfiFree(fi);
>      Fclose(payload);
> diff --git a/macros.in b/macros.in
> index 1647104..0b62991 100644
> --- a/macros.in
> +++ b/macros.in
> @@ -1043,6 +1043,7 @@ done \
>  %__transaction_systemd_inhibit	%{__plugindir}/systemd_inhibit.so
>  %__transaction_selinux		%{__plugindir}/selinux.so
>  %__transaction_syslog		%{__plugindir}/syslog.so
> +%__transaction_ima		%{__plugindir}/ima.so
>  
>  #------------------------------------------------------------------------------
>  # Macros for further automated spec %setup and patch application
> diff --git a/plugins/Makefile.am b/plugins/Makefile.am
> index 53b2450..18f6170 100644
> --- a/plugins/Makefile.am
> +++ b/plugins/Makefile.am
> @@ -31,3 +31,7 @@ endif
>  syslog_la_SOURCES = syslog.c
>  syslog_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la
>  plugins_LTLIBRARIES += syslog.la
> +
> +ima_la_sources = ima.c
> +ima_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la
> +plugins_LTLIBRARIES +=  ima.la
> diff --git a/plugins/ima.c b/plugins/ima.c
> new file mode 100644
> index 0000000..6b739db
> --- /dev/null
> +++ b/plugins/ima.c
> @@ -0,0 +1,83 @@
> +/**
> + * Copyright (C) 2014 IBM Corporation
> + *
> + * Author: Fionnuala Gunter <fin at linux.vnet.ibm.com>
> + */
> +#include <syslog.h>
> +
> +#include <sys/types.h>
> +#include <sys/xattr.h>
> +#include <rpm/rpmts.h>
> +#include <rpm/rpmlog.h>
> +#include <lib/rpmplugin.h>
> +#include <errno.h>
> +#include <ctype.h>
> +
> +#include "debug.h"
> +
> +#define XATTR_NAME_IMA "security.ima"
> +
> +static int hex_to_bin(char ch)
> +{
> +	if ((ch >= '0') && (ch <= '9'))
> +		return ch - '0';
> +	ch = tolower(ch);
> +	if ((ch >= 'a') && (ch <= 'f'))
> +		return ch - 'a' + 10;
> +	return -1;
> +}
> +
> +static int hex2bin(char *dst, const char *src, size_t count)
> +{

Does not RPM has any hex conversion facilities yet?
It has digests. Does not it uses it somehow?

- Dmitry

> +	int hi, lo;
> +
> +	while (count--) {
> +		if (*src == ' ')
> +			src++;
> +
> +		hi = hex_to_bin(*src++);
> +		lo = hex_to_bin(*src++);
> +
> +		if ((hi < 0) || (lo < 0))
> +			return -1;
> +
> +		*dst++ = (hi << 4) | lo;
> +        }
> +	return 0;
> +}
> +
> +static rpmRC ima_init(rpmPlugin plugin, rpmts ts)
> +{
> +	return RPMRC_OK;
> +}
> +
> +static void ima_cleanup(rpmPlugin plugin)
> +{
> +}
> +
> +static rpmRC ima_fsm_file_post(rpmPlugin plugin, rpmfi fi, const char *path,
> +                               mode_t file_mode, rpmFsmOp op, const char *sig,
> +                               int res)
> +{
> +	rpmRC rc = RPMRC_OK;
> +	if (sig == NULL) {
> +		return rc;
> +	}
> +
> +	int siglen = strlen(sig) + 1;
> +	char bin[siglen/2];
> +	hex2bin(bin, sig, siglen);
> +	rc = lsetxattr(path, XATTR_NAME_IMA, bin, siglen/2, 0);
> +
> +	if (rpmIsDebug())
> +		rpmlog(RPMLOG_DEBUG, "lsetxattr: (%s) %s\n",
> +			path, (rc < 0 ? strerror(errno) : ""));
> +
> +	return rc;
> +}
> +
> +struct rpmPluginHooks_s ima_hooks = {
> +	.init = ima_init,
> +	.cleanup = ima_cleanup,
> +	.fsm_file_post = ima_fsm_file_post,
> +};



More information about the Rpm-maint mailing list