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
|
# 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()
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user