Hello all, I am trying to get the minimal bits and pieces into place for allowing us to start using file capabilties.
Currently, rpm neither supports acls nor file capabilities [1], and so when they are needed, the usual way is to set them in the %post script. This works, but unfortunately rpm then cannot --verify that a file has the right permissions and capabilities attached. In am not aware of any cases where acls would actually be needed for packaged files, so I think that we can safely leave acl support out of rpm for now. It would be nice to check for acls in --verify, though. With file capabilities, things are different: distributions are going to start using them instead of suid root binaries, and perhaps to run some daemons with fewer privileges. The number of packages using capabilities won't be huge, but sure more than a hand full. I believe that full capability support in rpm would be very useful. I am not familiar enough with the rpm codebase, and I don't think I can implement full file capability support efficiently. Nevertheless, rpm can meanwhile at least make sure in --verify that no files have capabilities attached. To allow turning this check off, a new %verify file list flag and a new --nocaps command line option seems to make sense for me. The attached two patches against (our version of) rpm-4.4.2 do the following: verify-acls.diff In --verify, also check for POSIX ACLs as part of the mode checks, and complain if any are found. verify-file-capabilities.diff Introduce a new "caps" %verify flag, and allocate a flag for it. Introduce a new --nocaps command line option. In --verify, also check for the presence of file capabilities, and complain if any are found. Use "P" as the indicator letter in the --verify output (in a new column). What do you think -- do these patches look acceptable? Thanks, Andreas [1] http://ols.fedoraproject.org/OLS/Reprints-2008/hallyn-reprint.pdf -- Andreas Gruenbacher <[EMAIL PROTECTED]>, SUSE Labs
Index: lib/verify.c =================================================================== --- lib/verify.c.orig +++ lib/verify.c @@ -5,6 +5,8 @@ #include "system.h" +#include <sys/xattr.h> + #include <rpmcli.h> #include "psm.h" @@ -203,6 +205,16 @@ int rpmVerifyFile(const rpmts ts, const *res |= RPMVERIFY_MODE; } + if (flags & RPMVERIFY_MODE) { + ssize_t size; + + size = getxattr(fn, "system.posix_acl_access", NULL, 0); + if (size <= 0 && S_ISDIR(sb.st_mode)) + size = getxattr(fn, "system.posix_acl_default", NULL, 0); + if (size > 0) + *res |= RPMVERIFY_MODE; + } + if (flags & RPMVERIFY_RDEV) { if (S_ISCHR(fmode) != S_ISCHR(sb.st_mode) || S_ISBLK(fmode) != S_ISBLK(sb.st_mode))
Index: lib/poptQV.c =================================================================== --- lib/poptQV.c.orig +++ lib/poptQV.c @@ -333,6 +333,9 @@ struct poptOption rpmVerifyPoptTable[] = { "nordev", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &rpmQVKArgs.qva_flags, VERIFY_RDEV, N_("don't verify mode of files"), NULL }, + { "nocaps", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, + &rpmQVKArgs.qva_flags, VERIFY_CAPS, + N_("don't verify capabilities of files"), NULL }, { "nocontexts", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL, RPMCLI_POPT_NOCONTEXTS, N_("don't verify file security contexts"), NULL }, Index: lib/rpmcli.h =================================================================== --- lib/rpmcli.h.orig +++ lib/rpmcli.h @@ -130,7 +130,8 @@ typedef enum rpmVerifyAttrs_e { RPMVERIFY_MTIME = (1 << 5), /*!< from %verify(mtime) */ RPMVERIFY_MODE = (1 << 6), /*!< from %verify(mode) */ RPMVERIFY_RDEV = (1 << 7), /*!< from %verify(rdev) */ - /* bits 8-14 unused, reserved for rpmVerifyAttrs */ + RPMVERIFY_CAPS = (1 << 8), /*!< from %verify(caps) */ + /* bits 9-14 unused, reserved for rpmVerifyAttrs */ RPMVERIFY_CONTEXTS = (1 << 15), /*!< verify: from --nocontexts */ /* bits 16-22 used in rpmVerifyFlags */ /* bits 23-27 used in rpmQueryFlags */ @@ -201,7 +202,8 @@ typedef enum rpmVerifyFlags_e { VERIFY_MTIME = (1 << 5), /*!< from --nomtime */ VERIFY_MODE = (1 << 6), /*!< from --nomode */ VERIFY_RDEV = (1 << 7), /*!< from --nodev */ - /* bits 8-14 unused, reserved for rpmVerifyAttrs */ + VERIFY_CAPS = (1 << 8), /*!< from --nocaps */ + /* bits 9-14 unused, reserved for rpmVerifyAttrs */ VERIFY_CONTEXTS = (1 << 15), /*!< verify: from --nocontexts */ VERIFY_FILES = (1 << 16), /*!< verify: from --nofiles */ VERIFY_DEPS = (1 << 17), /*!< verify: from --nodeps */ @@ -222,7 +224,7 @@ typedef enum rpmVerifyFlags_e { #define VERIFY_ATTRS \ ( VERIFY_MD5 | VERIFY_SIZE | VERIFY_LINKTO | VERIFY_USER | VERIFY_GROUP | \ - VERIFY_MTIME | VERIFY_MODE | VERIFY_RDEV | VERIFY_CONTEXTS ) + VERIFY_MTIME | VERIFY_MODE | VERIFY_RDEV | VERIFY_CAPS | VERIFY_CONTEXTS ) #define VERIFY_ALL \ ( VERIFY_ATTRS | VERIFY_FILES | VERIFY_DEPS | VERIFY_SCRIPT | VERIFY_DIGEST |\ VERIFY_SIGNATURE | VERIFY_HDRCHK ) Index: lib/verify.c =================================================================== --- lib/verify.c.orig +++ lib/verify.c @@ -228,6 +228,14 @@ int rpmVerifyFile(const rpmts ts, const } } + if (flags & RPMVERIFY_CAPS) { + ssize_t size; + + size = getxattr(fn, "security.capability", NULL, 0); + if (size > 0) + *res |= RPMVERIFY_CAPS; + } + if (flags & RPMVERIFY_MTIME) { if (sb.st_mtime != rpmfiFMtime(fi)) *res |= RPMVERIFY_MTIME; @@ -347,7 +355,7 @@ static int verifyHeader(QVA_t qva, const } } else if (verifyResult || rpmIsVerbose()) { const char * size, * MD5, * link, * mtime, * mode; - const char * group, * user, * rdev, *ctxt; + const char * group, * user, * rdev, *caps, *ctxt; /[EMAIL PROTECTED]@*/ static const char *const aok = "."; /[EMAIL PROTECTED]@*/ static const char *const unknown = "?"; /[EMAIL PROTECTED]@*/ static const char *const ctxt_ignore = " "; @@ -375,6 +383,7 @@ static int verifyHeader(QVA_t qva, const user = _verify(RPMVERIFY_USER, "U"); group = _verify(RPMVERIFY_GROUP, "G"); mode = _verify(RPMVERIFY_MODE, "M"); + caps = _verify(RPMVERIFY_CAPS, "P"); ctxt = _verifyctxt(RPMVERIFY_CONTEXTS, "C"); #undef _verifyctxt @@ -382,8 +391,9 @@ static int verifyHeader(QVA_t qva, const #undef _verifylink #undef _verify - sprintf(te, "%s%s%s%s%s%s%s%s%s %c %s", - size, mode, MD5, rdev, link, user, group, mtime, ctxt, + sprintf(te, "%s%s%s%s%s%s%s%s%s%s %c %s", + size, mode, MD5, rdev, link, user, group, mtime, caps, + ctxt, ((fileAttrs & RPMFILE_CONFIG) ? 'c' : (fileAttrs & RPMFILE_DOC) ? 'd' : (fileAttrs & RPMFILE_GHOST) ? 'g' : Index: doc/rpm.8 =================================================================== --- doc/rpm.8.orig +++ doc/rpm.8 @@ -93,6 +93,7 @@ rpm \- RPM Package Manager [\fB--nodigest\fR] [\fB--nosignature\fR] [\fB--nolinkto\fR] [\fB--nomd5\fR] [\fB--nosize\fR] [\fB--nouser\fR] [\fB--nogroup\fR] [\fB--nomtime\fR] [\fB--nomode\fR] [\fB--nordev\fR] + [\fB--nocaps\fR] .SS "install-options" .PP @@ -708,6 +709,8 @@ Don't verify package or header signature \fB--nomode\fR .TP \fB--nordev\fR +.TP +\fB--nocaps\fR Don't verify the corresponding file attribute. .PP The format of the output is a string of 8 characters, a possible @@ -742,6 +745,7 @@ the corresponding \fB--verify\fR test: \fBU\fR \fBU\fRser ownership differs \fBG\fR \fBG\fRroup ownership differs \fBT\fR m\fBT\fRime differs +\fBP\fR ca\fBP\fRabilities differ .fi .SS "DIGITAL SIGNATURE AND DIGEST VERIFICATION" Index: build/files.c =================================================================== --- build/files.c.orig +++ build/files.c @@ -313,6 +313,7 @@ VFA_t verifyAttrs[] = { { "mtime", 0, RPMVERIFY_MTIME }, { "mode", 0, RPMVERIFY_MODE }, { "rdev", 0, RPMVERIFY_RDEV }, + { "caps", 0, RPMVERIFY_CAPS }, { NULL, 0, 0 } }; /[EMAIL PROTECTED] [EMAIL PROTECTED]/
_______________________________________________ Rpm-maint mailing list Rpm-maint@lists.rpm.org https://lists.rpm.org/mailman/listinfo/rpm-maint