forked from pool/rpmlint
This commit is contained in:
parent
53597c7cde
commit
b092addcc9
328
CheckFilelist.py
328
CheckFilelist.py
@ -3,7 +3,7 @@
|
||||
# File : CheckFilelist.py
|
||||
# Package : rpmlint
|
||||
# Author : Ludwig Nussel
|
||||
# Purpose : Check for wrongly packaged files
|
||||
# Purpose : Check for wrongly packaged files and FHS violations
|
||||
#############################################################################
|
||||
|
||||
from Filter import *
|
||||
@ -12,13 +12,17 @@ import re
|
||||
import os
|
||||
import string
|
||||
import fnmatch
|
||||
from rpm import RPMTAG_VENDOR
|
||||
|
||||
_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):
|
||||
return pkg.arch != 'noarch'
|
||||
|
||||
def isfilesystem(pkg):
|
||||
return pkg.name == 'filesystem'
|
||||
|
||||
def isdebuginfo(pkg):
|
||||
if pkg.name.endswith('-debuginfo') \
|
||||
or pkg.name.endswith('-debuginfo-32bit') \
|
||||
@ -34,6 +38,52 @@ def notsymlink(pkg, f):
|
||||
type = (mode>>12)&017
|
||||
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 = [
|
||||
{
|
||||
'good': [
|
||||
@ -74,8 +124,6 @@ _checks = [
|
||||
'/etc/rc.config.d/*',
|
||||
'/etc/init.d/*/*',
|
||||
'/usr/share/locale/LC_MESSAGES',
|
||||
'/usr/X11R6/lib/locale',
|
||||
'/usr/X11R6/lib/X11/locale/LC_MESSAGES*',
|
||||
'/opt/gnome',
|
||||
'/usr/lib/perl5/site_perl/*',
|
||||
'/usr/lib/perl5/vendor_perl/5.*/auto',
|
||||
@ -84,7 +132,7 @@ _checks = [
|
||||
},
|
||||
{
|
||||
'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': [
|
||||
"/lib/*.la",
|
||||
"/lib/*.a",
|
||||
@ -94,7 +142,7 @@ _checks = [
|
||||
},
|
||||
{
|
||||
'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': [
|
||||
# exception for pam
|
||||
"/lib/security/*.so",
|
||||
@ -108,13 +156,10 @@ _checks = [
|
||||
'ignorefileif': notsymlink,
|
||||
},
|
||||
{
|
||||
'error': 'suse-filelist-forbidden-fhs22',
|
||||
'msg': '%(file)s is not allowed in FHS 2.2',
|
||||
'error': 'suse-filelist-forbidden-fhs23',
|
||||
'msg': '%(file)s is not allowed in FHS 2.3',
|
||||
'details': 'see http://www.pathname.com/fhs/ to find a better location',
|
||||
'bad': [
|
||||
"/usr/dict",
|
||||
"/var/locale",
|
||||
"/var/locale/*",
|
||||
"/etc/X11/app-defaults/*",
|
||||
"/usr/local/man/*/*",
|
||||
"/var/lib/games",
|
||||
@ -196,19 +241,9 @@ _checks = [
|
||||
'error': 'suse-filelist-forbidden-xorg',
|
||||
'details': """Please use the updated paths for Xorg 7.1 and above""",
|
||||
'bad': [
|
||||
'/usr/X11R6/include/X11',
|
||||
'/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/*',
|
||||
'/usr/X11R6/*',
|
||||
],
|
||||
'ignorepkgif': isfilesystem,
|
||||
},
|
||||
{
|
||||
'error': 'suse-filelist-forbidden-suseconfig',
|
||||
@ -264,150 +299,6 @@ _checks = [
|
||||
{
|
||||
'error': 'suse-filelist-forbidden-opt',
|
||||
'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")
|
||||
import re
|
||||
|
||||
_restricteddirs.add('/')
|
||||
for d in _goodprefixes:
|
||||
if d.count('/') > 2:
|
||||
_restricteddirs.add(d[0:-1].rpartition('/')[0])
|
||||
|
||||
for check in _checks:
|
||||
if 'good' in check:
|
||||
for i in range(len(check['good'])):
|
||||
@ -424,16 +320,19 @@ class FilelistCheck(AbstractCheck.AbstractCheck):
|
||||
r = fnmatch.translate(pattern)
|
||||
check['good'][i] = re.compile(r)
|
||||
|
||||
for i in range(len(check['bad'])):
|
||||
pattern = check['bad'][i]
|
||||
if '*' in pattern:
|
||||
r = fnmatch.translate(pattern)
|
||||
check['bad'][i] = re.compile(r)
|
||||
if 'bad' in check:
|
||||
for i in range(len(check['bad'])):
|
||||
pattern = check['bad'][i]
|
||||
if '*' in pattern:
|
||||
r = fnmatch.translate(pattern)
|
||||
check['bad'][i] = re.compile(r)
|
||||
|
||||
def check(self, pkg):
|
||||
global _checks
|
||||
global _defaultmsg
|
||||
global _defaulterror
|
||||
global _goodprefixes
|
||||
global _restricteddirs
|
||||
|
||||
if pkg.isSource():
|
||||
return
|
||||
@ -441,7 +340,7 @@ class FilelistCheck(AbstractCheck.AbstractCheck):
|
||||
files = pkg.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
|
||||
|
||||
for check in _checks:
|
||||
@ -460,24 +359,77 @@ class FilelistCheck(AbstractCheck.AbstractCheck):
|
||||
else:
|
||||
error = _defaulterror
|
||||
|
||||
for f in files:
|
||||
ok = False
|
||||
if 'good' in check:
|
||||
for g in check['good']:
|
||||
if (not isinstance(g, str) and g.match(f)) or g == f:
|
||||
ok = True
|
||||
break
|
||||
if ok:
|
||||
if 'good' in check or 'bad' in check:
|
||||
for f in files:
|
||||
ok = False
|
||||
if 'good' in check:
|
||||
for g in check['good']:
|
||||
if (not isinstance(g, str) and g.match(f)) or g == f:
|
||||
ok = True
|
||||
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
|
||||
|
||||
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)
|
||||
d = '/opt/'+provider
|
||||
invalidopt.add(d)
|
||||
|
||||
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()
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -22,7 +22,7 @@ Name: rpmlint
|
||||
BuildRequires: rpm-python
|
||||
Summary: Rpm correctness checker
|
||||
Version: 0.84
|
||||
Release: 9
|
||||
Release: 11
|
||||
Source0: %{name}-%{version}.tar.bz2
|
||||
Source1: config
|
||||
Source1001: config.in
|
||||
@ -220,6 +220,9 @@ rm -rf $RPM_BUILD_ROOT
|
||||
/usr/share/man/man1/rpmlint.1.gz
|
||||
|
||||
%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
|
||||
- CheckFilelist: add exceptions for kde and pam
|
||||
- CheckPolkitPrivs: use info instead of warning to avoid badness assignment
|
||||
|
Loading…
Reference in New Issue
Block a user