SHA256
1
0
forked from pool/rpmlint
OBS User unknown 2009-01-14 00:55:43 +00:00 committed by Git OBS Bridge
parent 53597c7cde
commit b092addcc9
3 changed files with 150 additions and 189 deletions

View File

@ -3,7 +3,7 @@
# File : CheckFilelist.py # File : CheckFilelist.py
# Package : rpmlint # Package : rpmlint
# Author : Ludwig Nussel # Author : Ludwig Nussel
# Purpose : Check for wrongly packaged files # Purpose : Check for wrongly packaged files and FHS violations
############################################################################# #############################################################################
from Filter import * from Filter import *
@ -12,13 +12,17 @@ import re
import os import os
import string import string
import fnmatch import fnmatch
from rpm import RPMTAG_VENDOR
_defaulterror = 'suse-filelist-forbidden' _defaulterror = 'suse-filelist-forbidden'
_defaultmsg = '%(file)s is not allowed anymore in SUSE Linux' _defaultmsg = '%(file)s is not allowed in SUSE Linux'
def notnoarch(pkg): def notnoarch(pkg):
return pkg.arch != 'noarch' return pkg.arch != 'noarch'
def isfilesystem(pkg):
return pkg.name == 'filesystem'
def isdebuginfo(pkg): def isdebuginfo(pkg):
if pkg.name.endswith('-debuginfo') \ if pkg.name.endswith('-debuginfo') \
or pkg.name.endswith('-debuginfo-32bit') \ or pkg.name.endswith('-debuginfo-32bit') \
@ -34,6 +38,52 @@ def notsymlink(pkg, f):
type = (mode>>12)&017 type = (mode>>12)&017
return type != 012 return type != 012
_goodprefixes = (
'/bin/',
'/boot/',
'/etc/',
'/lib/',
'/lib64/',
'/media/',
# SUSE policy handled in separate check
'/opt/',
'/sbin/',
'/srv/',
# SUSE policy handled in separate check
'/usr/X11R6/',
'/usr/bin/',
'/usr/games/',
'/usr/include/',
'/usr/lib/',
'/usr/lib64/',
'/usr/sbin/',
'/usr/share/',
# actually only linux is allowed by fhs
'/usr/src/linux',
'/usr/src/debug/',
'/usr/src/packages/',
'/var/account/',
'/var/cache/',
'/var/crash/',
'/var/games/',
'/var/lib/',
'/var/lock/',
'/var/log/',
'/var/mail/',
'/var/opt/',
'/var/run/',
'/var/spool/',
'/var/yp/',
# those are not in FHS!
'/var/adm/',
'/var/nis/',
'/emul/',
)
# computed from goodprefixes.
# Directories that are only allowed to have defined subdirs (such as /usr)
_restricteddirs = set()
_checks = [ _checks = [
{ {
'good': [ 'good': [
@ -74,8 +124,6 @@ _checks = [
'/etc/rc.config.d/*', '/etc/rc.config.d/*',
'/etc/init.d/*/*', '/etc/init.d/*/*',
'/usr/share/locale/LC_MESSAGES', '/usr/share/locale/LC_MESSAGES',
'/usr/X11R6/lib/locale',
'/usr/X11R6/lib/X11/locale/LC_MESSAGES*',
'/opt/gnome', '/opt/gnome',
'/usr/lib/perl5/site_perl/*', '/usr/lib/perl5/site_perl/*',
'/usr/lib/perl5/vendor_perl/5.*/auto', '/usr/lib/perl5/vendor_perl/5.*/auto',
@ -84,7 +132,7 @@ _checks = [
}, },
{ {
'error': 'suse-filelist-forbidden-devel-in-lib', 'error': 'suse-filelist-forbidden-devel-in-lib',
'details': 'please move la files, static libs and .so symlinks out of /', 'details': 'please move la files, static libs and .so symlinks to /usr/lib(64)',
'bad': [ 'bad': [
"/lib/*.la", "/lib/*.la",
"/lib/*.a", "/lib/*.a",
@ -94,7 +142,7 @@ _checks = [
}, },
{ {
'error': 'suse-filelist-forbidden-devel-in-lib', 'error': 'suse-filelist-forbidden-devel-in-lib',
'details': 'please move la files, static libs and .so symlinks out of /', 'details': 'please move la files, static libs and .so symlinks to /usr/lib(64)',
'good': [ 'good': [
# exception for pam # exception for pam
"/lib/security/*.so", "/lib/security/*.so",
@ -108,13 +156,10 @@ _checks = [
'ignorefileif': notsymlink, 'ignorefileif': notsymlink,
}, },
{ {
'error': 'suse-filelist-forbidden-fhs22', 'error': 'suse-filelist-forbidden-fhs23',
'msg': '%(file)s is not allowed in FHS 2.2', 'msg': '%(file)s is not allowed in FHS 2.3',
'details': 'see http://www.pathname.com/fhs/ to find a better location', 'details': 'see http://www.pathname.com/fhs/ to find a better location',
'bad': [ 'bad': [
"/usr/dict",
"/var/locale",
"/var/locale/*",
"/etc/X11/app-defaults/*", "/etc/X11/app-defaults/*",
"/usr/local/man/*/*", "/usr/local/man/*/*",
"/var/lib/games", "/var/lib/games",
@ -196,19 +241,9 @@ _checks = [
'error': 'suse-filelist-forbidden-xorg', 'error': 'suse-filelist-forbidden-xorg',
'details': """Please use the updated paths for Xorg 7.1 and above""", 'details': """Please use the updated paths for Xorg 7.1 and above""",
'bad': [ 'bad': [
'/usr/X11R6/include/X11', '/usr/X11R6/*',
'/usr/X11R6/include/X11/*',
'/usr/X11R6/lib/X11',
'/usr/X11R6/lib/X11/*',
'/usr/X11R6/lib/modules',
'/usr/X11R6/lib/modules/*',
'/usr/X11R6/lib64/modules',
'/usr/X11R6/lib64/modules/*',
'/usr/X11R6/lib/X11/app-defaults',
'/usr/X11R6/lib/X11/app-defaults/*',
'/usr/X11R6/lib64/X11/app-defaults',
'/usr/X11R6/lib64/X11/app-defaults/*',
], ],
'ignorepkgif': isfilesystem,
}, },
{ {
'error': 'suse-filelist-forbidden-suseconfig', 'error': 'suse-filelist-forbidden-suseconfig',
@ -264,150 +299,6 @@ _checks = [
{ {
'error': 'suse-filelist-forbidden-opt', 'error': 'suse-filelist-forbidden-opt',
'details': """/opt may not be used by a distribution. It is reserved for 3rd party packagers""", 'details': """/opt may not be used by a distribution. It is reserved for 3rd party packagers""",
'good': [
# KDE3 legacy exception
'/opt/kde3',
'/opt/kde3/*',
],
'bad': [
'/opt/*',
],
},
{
'error': 'suse-filelist-forbidden-fhs22',
'good': [
'/bin',
'/bin/*',
'/boot',
'/boot/*',
'/cdrom',
'/dev',
'/dev/*',
'/etc',
'/etc/*',
'/floppy',
'/home',
'/lib',
'/lib/*',
'/lib64',
'/lib64/*',
'/media',
'/media/*',
'/mnt',
'/opt',
# handled in separate check
'/opt/*',
'/proc',
'/root',
'/root/.exrc',
'/root/.gnupg',
'/root/.gnupg/*',
'/root/.kbackrc',
'/root/.xinitrc',
'/root/bin',
'/sbin',
'/sbin/*',
'/subdomain',
'/sys',
'/tmp',
'/tmp/.X11-unix',
'/tmp/.ICE-unix',
'/usr',
'/usr/*-linux-libc5',
'/usr/*-linux-libc5/*',
'/usr/*-linux',
'/usr/*-linux/*',
'/usr/X11',
'/usr/X11R6',
'/usr/X11R6/*',
'/usr/bin',
'/usr/bin/*',
'/usr/games',
'/usr/games/*',
'/usr/include',
'/usr/include/*',
'/usr/lib',
'/usr/lib/*',
'/usr/lib64',
'/usr/lib64/*',
'/usr/local',
'/usr/local/bin',
'/usr/local/games',
'/usr/local/include',
'/usr/local/lib',
'/usr/local/lib64',
'/usr/local/man',
'/usr/local/man/*',
'/usr/local/sbin',
'/usr/local/share',
'/usr/local/src',
'/usr/sbin',
'/usr/sbin/*',
'/usr/share',
'/usr/share/*',
'/usr/spool',
'/usr/src',
'/usr/src/debug*',
'/usr/src/linux*',
'/usr/src/kernel-modules*',
'/usr/src/packages',
'/usr/src/packages/*',
'/usr/src/bxform*',
'/usr/src/dicts',
'/usr/src/dicts/*',
'/usr/tmp',
'/var',
'/var/X11R6',
'/var/X11R6/*',
'/var/account',
'/var/account/*',
'/var/agentx',
'/var/agentx/*',
'/var/cache',
'/var/cache/*',
'/var/crash',
'/var/crash/*',
'/var/games',
'/var/games/*',
'/var/lib',
'/var/lib/*',
'/var/local',
'/var/lock',
'/var/lock/*',
'/var/log',
'/var/log/*',
'/var/mail',
'/var/mail/*',
'/var/opt',
'/var/opt/*',
'/var/preserve',
'/var/run',
'/var/run/*',
'/var/spool',
'/var/spool/*',
'/var/tmp',
'/var/tmp/vi.recover',
'/var/yp',
'/var/yp/*',
# we have these below /var, but not nice to have:
'/var/adm',
'/var/adm/*',
'/var/db',
'/var/db/*',
'/var/nis',
'/var/nis/*',
'/var/heimdal',
# allowed, but not nice to have:
'/afs',
'/afs/*',
'/emul',
'/emul/*',
'/srv',
'/srv/*',
],
'bad': [
'*',
]
}, },
] ]
@ -416,6 +307,11 @@ class FilelistCheck(AbstractCheck.AbstractCheck):
AbstractCheck.AbstractCheck.__init__(self, "CheckFilelist") AbstractCheck.AbstractCheck.__init__(self, "CheckFilelist")
import re import re
_restricteddirs.add('/')
for d in _goodprefixes:
if d.count('/') > 2:
_restricteddirs.add(d[0:-1].rpartition('/')[0])
for check in _checks: for check in _checks:
if 'good' in check: if 'good' in check:
for i in range(len(check['good'])): for i in range(len(check['good'])):
@ -424,16 +320,19 @@ class FilelistCheck(AbstractCheck.AbstractCheck):
r = fnmatch.translate(pattern) r = fnmatch.translate(pattern)
check['good'][i] = re.compile(r) check['good'][i] = re.compile(r)
for i in range(len(check['bad'])): if 'bad' in check:
pattern = check['bad'][i] for i in range(len(check['bad'])):
if '*' in pattern: pattern = check['bad'][i]
r = fnmatch.translate(pattern) if '*' in pattern:
check['bad'][i] = re.compile(r) r = fnmatch.translate(pattern)
check['bad'][i] = re.compile(r)
def check(self, pkg): def check(self, pkg):
global _checks global _checks
global _defaultmsg global _defaultmsg
global _defaulterror global _defaulterror
global _goodprefixes
global _restricteddirs
if pkg.isSource(): if pkg.isSource():
return return
@ -441,7 +340,7 @@ class FilelistCheck(AbstractCheck.AbstractCheck):
files = pkg.files() files = pkg.files()
if not files: if not files:
printError(pkg, 'suse-filelist-empty', 'packages without any files are not allowed anymore in SUSE Linux') printError(pkg, 'suse-filelist-empty', 'packages without any files are not allowed in SUSE Linux')
return return
for check in _checks: for check in _checks:
@ -460,24 +359,77 @@ class FilelistCheck(AbstractCheck.AbstractCheck):
else: else:
error = _defaulterror error = _defaulterror
for f in files: if 'good' in check or 'bad' in check:
ok = False for f in files:
if 'good' in check: ok = False
for g in check['good']: if 'good' in check:
if (not isinstance(g, str) and g.match(f)) or g == f: for g in check['good']:
ok = True if (not isinstance(g, str) and g.match(f)) or g == f:
break ok = True
if ok: break
if ok:
continue
if 'bad' in check:
for b in check['bad']:
if 'ignorefileif' in check:
if check['ignorefileif'](pkg, f):
continue
if (not isinstance(b, str) and b.match(f)) or b == f:
m = msg % { 'file':f }
printError(pkg, error, m)
invalidfhs = set()
invalidopt = set()
if pkg.header[RPMTAG_VENDOR] and pkg.header[RPMTAG_VENDOR].find('SUSE') != -1:
isSUSE = True
else:
isSUSE = False
# the checks here only warn about a directory once rather
# than reporting potentially hundreds of files individually
for f in files:
enreg = files[f]
mode = enreg[0]
type = (mode>>12)&017
# append / to directories
if type == 04:
f += '/'
if not f.startswith(_goodprefixes):
base = f.rpartition('/')
pfx = None
# find the first invalid path component (/usr/foo/bar/baz -> /usr)
while base[0] and not base[0].startswith(_goodprefixes) and not base[0] in _restricteddirs:
pfx = base[0]
base = base[0].rpartition('/')
if not pfx:
invalidfhs.add(f)
else:
invalidfhs.add(pfx)
if f.startswith('/opt'):
try:
provider = f.split('/')[2]
except:
continue
# legacy exception
if provider == 'kde3':
continue
if isSUSE and (provider == 'suse' or provider == 'novell'):
continue continue
for b in check['bad']: d = '/opt/'+provider
if 'ignorefileif' in check: invalidopt.add(d)
if check['ignorefileif'](pkg, f):
continue
if (not isinstance(b, str) and b.match(f)) or b == f:
m = msg % { 'file':f }
printError(pkg, error, m)
for f in invalidfhs:
printError(pkg, 'suse-filelist-forbidden-fhs23', "%(file)s is not allowed in FHS 2.3" % { 'file': f })
for f in invalidopt:
printError(pkg, 'suse-filelist-forbidden-opt', '%(file)s is not allowed for official SUSE packages' % { 'file': f })
check=FilelistCheck() check=FilelistCheck()

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Tue Jan 13 15:59:15 CET 2009 - lnussel@suse.de
- CheckFilelist: optimize FHS check to only complain about wrong
directories rather than hundreds of individual files
------------------------------------------------------------------- -------------------------------------------------------------------
Mon Jan 12 10:48:19 CET 2009 - lnussel@suse.de Mon Jan 12 10:48:19 CET 2009 - lnussel@suse.de

View File

@ -22,7 +22,7 @@ Name: rpmlint
BuildRequires: rpm-python BuildRequires: rpm-python
Summary: Rpm correctness checker Summary: Rpm correctness checker
Version: 0.84 Version: 0.84
Release: 9 Release: 11
Source0: %{name}-%{version}.tar.bz2 Source0: %{name}-%{version}.tar.bz2
Source1: config Source1: config
Source1001: config.in Source1001: config.in
@ -220,6 +220,9 @@ rm -rf $RPM_BUILD_ROOT
/usr/share/man/man1/rpmlint.1.gz /usr/share/man/man1/rpmlint.1.gz
%changelog %changelog
* Tue Jan 13 2009 lnussel@suse.de
- CheckFilelist: optimize FHS check to only complain about wrong
directories rather than hundreds of individual files
* Mon Jan 12 2009 lnussel@suse.de * Mon Jan 12 2009 lnussel@suse.de
- CheckFilelist: add exceptions for kde and pam - CheckFilelist: add exceptions for kde and pam
- CheckPolkitPrivs: use info instead of warning to avoid badness assignment - CheckPolkitPrivs: use info instead of warning to avoid badness assignment