[Rpm-maint] [PATCH 17/18] Add hook for verifying policy modules

Steve Lawrence slawrence at tresys.com
Wed Dec 23 20:57:37 UTC 2009


In the current state, there is no verification that a file specified with
the %module tag is actually a policy module. This patch adds an rpmbuild
hook that can be used to perform module verification. A %__check_policies
macro has been added which can point to a script/executable that performs
module validation at rpmbuild time. The patch also adds a simple script,
check-policies, that checks the magic number of modules to ensure that they
are valid modules. Similar to the check-files script, the check-policies
script takes a list of files on stdin and echos any files that are not
valid modules to stdout.
---
 build/policies.c       |   59 +++++++++++++++++++++++++++++++++++++++++++++++-
 macros.in              |    2 +
 scripts/Makefile.am    |    4 +-
 scripts/check-policies |   49 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 111 insertions(+), 3 deletions(-)
 create mode 100755 scripts/check-policies

diff --git a/build/policies.c b/build/policies.c
index fbd8c8f..b4a1f68 100644
--- a/build/policies.c
+++ b/build/policies.c
@@ -9,6 +9,7 @@
 #include <rpm/argv.h>
 #include <rpm/rpmlog.h>
 #include <rpm/rpmpol.h>
+#include <rpm/rpmfc.h>
 
 #include "rpmio/rpmio_internal.h"
 #include "rpmio/base64.h"
@@ -18,6 +19,8 @@
 #define SKIPSPACE(s)    { while ((s) && *(s) &&  risspace(*(s))) (s)++; }
 #define SKIPNONSPACE(s) { while ((s) && *(s) && !risspace(*(s))) (s)++; }
 
+static StringBuf check_policyList = NULL;
+
 typedef struct ModuleRec_s {
 	char *path;
 	char *name;
@@ -234,6 +237,12 @@ static rpmRC writeModuleToHeader(ModuleRec mod, Package pkg)
 		headerPutUint32(pkg->header, RPMTAG_POLICYOBSOLETESBY, &count, 1);
 	}
 
+	/* add module to list of modules to check */
+	if (check_policyList) {
+		appendStringBuf(check_policyList, mod->path);
+		appendStringBuf(check_policyList, "\n");
+	}
+
 	rc = RPMRC_OK;
 
 exit:
@@ -457,6 +466,47 @@ exit:
 
 }
 
+/**
+ * Check packaged policies.
+ * @param fileList	packaged policy list
+ * @return		RPMRC_OK if all policies are ok, RPMRC_FAIL otherwise
+ */
+static int checkPolicies(StringBuf policyList)
+{
+	static char *const av_ckpolicy[] = { "%{?__check_policies}", NULL };
+	StringBuf sb_stdout = NULL;
+	char *s;
+	int ret;
+	int rc = RPMRC_FAIL;
+
+	s = rpmExpand(av_ckpolicy[0], NULL);
+	if (!(s && *s)) {
+		goto exit;
+	}
+
+	rpmlog(RPMLOG_NOTICE, _("Checking policy module(s): %s\n"), s);
+
+	ret = rpmfcExec(av_ckpolicy, policyList, &sb_stdout, 0);
+	if (ret < 0) {
+		goto exit;
+	}
+
+	if (sb_stdout) {
+		const char *t = getStringBuf(sb_stdout);
+		if ((*t != '\0') && (*t != '\n')) {
+			rpmlog(RPMLOG_ERR, _("Invalid policy module(s) found:\n%s"), t);
+			goto exit;
+		}
+	}
+
+	rc = RPMRC_OK;
+
+exit:
+	sb_stdout = freeStringBuf(sb_stdout);
+	s = _free(s);
+	return rc;
+}
+
 static rpmRC processPolicies(rpmSpec spec, Package pkg, int test)
 {
 	ARGV_t policies = NULL;
@@ -513,6 +563,8 @@ int processBinaryPolicies(rpmSpec spec, int test)
 	int rc = RPMRC_OK;
 	char *nvr;
 
+	check_policyList = newStringBuf();
+
 	for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
 		if (pkg->policyList == NULL) {
 			continue;
@@ -524,10 +576,15 @@ int processBinaryPolicies(rpmSpec spec, int test)
 
 		if (processPolicies(spec, pkg, test) != RPMRC_OK) {
 			rc = RPMRC_FAIL;
-			break;
+			goto exit;
 		}
 	}
 
+	rc = checkPolicies(check_policyList);
+
+exit:
+	check_policyList = freeStringBuf(check_policyList);
+
 	return rc;
 }
 
