[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