[Rpm-maint] Re: ACL and File Capability Support in RPM

Serge E. Hallyn serue at us.ibm.com
Tue Sep 2 18:53:16 UTC 2008


Quoting Andreas Gruenbacher (agruen at suse.de):
> 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?

It seems reasonable.  Of course people manually using file capabilities 
will get annoying warnings, but given how serious stray file caps would
be it seems worthwhile.

Hopefully someone will implement full capabilities support for rpm
soon  :)  Alas, like yourself, I'm very unfamiliar with the code (heck,
with rpm itself).  If someone with more rpm familiarity wants to give
it a shot, but would like some help, please don't hesitate to email me.

thanks,
-serge

> Thanks,
> Andreas
> 
> [1] http://ols.fedoraproject.org/OLS/Reprints-2008/hallyn-reprint.pdf
> 
> -- 
> Andreas Gruenbacher <agruen at suse.de>, 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;
>  	    /*@observer@*/ static const char *const aok = ".";
>  	    /*@observer@*/ static const char *const unknown = "?";
>  	    /*@observer@*/ 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 }
>  };
>  /*@=exportlocal =exportheadervar@*/




More information about the Rpm-maint mailing list