diff --git a/macros.in b/macros.in
index eee35d0..1f7303d 100644
--- a/macros.in
+++ b/macros.in
@@ -370,6 +370,8 @@ package or when debugging this package.\
 # Note: Disable (by commenting out) for legacy compatibility.
 %__check_files         %{_rpmconfigdir}/check-files %{buildroot}
 
+%__check_policies      %{_rpmconfigdir}/check-policies %{_builddir}/%{?buildsubdir}/
+
 #
 # Should unpackaged files in a build root terminate a build?
 #
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 25d5e36..1f14f6c 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -8,7 +8,7 @@ EXTRA_DIST = \
 	brp-compress brp-python-bytecompile brp-java-gcjcompile \
 	brp-strip brp-strip-comment-note \
 	brp-strip-shared brp-strip-static-archive \
-	check-files check-prereqs \
+	check-files check-policies check-prereqs \
 	check-buildroot check-rpaths check-rpaths-worker \
 	find-debuginfo.sh find-lang.sh \
 	perldeps.pl perl.prov perl.req pythondeps.sh osgideps.pl \
@@ -26,7 +26,7 @@ rpmconfig_SCRIPTS = \
 	brp-compress brp-python-bytecompile brp-java-gcjcompile \
 	brp-strip brp-strip-comment-note \
 	brp-strip-shared brp-strip-static-archive \
-	check-files check-prereqs \
+	check-files check-policies check-prereqs \
 	check-buildroot check-rpaths check-rpaths-worker \
 	find-lang.sh \
 	perl.prov perl.req perldeps.pl pythondeps.sh osgideps.pl \
diff --git a/scripts/check-policies b/scripts/check-policies
new file mode 100755
index 0000000..c79ae5a
--- /dev/null
+++ b/scripts/check-policies
@@ -0,0 +1,49 @@
+#!/bin/sh
+# Gets list of policy files on standard input and RPM_BUILD_DIR
+# as first parameter and validates policy files
+# Returns it's output on standard output.
+
+RPM_BUILD_DIR=$1
+if [ ! -d "$RPM_BUILD_DIR" ] ; then
+	cat > /dev/null
+	exit 1
+fi
+
+MAGIC_PP="0xf97cff8f"
+
+[ "$TMPDIR" ] || TMPDIR=/tmp
+BUNZIP_FILE=`mktemp $TMPDIR/rpmXXXXXX`
+
+while read FILE
+do
+	FILEPATH="$RPM_BUILD_DIR/$FILE"
+
+	if [ ! -s "$FILEPATH" ]
+	then
+		echo "$FILEPATH"
+		continue
+	fi
+
+	bzip2 --decompress --stdout "$FILEPATH" > "$BUNZIP_FILE" 2> /dev/null
+	if [ "$?" -ne "0" ]
+	then
+		PPFILE="$FILEPATH" # assume original file is not compressed
+	else
+		PPFILE="$BUNZIP_FILE"
+	fi
+
+	if [ ! -s "$PPFILE" ]
+	then
+		echo "$FILEPATH"
+		continue
+	fi
+
+	MAGIC=`od -An -tx4 -N4 "$PPFILE" | sed 's/ //g'`
+	if [ "0x$MAGIC" != "$MAGIC_PP" ]
+	then
+		echo "$FILEPATH"
+		continue
+	fi
+done
+
+rm -f $BUNZIP_FILE
-- 
1.6.0.6



More information about the Rpm-maint mailing list