diff --git a/CheckSUIDPermissions.py b/CheckSUIDPermissions.py index b820ef7..584af6a 100644 --- a/CheckSUIDPermissions.py +++ b/CheckSUIDPermissions.py @@ -11,6 +11,7 @@ import AbstractCheck import re import os import string +import rpm _permissions_d_whitelist = ( "lprng", @@ -37,15 +38,34 @@ class SUIDCheck(AbstractCheck.AbstractCheck): self._parsefile(file) def _parsefile(self,file): + lnr = 0 + lastfn = None for line in open(file): + lnr+=1 line = line.split('#')[0].split('\n')[0] - if len(line): - line = re.split(r'\s+', line) + line = line.lstrip() + if not len(line): + continue + + if line.startswith("+capabilities "): + line = line[len("+capabilities "):] + if lastfn: + self.perms[lastfn]['fscaps'] = line + continue + + line = re.split(r'\s+', line) + if len(line) == 3: fn = line[0] owner = line[1].replace('.', ':') mode = line[2] self.perms[fn] = { "owner" : owner, "mode" : int(mode,8)&07777} + # for permissions that don't change and therefore + # don't need special handling + if file == '/etc/permissions': + self.perms[fn]['static'] = True + else: + print >>sys.stderr, "invalid line %d " % lnr def check(self, pkg): global _permissions_d_whitelist @@ -78,10 +98,16 @@ class SUIDCheck(AbstractCheck.AbstractCheck): else: self._parsefile(f) + need_run_permissions = False # second pass, find permissions violations for f, pkgfile in files.items(): if f in pkg.ghostFiles(): continue + + if pkgfile.filecaps: + printError(pkg, 'permissions-fscaps', '%(file)s has fscaps "%(caps)s"' % \ + { 'file':f, 'caps':pkgfile.filecaps}) + mode = pkgfile.mode owner = pkgfile.user+':'+pkgfile.group @@ -94,11 +120,14 @@ class SUIDCheck(AbstractCheck.AbstractCheck): # S_IFIFO 001 FIFO type = (mode>>12)&017; mode &= 07777 + need_verifyscript = False if f in self.perms or (type == 04 and f+"/" in self.perms): if type == 012: printWarning(pkg, "permissions-symlink", f) continue + need_verifyscript = True + m = 0 o = "invalid" if type == 04: @@ -124,6 +153,7 @@ class SUIDCheck(AbstractCheck.AbstractCheck): printWarning(pkg, 'permissions-file-as-dir', f+' is a file but listed as directory') if mode&06000: + need_verifyscript = True msg = '%(file)s is packaged with setuid/setgid bits (0%(mode)o)' % { 'file':f, 'mode':mode } if type != 04: printError(pkg, 'permissions-file-setuid-bit', msg) @@ -131,10 +161,29 @@ class SUIDCheck(AbstractCheck.AbstractCheck): printWarning(pkg, 'permissions-directory-setuid-bit', msg) if mode&02: + need_verifyscript = True printError(pkg, 'permissions-world-writable', \ '%(file)s is packaged with world writable permissions (0%(mode)o)' % \ { 'file':f, 'mode':mode }) + if need_verifyscript and \ + (not f in self.perms or not 'static' in self.perms[f]): + need_run_permissions = True + script = pkg[rpm.RPMTAG_VERIFYSCRIPT] or pkg[rpm.RPMTAG_VERIFYSCRIPTPROG] + if not script or not "chkstat -n -e %s"%f in script: + printError(pkg, 'permissions-missing-verifyscript', \ + "missing %%verify_permissions -e %s" % f) + + if need_run_permissions: + postin = pkg[rpm.RPMTAG_POSTIN] or pkg[rpm.RPMTAG_POSTINPROG] + if not postin or not "SuSEconfig --module permissions" in postin: + printError(pkg, 'permissions-missing-postin', \ + "missing %run_permissions in %post") + + if not 'permissions' in map(lambda x: x[0], pkg.prereq()): + printError(pkg, 'permissions-missing-requires', \ + "missing 'permissions' in PreReq") + check=SUIDCheck() @@ -171,4 +220,15 @@ security team""", """If the package is intended for inclusion in any SUSE product please open a bug report to request review of the package by the security team""", +'permissions-fscaps', +"""Packaging file capabilities is currently not supported. Please +use normal permissions instead. You may contact the security team to +request an entry that sets capabilities in /etc/permissions +instead.""", +'permissions-missing-postin', +"""Please add %run_permissions to %post""", +'permissions-missing-requires', +"""Please add \"PreReq: permissions\"""", +'permissions-missing-verifyscript', +"""Please add a %verifyscript section""", ) diff --git a/rpmlint-0.99.tar.bz2 b/rpmlint-0.99.tar.bz2 deleted file mode 100644 index 7eda010..0000000 --- a/rpmlint-0.99.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:452c65f114d445051c400d1a57e48061609fe2946dccda6d3ac52ffa425d2808 -size 123463 diff --git a/rpmlint-1.0.tar.bz2 b/rpmlint-1.0.tar.bz2 new file mode 100644 index 0000000..2cec432 --- /dev/null +++ b/rpmlint-1.0.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:504ea4212812993b19de3e12dffb9bbe0cd9dac9e46f7c55760428f1bc77b814 +size 123667 diff --git a/rpmlint-fscaps.diff b/rpmlint-fscaps.diff new file mode 100644 index 0000000..d5ba2ee --- /dev/null +++ b/rpmlint-fscaps.diff @@ -0,0 +1,44 @@ +From 1300bf63e4f5e345329b040e3ccd982c02ee35bd Mon Sep 17 00:00:00 2001 +From: Ludwig Nussel +Date: Wed, 3 Nov 2010 16:57:00 +0100 +Subject: [PATCH] make file capabilities available in PkgFile + +--- + Pkg.py | 7 +++++++ + 1 files changed, 7 insertions(+), 0 deletions(-) + +diff --git a/Pkg.py b/Pkg.py +index 73bd0ba..a2c864d 100644 +--- a/Pkg.py ++++ b/Pkg.py +@@ -603,6 +603,10 @@ class Pkg: + provides = self.header[rpm.RPMTAG_FILEPROVIDE] + files = self.header[rpm.RPMTAG_FILENAMES] + magics = self.header[rpm.RPMTAG_FILECLASS] ++ try: ++ filecaps = self.header[rpm.RPMTAG_FILECAPS] ++ except: ++ filecaps = None + + # rpm-python < 4.6 does not return a list for this (or FILEDEVICES, + # FWIW) for packages containing exactly one file +@@ -629,6 +633,8 @@ class Pkg: + pkgfile.requires = parse_deps(requires[idx]) + pkgfile.provides = parse_deps(provides[idx]) + pkgfile.lang = langs[idx] ++ if filecaps: ++ pkgfile.filecaps = filecaps[idx] + pkgfile.magic = magics[idx] + if not pkgfile.magic and _magic: + pkgfile.magic = _magic.file(pkgfile.path) +@@ -806,6 +812,7 @@ class PkgFile(object): + self.provides = [] + self.lang = '' + self.magic = '' ++ self.filecaps = None + + # TODO: decompression support + +-- +1.7.1 + diff --git a/rpmlint.changes b/rpmlint.changes index f282f8b..8a083e3 100644 --- a/rpmlint.changes +++ b/rpmlint.changes @@ -1,3 +1,21 @@ +------------------------------------------------------------------- +Thu Nov 4 14:20:41 UTC 2010 - lnussel@suse.de + +- enable suse-hide-unstripped-outside-build.diff again + +------------------------------------------------------------------- +Thu Nov 4 13:35:33 UTC 2010 - lnussel@suse.de + +- check for file system capabilities +- check for %verifyscript and %run_permissions + +------------------------------------------------------------------- +Wed Nov 3 10:48:30 CET 2010 - dmueller@suse.de + +- update to 1.0: + * add support for PEP 3147 when handling python bytecode + * various doc improvements + ------------------------------------------------------------------- Fri Oct 29 07:23:39 UTC 2010 - lnussel@suse.de diff --git a/rpmlint.spec b/rpmlint.spec index 9dcc432..ccf0ce5 100644 --- a/rpmlint.spec +++ b/rpmlint.spec @@ -22,8 +22,8 @@ Name: rpmlint BuildRequires: rpm-python Summary: Rpm correctness checker -Version: 0.99 -Release: 5 +Version: 1.0 +Release: 1 Source0: %{name}-%{version}.tar.bz2 Source1: config Source1001: config.in @@ -117,6 +117,7 @@ Patch75: stricter-interpreter-check.diff Patch76: confusing-invalid-spec-name.patch Patch77: rpmlint-pkg-quoting.diff Patch78: suse-g-ir-chech.diff +Patch79: rpmlint-fscaps.diff %py_requires %description @@ -148,7 +149,7 @@ Authors: %patch13 %patch14 %patch17 -#%patch18 +%patch18 %patch19 %patch20 %patch22 @@ -190,6 +191,7 @@ Authors: %patch76 -p1 %patch77 %patch78 +%patch79 -p1 cp -p %{SOURCE1} . cp -p %{SOURCE2} . cp -p %{SOURCE3} . diff --git a/suse-hide-unstripped-outside-build.diff b/suse-hide-unstripped-outside-build.diff index d93a329..88f677e 100644 --- a/suse-hide-unstripped-outside-build.diff +++ b/suse-hide-unstripped-outside-build.diff @@ -1,4 +1,6 @@ ---- BinariesCheck.py +Index: BinariesCheck.py +=================================================================== +--- BinariesCheck.py.orig +++ BinariesCheck.py @@ -10,6 +10,7 @@ @@ -8,18 +10,18 @@ import rpm -@@ -283,7 +284,9 @@ +@@ -284,7 +285,9 @@ class BinariesCheck(AbstractCheck.Abstra continue # stripped ? - if 'not stripped' in pkgfile.magic: + if 'not stripped' in pkgfile.magic and \ -+ (os.environ.get('BUILD_DIR', None) == None or -+ os.environ.get('BUILD_DEBUG', None) != None): ++ (os.environ.get('BUILD_DIR', '') == '' or ++ os.environ.get('BUILD_DEBUG', '') != ''): printWarning(pkg, 'unstripped-binary-or-object', fname) # inspect binary file -@@ -580,6 +583,12 @@ +@@ -581,6 +584,12 @@ form, make sure that rpmbuild does not s that use prelink, make sure that prelink does not strip it either, usually by placing a blacklist file in /etc/prelink.conf.d. For more information, see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=256900#49''',