示例#1
0
def registerErrorDetails(details):
    """details is expected to be a sequence of (id, description) pairs, where
    id is the error id like 'cronjob-unauthorized-file' and description is a
    human readable text describing the situation. The text may contain
    placeholders that will be replaced by the constants above."""
    from Filter import addDetails

    for _id, desc in details:
        addDetails(
            _id,
            desc.format(url=AUDIT_BUG_URL,
                        review_needed_text=REVIEW_NEEDED_TEXT,
                        followup_needed_text=FOLLOWUP_NEEDED_TEXT,
                        ghost_encountered_text=GHOST_ENCOUNTERED_TEXT))
    def add_check(self, pkg_name, name_re, file_re):
        c = {}
        c['pkg_name'] = pkg_name
        c['name_re'] = re.compile(name_re)
        c['file_re'] = re.compile(file_re)
        self.checks_.append(c)

        if simple_naming_policy_re.search(name_re):
            details = "Its name should begin with " + name_re[1:]
        else:
            details = "Its name should match the regular expression " + name_re

        addDetails(pkg_name + '-naming-policy-not-applied',
                   "This package doesn't respect the naming policy for %s "
                   "packages.\n%s." % (pkg_name, details))
示例#3
0
    def add_check(self, pkg_name, name_re, file_re):
        c = {}
        c['pkg_name'] = pkg_name
        c['name_re'] = re.compile(name_re)
        c['file_re'] = re.compile(file_re)
        self.checks_.append(c)

        if simple_naming_policy_re.search(name_re):
            details = "Its name should begin with " + name_re[1:]
        else:
            details = "Its name should match the regular expression " + name_re

        addDetails(pkg_name + '-naming-policy-not-applied',
                   "This package doesn't respect the naming policy for %s "
                   "packages.\n%s." % (pkg_name, details))
addDetails(
'permissions-unauthorized-file',
"""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. Please refer to {} for more
information.""".format(AUDIT_BUG_URL),
'permissions-symlink',
"""permissions handling for symlinks is useless. Please contact
[email protected] to remove the entry. Please refer to {} for more
information.""".format(AUDIT_BUG_URL),
'permissions-dir-without-slash',
"""the entry in the permissions file refers to a directory. Please
contact [email protected] to append a slash to the entry in order to
avoid security problems. Please refer to {} for more information.""".format(AUDIT_BUG_URL),
'permissions-file-as-dir',
"""the entry in the permissions file refers to a directory but the
package actually contains a file. Please contact [email protected] to
remove the slash. Please refer to {} for more information.""".format(AUDIT_BUG_URL),
'permissions-incorrect',
"""please use the %attr macro to set the correct permissions.""",
'permissions-incorrect-owner',
"""please use the %attr macro to set the correct ownership.""",
'permissions-file-setuid-bit',
"""If the package is intended for inclusion in any SUSE product
please open a bug report to request review of the program by the
security team. Please refer to {} for more information.""".format(AUDIT_BUG_URL),
'permissions-directory-setuid-bit',
"""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. Please refer to {} for more
information.""".format(AUDIT_BUG_URL),
'permissions-world-writable',
"""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. Please refer to {} for more
information.""".format(AUDIT_BUG_URL),
'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 an appropriate %post section""",
'permissions-missing-requires',
"""Please add \"PreReq: permissions\"""",
'permissions-missing-verifyscript',
"""Please add a %verifyscript section""",
'permissions-suseconfig-obsolete',
"""The %run_permissions macro calls SuSEconfig which sets permissions for all
files in the system. Please use %set_permissions <filename> instead
to only set permissions for files contained in this package""",
)
示例#5
0
class BinaryInfo(object):

    needed_regex = re.compile('\s+\(NEEDED\).*\[(\S+)\]')
    rpath_regex = re.compile('\s+\(RPATH\).*\[(\S+)\]')
    soname_regex = re.compile('\s+\(SONAME\).*\[(\S+)\]')
    comment_regex = re.compile('^\s+\[\s*\d+\]\s+\.comment\s+')
    pic_regex = re.compile('^\s+\[\s*\d+\]\s+\.rela?\.(data|text)')
    #   GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
    stack_regex = re.compile('^\s+GNU_STACK\s+(?:(?:\S+\s+){5}(\S+)\s+)?')
    stack_exec_regex = re.compile('^..E$')
    undef_regex = re.compile('^undefined symbol:\s+(\S+)')
    unused_regex = re.compile('^\s+(\S+)')
    call_regex = re.compile('\s0\s+FUNC\s+(.*)')
    exit_call_regex = create_regexp_call('_?exit')
    fork_call_regex = create_regexp_call('fork')
    setgid_call_regex = create_regexp_call('set(?:res|e)?gid')
    setuid_call_regex = create_regexp_call('set(?:res|e)?uid')
    setgroups_call_regex = create_regexp_call('(?:ini|se)tgroups')
    chroot_call_regex = create_regexp_call('chroot')
    # 401eb8:   e8 c3 f0 ff ff          callq  400f80 <chdir@plt>
    objdump_call_regex = re.compile(b'callq?\s(.*)')

    forbidden_functions = Config.getOption("WarnOnFunction")
    if forbidden_functions:
        for name, func in forbidden_functions.items():
            # precompile regexps
            f_name = func['f_name']
            func['f_regex'] = create_nonlibc_regexp_call(f_name)
            if 'good_param' in func:
                func['waiver_regex'] = re.compile(func['good_param'])
            # register descriptions
            addDetails(name, func['description'])

    chdir_call_regex = create_regexp_call('chdir')
    mktemp_call_regex = create_regexp_call('mktemp')

    def __init__(self, pkg, path, file, is_ar, is_shlib):
        self.readelf_error = False
        self.needed = []
        self.rpath = []
        self.undef = []
        self.unused = []
        self.comment = False
        self.soname = False
        self.non_pic = True
        self.stack = False
        self.exec_stack = False
        self.exit_calls = []
        self.forbidden_calls = []
        fork_called = False
        self.tail = ''

        self.setgid = False
        self.setuid = False
        self.setgroups = False
        self.chroot = False
        self.chdir = False
        self.chroot_near_chdir = False
        self.mktemp = False

        is_debug = path.endswith('.debug')

        cmd = ['env', 'LC_ALL=C', 'readelf', '-W', '-S', '-l', '-d', '-s']
        cmd.append(path)
        res = Pkg.getstatusoutput(cmd)
        if not res[0]:
            lines = res[1].splitlines()
            for l in lines:
                r = BinaryInfo.needed_regex.search(l)
                if r:
                    self.needed.append(r.group(1))
                    continue

                r = BinaryInfo.rpath_regex.search(l)
                if r:
                    for p in r.group(1).split(':'):
                        self.rpath.append(p)
                    continue

                if BinaryInfo.comment_regex.search(l):
                    self.comment = True
                    continue

                if BinaryInfo.pic_regex.search(l):
                    self.non_pic = False
                    continue

                r = BinaryInfo.soname_regex.search(l)
                if r:
                    self.soname = r.group(1)
                    continue

                r = BinaryInfo.stack_regex.search(l)
                if r:
                    self.stack = True
                    flags = r.group(1)
                    if flags and BinaryInfo.stack_exec_regex.search(flags):
                        self.exec_stack = True
                    continue

                if l.startswith("Symbol table"):
                    break

            for l in lines:
                r = BinaryInfo.call_regex.search(l)
                if not r:
                    continue
                l = r.group(1)

                if BinaryInfo.mktemp_call_regex.search(l):
                    self.mktemp = True

                if BinaryInfo.setgid_call_regex.search(l):
                    self.setgid = True

                if BinaryInfo.setuid_call_regex.search(l):
                    self.setuid = True

                if BinaryInfo.setgroups_call_regex.search(l):
                    self.setgroups = True

                if BinaryInfo.chdir_call_regex.search(l):
                    self.chdir = True

                if BinaryInfo.chroot_call_regex.search(l):
                    self.chroot = True

                if BinaryInfo.forbidden_functions:
                    for r_name, func in BinaryInfo.forbidden_functions.items():
                        ret = func['f_regex'].search(l)
                        if ret:
                            self.forbidden_calls.append(r_name)

                if is_shlib:
                    r = BinaryInfo.exit_call_regex.search(l)
                    if r:
                        self.exit_calls.append(r.group(1))
                        continue
                    r = BinaryInfo.fork_call_regex.search(l)
                    if r:
                        fork_called = True
                        continue

            # check if we don't have a string that will automatically
            # waive the presence of a forbidden call
            if self.forbidden_calls:
                cmd = ['env', 'LC_ALL=C', 'strings']
                cmd.append(path)
                res = Pkg.getstatusoutput(cmd)
                if not res[0]:
                    for l in res[1].splitlines():
                        # as we need to remove elements, iterate backwards
                        for i in range(len(self.forbidden_calls) - 1, -1, -1):
                            func = self.forbidden_calls[i]
                            f = BinaryInfo.forbidden_functions[func]
                            if 'waiver_regex' not in f:
                                continue
                            r = f['waiver_regex'].search(l)
                            if r:
                                del self.forbidden_calls[i]

            if self.non_pic:
                self.non_pic = 'TEXTREL' in res[1]

            # Ignore all exit() calls if fork() is being called.
            # Does not have any context at all but without this kludge, the
            # number of false positives would probably be intolerable.
            if fork_called:
                self.exit_calls = []

            # check if chroot is near chdir (since otherwise, chroot is called
            # without chdir)
            # Currently this implementation works only on x86_64 due to reliance
            # on x86_64 specific assembly. Skip it on other architectures
            if pkg.arch == 'x86_64' and self.chroot and self.chdir:
                p = subprocess.Popen(
                    ['env', 'LC_ALL=C', 'objdump', '-d', path],
                    stdout=subprocess.PIPE,
                    bufsize=-1)
                with p.stdout:
                    index = 0
                    chroot_index = -99
                    chdir_index = -99
                    for line in p.stdout:
                        res = BinaryInfo.objdump_call_regex.search(line)
                        if not res:
                            continue
                        if b'@plt' not in res.group(1):
                            pass
                        elif b'chroot@plt' in res.group(1):
                            chroot_index = index
                            if abs(chroot_index - chdir_index) <= 2:
                                self.chroot_near_chdir = True
                                break
                        elif b'chdir@plt' in res.group(1):
                            chdir_index = index
                            if abs(chroot_index - chdir_index) <= 2:
                                self.chroot_near_chdir = True
                                break
                        index += 1
                if p.wait() and not self.chroot_near_chdir:
                    printWarning(pkg, 'binaryinfo-objdump-failed', file)
                    self.chroot_near_chdir = True  # avoid false positive

        else:
            self.readelf_error = True
            printWarning(pkg, 'binaryinfo-readelf-failed', file,
                         re.sub('\n.*', '', res[1]))

        try:
            with open(path, 'rb') as fobj:
                fobj.seek(-12, os.SEEK_END)
                self.tail = Pkg.b2s(fobj.read())
        except Exception as e:
            printWarning(pkg, 'binaryinfo-tail-failed %s: %s' % (file, e))

        # Undefined symbol and unused direct dependency checks make sense only
        # for installed packages.
        # skip debuginfo: https://bugzilla.redhat.com/190599
        if not is_ar and not is_debug and isinstance(pkg, Pkg.InstalledPkg):
            # We could do this with objdump, but it's _much_ simpler with ldd.
            res = Pkg.getstatusoutput(
                ('env', 'LC_ALL=C', 'ldd', '-d', '-r', path))
            if not res[0]:
                for l in res[1].splitlines():
                    undef = BinaryInfo.undef_regex.search(l)
                    if undef:
                        self.undef.append(undef.group(1))
                if self.undef:
                    cmd = self.undef[:]
                    cmd.insert(0, 'c++filt')
                    try:
                        res = Pkg.getstatusoutput(cmd)
                        if not res[0]:
                            self.undef = res[1].splitlines()
                    except:
                        pass
            else:
                printWarning(pkg, 'ldd-failed', file)
            res = Pkg.getstatusoutput(
                ('env', 'LC_ALL=C', 'ldd', '-r', '-u', path))
            if res[0]:
                # Either ldd doesn't grok -u (added in glibc 2.3.4) or we have
                # unused direct dependencies
                in_unused = False
                for l in res[1].splitlines():
                    if not l.rstrip():
                        pass
                    elif l.startswith('Unused direct dependencies'):
                        in_unused = True
                    elif in_unused:
                        unused = BinaryInfo.unused_regex.search(l)
                        if unused:
                            self.unused.append(unused.group(1))
                        else:
                            in_unused = False
示例#6
0
            if docfile.endswith("/INSTALL"):
                printWarning(pkg, "install-file-in-docs", docfile)

    def check_binary(self, pkg):

        if not pkg.docFiles():
            return

        self.__checkRequirements(pkg)
        self.__checkUnwantedFiles(pkg)


check = DocFilesCheck()

addDetails(
    'doc-file-dependency',
    '''An included file marked as %doc creates a possible additional dependency in
the package.  Usually, this is not wanted and may be caused by eg. example
scripts with executable bits set included in the package's documentation.''',
    'install-file-in-docs',
    '''A file whose name suggests that it contains installation instructions is
included in the package.  Such instructions are often not relevant for already
installed packages; if this is the case for this file and it does not contain
any information that is of interest after the package has been built and
installed, do not include the file in the binary package.''',
)

# DocFilesCheck.py ends here

# ex: ts=4 sw=4 et
示例#7
0
        if pkg.isSource():
            return
        ghosts = pkg.ghostFiles()
        for filename in (x for x in pkg.files() if x not in ghosts):
            if self.__files_re.match(filename):
                self.check_file(pkg, filename)


    def check_file(self, pkg, filename):
        """Virtual method called for each file that match the regexp passed
        to the constructor.
        """
        raise NotImplementedError('check must be implemented in subclass')

addDetails(
'invalid-url',
'''The value should be a valid, public HTTP, HTTPS, or FTP URL.''',

'network-checks-disabled',
'''Checks requiring network access have not been enabled in configuration,
see the NetworkEnabled option.''',
)

# AbstractCheck.py ends here

# Local variables:
# indent-tabs-mode: nil
# py-indent-offset: 4
# End:
# ex: ts=4 sw=4 et
示例#8
0
addDetails(
'summary-too-long',
'The "Summary:" must not exceed %d characters.' % max_line_len,

'invalid-version',
'''The version string must not contain the pre, alpha, beta or rc suffixes
because when the final version will be out, you will have to use an Epoch tag
to make the package upgradable. Instead put it in the release tag, prefixed
with something you have control over.''',

'spelling-error',
'''The value of this tag appears to be misspelled. Please double-check.''',

'no-packager-tag',
'''There is no Packager tag in your package. You have to specify a packager
using the Packager tag. Ex: Packager: John Doe <*****@*****.**>.''',

'invalid-packager',
'''The packager email must end with an email compatible with the Packager
option of rpmlint. Please change it and rebuild your package.''',

'no-version-tag',
'''There is no Version tag in your package. You have to specify a version using
the Version tag.''',

'no-release-tag',
'''There is no Release tag in your package. You have to specify a release using
the Release tag.''',

'not-standard-release-extension',
'Your release tag must match the regular expression ' + release_ext + '.',

'no-name-tag',
'''There is no Name tag in your package. You have to specify a name using the
Name tag.''',

'non-coherent-filename',
'''The file which contains the package should be named
<NAME>-<VERSION>-<RELEASE>.<ARCH>.rpm.''',

'no-dependency-on',
'''
''',

'incoherent-version-dependency-on',
'''
''',

'no-version-dependency-on',
'''
''',

'no-major-in-name',
'''The major number of the library isn't included in the package's name.
''',

'no-provides',
'''Your library package doesn't provide the -devel name without the major
version included.''',

'no-summary-tag',
'''There is no Summary tag in your package. You have to describe your package
using this tag. To insert it, just insert a tag 'Summary'.''',

'summary-on-multiple-lines',
'''Your summary must fit on one line. Please make it shorter and rebuild the
package.''',

'summary-not-capitalized',
'''Summary doesn't begin with a capital letter.''',

'summary-ended-with-dot',
'''Summary ends with a dot.''',

'summary-has-leading-spaces',
'''Summary begins with whitespace which will waste space when displayed.''',

'no-description-tag',
'''The description of the package is empty or missing. To add it, insert a
%description section in your spec file, add a textual description of the
package after it, and rebuild the package.''',

'description-line-too-long',
'''Your description lines must not exceed %d characters. If a line is exceeding
this number, cut it to fit in two lines.''' % max_line_len,

'tag-in-description',
'''Something that looks like a tag was found in the package's description.
This may indicate a problem where the tag was not actually parsed as a tag
but just textual description content, thus being a no-op.  Verify if this is
the case, and move the tag to a place in the specfile where %description
won't fool the specfile parser, and rebuild the package.''',

'no-group-tag',
'''There is no Group tag in your package. You have to specify a valid group
in your spec file using the Group tag.''',

'non-standard-group',
'''The value of the Group tag in the package is not valid.  Valid groups are:
"%s".''' % '", "'.join(VALID_GROUPS),

'no-changelogname-tag',
'''There is no %changelog tag in your spec file. To insert it, just insert a
'%changelog' in your spec file and rebuild it.''',

'no-version-in-last-changelog',
'''The latest changelog entry doesn't contain a version. Please insert the
version that is coherent with the version of the package and rebuild it.''',

'incoherent-version-in-changelog',
'''The latest entry in %changelog contains a version identifier that is not
coherent with the epoch:version-release tuple of the package.''',

'changelog-time-overflow',
'''The timestamp of the latest entry in %changelog is suspiciously far away in
the past; it is possible that it is actually so much in the future that it
has overflowed rpm's timestamp representation.''',

'changelog-time-in-future',
'''The timestamp of the latest entry in %changelog is in the future.''',

'no-license',
'''There is no License tag in your spec file. You have to specify one license
for your program (eg. GPL). To insert this tag, just insert a 'License' in
your specfile.''',

'invalid-license',
'''The value of the License tag was not recognized.  Known values are:
"%s".''' % '", "'.join(VALID_LICENSES),

'obsolete-not-provided',
'''If a package is obsoleted by a compatible replacement, the obsoleted package
should also be provided in order to not cause unnecessary dependency breakage.
If the obsoleting package is not a compatible replacement for the old one,
leave out the Provides.''',

'invalid-dependency',
'''An invalid dependency has been detected. It usually means that the build of
the package was buggy.''',

'no-epoch-tag',
'''There is no Epoch tag in your package. You have to specify an epoch using
the Epoch tag.''',

'unreasonable-epoch',
'''The value of your Epoch tag is unreasonably large (> 99).''',

'no-epoch-in-dependency',
'''Your package contains a versioned dependency without an Epoch.''',

'devel-dependency',
'''Your package has a dependency on a devel package but it's not a devel
package itself.''',

'invalid-build-requires',
'''Your source package contains a dependency not compliant with the lib64
naming. This BuildRequires dependency will not be resolved on lib64 platforms
(eg. amd64).''',

'explicit-lib-dependency',
'''You must let rpm find the library dependencies by itself. Do not put
unneeded explicit Requires: tags.''',

'useless-provides',
'''This package provides 2 times the same capacity. It should only provide it
once.''',

'tag-not-utf8',
'''The character encoding of the value of this tag is not UTF-8.''',

'requires-on-release',
'''This rpm requires a specific release of another package.''',

'no-url-tag',
'''The URL tag is missing.''',

'name-repeated-in-summary',
'''The name of the package is repeated in its summary.  This is often redundant
information and looks silly in various programs' output.  Make the summary
brief and to the point without including redundant information in it.''',

'enchant-dictionary-not-found',
'''A dictionary for the Enchant spell checking library is not available for
the language given in the info message.  Spell checking will proceed with
rpmlint's built-in implementation for localized tags in this language.
For better spell checking results in this language, install the appropriate
dictionary that Enchant will use for this language, often for example
hunspell-* or aspell-*.''',

'self-obsoletion',
'''The package obsoletes itself.  This is known to cause errors in various
tools and should thus be avoided, usually by using appropriately versioned
Obsoletes and/or Provides and avoiding unversioned ones.''',

'unexpanded-macro',
'''This tag contains something that looks like an unexpanded macro; this is
often the sign of a misspelling. Please check your specfile.''',

'private-shared-object-provides',
'''A shared object soname provides is provided by a file in a path from which
other packages should not directly load shared objects from.  Such shared
objects should thus not be depended on and they should not result in provides
in the containing package.  Get rid of the provides if appropriate, for example
by filtering it out during build.  Note that in some cases this may require
disabling rpmbuild's internal dependency generator.''',
)
示例#9
0
# Create an object to enable the auto registration of the test
check = DistributionCheck()

addDetails(
'invalid-vendor',
'''In the "%s" distribution, vendor should be "%s".''' % (distribution, vendor),

'invalid-distribution',
'The distribution value should be "' + distribution + '".',

'manpage-not-compressed',
'''This manual page is not compressed with the %s compression method
(does not have the %s extension). If the compression does not happen
automatically when the package is rebuilt, make sure that you have the
appropriate rpm helper and/or config packages for your target distribution
installed and try rebuilding again; if it still does not happen automatically,
you can compress this file in the %%install section of the spec file.''' \
% (compress_ext, compress_ext),

'infopage-not-compressed',
'''This info page is not compressed with the %s compression method
(does not have the %s extension). If the compression does not happen
automatically when the package is rebuilt, make sure that you have the
appropriate rpm helper and/or config packages for your target distribution
installed and try rebuilding again; if it still does not happen automatically,
you can compress this file in the %%install section of the spec file.''' \
% (compress_ext, compress_ext),
)

# DistributionCheck.py ends here
示例#10
0
        # handled by systemd-tmpfiles
        ghost_files = set(pkg.ghostFiles()) - tmp_files
        if ghost_files:
            for f in ghost_files:
                if f in pkg.missingOkFiles():
                    continue
                if not postin and not prein:
                    printWarning(pkg, 'ghost-files-without-postin')
                if (not postin or f not in postin) and \
                        (not prein or f not in prein):
                    printWarning(pkg, 'postin-without-ghost-file-creation', f)


check = TmpFilesCheck()

addDetails(
    'postin-without-ghost-file-creation',
    '''A file tagged as ghost is not created during %prein nor during %postin.''',
    'postin-without-tmpfile-creation',
    '''Please use the %tmpfiles_create macro in %post for each of your
tmpfiles.d files''', 'tmpfile-not-regular-file',
    '''files in tmpfiles.d need to be regular files''',
    'tmpfile-not-in-filelist',
    '''please add the specified file to your %files section as %ghost so
users can easily query who created the file, it gets uninstalled on
package removal and finally other rpmlint checks see it''',
    'tmpfile-not-ghost',
    '''the specified file is not marked as %ghost although created at
runtime via tmpfiles mechanism.''')
# vim: sw=4 et
示例#11
0
        for fn, pkgfile in pkg.files().items():
            if not fn.startswith('/etc/init.d'):
                continue
            if os.path.basename(fn).startswith('boot.'):
                printError(pkg, bootscr_tag, fn)
            else:
                printError(pkg, etcinit_tag, fn)


check = CheckSysVinitOnSystemd()

if Config.info:
    addDetails(
insserv_tag,
'''In systemd based distributions insserv is obsolete.
Please remove dependencies on insserv.''',
etcinit_tag,
'''SysV init scripts are deprecated. Please migrate to
systemd service files.''',
bootscr_tag,
'''SysV boot scripts are deprecated. Please migrate to
systemd service files.''',
)

# Local variables:
# indent-tabs-mode: nil
# py-indent-offset: 4
# End:
# -*- coding: utf-8 -*-
# vim:sw=4:et:
示例#12
0
        for docfile in pkg.docFiles():
            if docfile.endswith("/INSTALL"):
                printWarning(pkg, "install-file-in-docs", docfile)

    def check_binary(self, pkg):

        if not pkg.docFiles():
            return

        self.__checkRequirements(pkg)
        self.__checkUnwantedFiles(pkg)


check = DocFilesCheck()

addDetails(
'doc-file-dependency',
'''An included file marked as %doc creates a possible additional dependency in
the package.  Usually, this is not wanted and may be caused by eg. example
scripts with executable bits set included in the package's documentation.''',

'install-file-in-docs',
'''A file whose name suggests that it contains installation instructions is
included in the package.  Such instructions are often not relevant for already
installed packages; if this is the case for this file and it does not contain
any information that is of interest after the package has been built and
installed, do not include the file in the binary package.''',
)

# DocFilesCheck.py ends here
示例#13
0
                else:
                    spec_file = fname
            elif source_regex.search(fname) and compress_ext and \
                    not fname.endswith(compress_ext):
                printWarning(pkg, 'source-or-patch-not-compressed',
                             compress_ext, fname)
            perm = pkgfile.mode & 0o7777
            if perm not in valid_src_perms:
                printWarning(pkg, 'strange-permission', fname, "%o" % perm)


check = SourceCheck()

addDetails(
    'multiple-specfiles',
    '''Your package contains multiple spec files. To build a
correct package, you need to have only one spec file containing
all your RPM information.''',
    'source-or-patch-not-compressed',
    '''A source archive or file in your package is not compressed using the %s
compression method (doesn't have the %s extension).''' %
    (compress_ext, compress_ext),
    'strange-permission',
    '''A file that you listed to include in your package has strange
permissions. Usually, a file should have 0644 permissions.''',
)

# SourceCheck.py ends here

# ex: ts=4 sw=4 et
示例#14
0
                             'suse-alternative-generic-name-missing', af)
            elif not stat.S_ISLNK(files[af].mode):
                printWarning(pkg,
                             'suse-alternative-generic-name-not-symlink', af)

            ### check that %post contains --install call
            ### check that %preun contains --remove call


check = CheckUpdateAlternatives()

if Config.info:
    addDetails(
'suse-alternative-generic-name-not-symlink',
'''The update-alternative generic-name is not a symlink pointing to
%{_sysconfdir}/alternatives/$(basename generic-name).
''',

'suse-alternative-link-not-ghost',
'''The %{_sysconfdir}/alternatives/$(basename generic-name) link exists but is
not marked as ghost. Mark it as %ghost.''',

'suse-alternative-link-missing',
'''The file %{_sysconfdir}/alternatives/$(basename generic-name) is missing
in the file list. Mark it as %ghost and add it to the file list.''',

'suse-alternative-generic-name-missing',
'''The update-alternatives generic name is not in the filelist. Create it as
a symlink to %{_sysconfdir}/alternatives/$(basename generic-name) and add it
to the file list.''')
示例#15
0
        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()

if Config.info:
    for check in _checks:

        if 'details' not in check:
            continue

        if 'error' not in check:
            continue

        addDetails(
            'suse-filelist-forbidden', """
Your package installs files or directories in a location that have
previously been blacklisted. Please have a look at the particular
file and see if the SUSE Packaging Guidelines propose a better place
on where to install the file or not install it at all.""")

        addDetails(check['error'], check['details'])
示例#16
0
check = I18NCheck()

addDetails(
    # Need to add a function to list all the locales
    'incorrect-i18n-tag-',
    """
""",
    'incorrect-locale-subdir',
    """
""",
    'incorrect-locale-',
    """
""",
    'invalid-lc-messages-dir',
    """
""",
    'invalid-locale-man-dir',
    """
""",
    'file-not-in-lang',
    """
""",
    'no-dependency-on',
    """
""",
    'subfile-not-in-%lang',
    """ If /foo/bar is not tagged %lang(XX) whereas /foo is, the package won't be
installable if XX is not in %_install_langs.""",
)

# I18NCheck.py ends here
示例#17
0
                z and z.close()


check = ZipCheck()

addDetails(
'bad-crc-in-zip',
'''The reported file in the zip fails the CRC check. Usually this is a
sign of a corrupt zip file.''',

'uncompressed-zip',
'''The zip file is not compressed.''',

'class-path-in-manifest',
'''The META-INF/MANIFEST.MF file in the jar contains a hardcoded Class-Path.
These entries do not work with older Java versions and even if they do work,
they are inflexible and usually cause nasty surprises.''',

'jar-indexed',
'''The jar file is indexed, ie. it contains the META-INF/INDEX.LIST file.
These files are known to cause problems with some older Java versions.''',

'jar-not-indexed',
'''The jar file is not indexed, ie. it does not contain the META-INF/INDEX.LIST
file.  Indexed jars speed up the class searching process of classloaders
in some situations.''',
)

# ZipCheck.py ends here

# Local variables:
# indent-tabs-mode: nil
示例#18
0
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


import os

import AbstractCheck
from Filter import addDetails, printWarning


class RpmFileCheck(AbstractCheck.AbstractCheck):
    def __init__(self):
        AbstractCheck.AbstractCheck.__init__(self, "RpmFileCheck")

    def check(self, pkg):
        # http://en.wikipedia.org/wiki/Joliet_(file_system)
        rpmfile_name = os.path.basename(pkg.filename)
        if len(rpmfile_name) > 64:
            printWarning(pkg, 'filename-too-long-for-joliet', rpmfile_name)

check = RpmFileCheck()

addDetails(
'filename-too-long-for-joliet',
'''This filename is too long to fit on a joliet filesystem (limit is 64 unicode
chars).''',
)

# ex: ts=4 sw=4 et
示例#19
0
                    if line.endswith('{'):
                        for logfile in line.split(' '):
                            logfile = logfile.strip()
                            if len(logfile) == 0 or logfile == '{':
                                continue
                            dn = os.path.dirname(logfile)
                            if dn not in dirs:
                                currentdirs.append(dn)
                                dirs[dn] = None
                else:
                    if line.endswith('}'):
                        currentdirs = []
                    elif line.startswith("su "):
                        a = line.split(" ")
                        for dn in currentdirs:
                            dirs[dn] = (a[1], a[2])
        return dirs


check = LogrotateCheck()

addDetails(
    'suse-logrotate-duplicate',
    """There are dupliated logrotate entries with different settings for
the specified file""", 'suse-logrotate-user-writable-log-dir',
    """The log directory is writable by unprivileged users. Please fix
the permissions so only root can write there or add the 'su' option
to your logrotate config""", 'suse-logrotate-log-dir-not-packaged',
    """Please add the specified directory to the file list to be able to
check permissions""")
                if not processed['pre']:
                    printWarning( pkg, 'systemd-service-without-service_add_pre', os.path.basename( fname ) )
                if not processed['post']:
                    printWarning( pkg, 'systemd-service-without-service_add_post', os.path.basename( fname ) )
                if not processed['preun']:
                    printWarning( pkg, 'systemd-service-without-service_del_preun', os.path.basename( fname ) )
                if not processed['postun']:
                    printWarning( pkg, 'systemd-service-without-service_del_postun', os.path.basename( fname ) )

# Create an object to enable the auto registration of the test
check = CheckSystemdInstall()

addDetails(
'systemd-service-without-service_add_pre',
'''The package contains a systemd service but doesn't contain a %pre with
a call to service_add_pre.''',

'systemd-service-without-service_add_post',
'''The package contains a systemd service but doesn't contain a %post with
a call to service_add_post.''',

'systemd-service-without-service_del_preun',
'''The package contains a systemd service but doesn't contain a %preun with
a call to service_del_preun.''',

'systemd-service-without-service_del_postun',
'''The package contains a systemd service but doesn't contain a %postun with
a call to service_del_postun.''',
)
示例#21
0
    addDetails(
'shlib-policy-missing-suffix',
"""Your package containing shared libraries does not end in a digit and
should probably be split.""",
'shlib-policy-devel-file',
"""Your shared library package contains development files. Split them into
a -devel subpackage.""",
'shlib-policy-name-error',
"""Your package contains a single shared library but is not named after its SONAME.""",
'shlib-policy-nonversioned-dir',
"""Your shared library package contains non-versioned directories. Those will not
allow to install multiple versions of the package in parallel.""",
'shlib-legacy-policy-name-error',
"""Your shared library package is not named after its SONAME, but it has been added to the list
of legacy exceptions. Please do not rename the package until SONAME changes, but if you have
to rename it for another reason, make sure you name it correctly.""",
'shlib-policy-excessive-dependency',
"""Your package starts with 'lib' as part of its name, but also contains binaries
that have more dependencies than those that already required by the libraries.
Those binaries should probably not be part of the library package, but split into
a seperate one to reduce the additional dependencies for other users of this library.""",
'shlib-policy-missing-lib',
"""Your package starts with 'lib' as part of its name, but does not provide
any libraries. It must not be called a lib-package then. Give it a more
sensible name.""",
'shlib-fixed-dependency',
"""Your shared library package requires a fixed version of another package. The
intention of the Shared Library Policy is to allow parallel installation of
multiple versions of the same shared library, hard dependencies likely make that
impossible. Please remove this dependency and instead move it to the runtime uses
of your library.""",
'shlib-unversioned-lib',
"""Your package matches the Shared Library Policy Naming Scheme but contains an
unversioned library. Therefore it is very unlikely that your package can be installed
in parallel to another version of this library package. Consider moving unversioned
parts into a runtime package."""
)
示例#22
0

class AbstractFilesCheck(AbstractCheck):
    def __init__(self, name, file_regexp):
        self.__files_re = re.compile(file_regexp)
        AbstractCheck.__init__(self, name)

    def check_binary(self, pkg):
        ghosts = pkg.ghostFiles()
        for filename in (x for x in pkg.files() if x not in ghosts):
            if self.__files_re.match(filename):
                self.check_file(pkg, filename)

    def check_file(self, pkg, filename):
        """Virtual method called for each file that match the regexp passed
        to the constructor.
        """
        raise NotImplementedError('check must be implemented in subclass')


addDetails(
'invalid-url',
'''The value should be a valid, public HTTP, HTTPS, or FTP URL.''',

'network-checks-disabled',
'''Checks requiring network access have not been enabled in configuration,
see the NetworkEnabled option.''',
)

# AbstractCheck.py ends here
示例#23
0
                kres = None
            if kres:
                printError(pkg, "unknown-key", kres.group(1))
            else:
                Pkg.warn("Error checking signature of %s: %s" %
                         (pkg.filename, res[1]))
        else:
            if not SignatureCheck.pgp_regex.search(res[1]):
                printError(pkg, "no-signature")

# Create an object to enable the auto registration of the test
check = SignatureCheck()

addDetails(
'no-signature',
'''You have to include your pgp or gpg signature in your package.
For more information on signatures, please refer to www.gnupg.org.''',

'unknown-key',
'''The package was signed, but with an unknown key.
See the rpm --import option for more information.''',
)

# SignatureCheck.py ends here

# Local variables:
# indent-tabs-mode: nil
# py-indent-offset: 4
# End:
# ex: ts=4 sw=4 et
示例#24
0
                    printError(pkg, 'invalid-desktopfile', filename,
                               line.split('error: ')[1])
                    error_printed = True
            if not error_printed:
                printError(pkg, 'invalid-desktopfile', filename)
        if not is_utf8(f):
            printError(pkg, 'non-utf8-desktopfile', filename)

        self.parse_desktop_file(pkg, root, f, filename)


check = MenuXDGCheck()

addDetails(
    'invalid-desktopfile',
    '''.desktop file is not valid, check with desktop-file-validate''',
    'non-utf8-desktopfile',
    '''.desktop file is not encoded in UTF-8''',
    'desktopfile-without-binary',
    '''the .desktop file is for a file not present in the package. You
should check the requires or see if this is not a error''',
    'desktopfile-duplicate-section',
    '''The .desktop file contains the mentioned section name twice, which
can trigger parsing ambiguities. Remove the duplicate.''',
    'desktopfile-duplicate-option',
    '''The .desktop file contains the mentioned option key twice,
which can trigger parsing ambiguities. Remove the duplicate.''',
    'desktopfile-missing-header',
    '''The .desktop file should start with a section header.''',
)
示例#25
0
                    printError(pkg, "perl-syntax-error-in-" + tag)
            elif prog.endswith("sh"):
                res = single_command_regex.search(script)
                if res:
                    printWarning(pkg, "one-line-command-in-" + tag, res.group(1))

        elif prog not in empty_shells and prog in valid_shells:
            printWarning(pkg, "empty-" + tag)


# Create an object to enable the auto registration of the test
check = PostCheck()

# Add information about checks
addDetails(
    "postin-without-ghost-file-creation", """A file tagged as ghost is not created during %prein nor during %postin."""
)
for scriptlet in map(lambda x: "%" + x, RPM_SCRIPTLETS):
    addDetails(
        "one-line-command-in-%s" % scriptlet,
        """You should use %s -p <command> instead of using:

%s
<command>

It will avoid the fork of a shell interpreter to execute your command as
well as allows rpm to automatically mark the dependency on your command
for the execution of the scriptlet."""
        % (scriptlet, scriptlet),
        "percent-in-%s" % scriptlet,
        """The %s scriptlet contains a "%%" in a context which might indicate it being
示例#26
0
            elif source_regex.search(fname) and compress_ext and \
                    not fname.endswith(compress_ext):
                printWarning(pkg, 'source-or-patch-not-compressed',
                             compress_ext, fname)
            perm = pkgfile.mode & 0o7777
            if perm not in valid_src_perms:
                printWarning(pkg, 'strange-permission', fname, "%o" % perm)

check = SourceCheck()

addDetails(
'multiple-specfiles',
'''Your package contains multiple spec files. To build a
correct package, you need to have only one spec file containing
all your RPM information.''',

'source-or-patch-not-compressed',
'''A source archive or file in your package is not compressed using the %s
compression method (doesn't have the %s extension).''' %
(compress_ext, compress_ext),

'strange-permission',
'''A file that you listed to include in your package has strange
permissions. Usually, a file should have 0644 permissions.''',

)

# SourceCheck.py ends here

# ex: ts=4 sw=4 et
示例#27
0
addDetails(
'arch-independent-package-contains-binary-or-object',
'''The package contains a binary or object file but is tagged
noarch.''',

'arch-dependent-file-in-usr-share',
'''This package installs an ELF binary in the /usr/share
 hierarchy, which is reserved for architecture-independent files.''',

'binary-in-etc',
'''This package installs an ELF binary in /etc.  Both the
FHS and the FSSTND forbid this.''',

# 'non-sparc32-binary',
# '',

'invalid-soname',
'''The soname of the library is neither of the form lib<libname>.so.<major> or
lib<libname>-<major>.so.''',

'invalid-ldconfig-symlink',
'''The symbolic link references the wrong file. It should reference
the shared library.''',

'no-ldconfig-symlink',
'''The package should not only include the shared library itself, but
also the symbolic link which ldconfig would produce. (This is
necessary, so that the link gets removed by rpm automatically when
the package gets removed, even if for some reason ldconfig would not be
run at package postinstall phase.)''',

'shlib-with-non-pic-code',
'''The listed shared libraries contain object code that was compiled
without -fPIC. All object code in shared libraries should be
recompiled separately from the static libraries with the -fPIC option.
Use the ``eu-findtextrel'' command on a library with debugging symbols
to list code compiled without -fPIC.

Another common mistake that causes this problem is linking with
``gcc -Wl,-shared'' instead of ``gcc -shared''.''',

'binary-or-shlib-defines-rpath',
'''The binary or shared library defines `RPATH'. Usually this is a
bad thing because it hardcodes the path to search libraries and so
makes it difficult to move libraries around.  Most likely you will find a
Makefile with a line like: gcc test.o -o test -Wl,--rpath.  Also, sometimes
configure scripts provide a --disable-rpath flag to avoid this.''',

'statically-linked-binary',
'''The package installs a statically linked binary or object file.

Usually this is a packaging bug. If not, contact your rpmlint distributor
about this so that this error gets included in the exception file for rpmlint
and will not be flagged as a packaging bug in the future (or add it to your
local configuration if you installed rpmlint from the source tarball).''',

'executable-in-library-package',
'''The package mixes up libraries and executables. Mixing up these
both types of files makes upgrades quite impossible.''',

'non-versioned-file-in-library-package',
'''The package contains files in non versioned directories. This makes it
impossible to have multiple major versions of the libraries installed.
One solution can be to change the directories which contain the files
to subdirs of /usr/lib/<name>-<version> or /usr/share/<name>-<version>.
Another solution can be to include a version number in the file names
themselves.''',

'incoherent-version-in-name',
'''The package name should contain the major version of the library.''',

'invalid-directory-reference',
'This file contains a reference to /tmp or /home.',

'no-binary',
'''The package should be of the noarch architecture because it doesn't contain
any binaries.''',

# http://sources.redhat.com/ml/libc-alpha/2003-05/msg00034.html
'undefined-non-weak-symbol',
'''The binary contains undefined non-weak symbols.  This may indicate improper
linkage; check that the binary has been linked as expected.''',

# http://www.redhat.com/archives/fedora-maintainers/2006-June/msg00176.html
'unused-direct-shlib-dependency',
'''The binary contains unused direct shared library dependencies.  This may
indicate gratuitously bloated linkage; check that the binary has been linked
with the intended shared libraries only.''',

'only-non-binary-in-usr-lib',
'''There are only non binary files in /usr/lib so they should be in
/usr/share.''',

'binaryinfo-readelf-failed',
'''Executing readelf on this file failed, all checks could not be run.''',

'binaryinfo-objdump-failed',
'''Executing objdump on this file failed, all checks could not be run.''',

'binaryinfo-tail-failed',
'''Reading trailing bytes of this file failed, all checks could not be run.''',

'ldd-failed',
'''Executing ldd on this file failed, all checks could not be run.''',

'executable-stack',
'''The binary declares the stack as executable.  Executable stack is usually an
error as it is only needed if the code contains GCC trampolines or similar
constructs which uses code on the stack.  One common source for needlessly
executable stack cases are object files built from assembler files which
don\'t define a proper .note.GNU-stack section.''',

'missing-PT_GNU_STACK-section',
'''The binary lacks a PT_GNU_STACK section.  This forces the dynamic linker to
make the stack executable.  Usual suspects include use of a non-GNU linker or
an old GNU linker version.''',

'shared-lib-calls-exit',
'''This library package calls exit() or _exit(), probably in a non-fork()
context. Doing so from a library is strongly discouraged - when a library
function calls exit(), it prevents the calling program from handling the
error, reporting it to the user, closing files properly, and cleaning up any
state that the program has. It is preferred for the library to return an
actual error code and let the calling program decide how to handle the
situation.''',

'ocaml-mixed-executable',
'''Executables built with ocamlc -custom are deprecated.  Packagers should ask
upstream maintainers to build these executables without the -custom option.  If
this cannot be changed and the executable needs to be packaged in its current
form, make sure that rpmbuild does not strip it during the build, and on setups
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''',

'non-position-independent-executable',
'''This executable must be position independent.  Check that it is built with
-fPIE/-fpie in compiler flags and -pie in linker flags.''',

'missing-call-to-setgroups-before-setuid',
'''This executable is calling setuid and setgid without setgroups or
initgroups. There is a high probability this means it didn't relinquish all
groups, and this would be a potential security issue to be fixed. Seek POS36-C
on the web for details about the problem.''',

'missing-call-to-chdir-with-chroot',
'''This executable appears to call chroot without using chdir to change the
current directory. This is likely an error and permits an attacker to break out
of the chroot by using fchdir. While that's not always a security issue, this
has to be checked.''',

'call-to-mktemp',
'''This executable calls mktemp. As advised by the manpage (mktemp(3)), this
function should be avoided. Some implementations are deeply insecure, and there
is a race condition between the time of check and time of use (TOCTOU).
See http://capec.mitre.org/data/definitions/29.html for details, and contact
upstream to have this issue fixed.''',

'unstripped-binary-or-object',
'''This executable should be stripped from debugging symbols, in order to take
less space and be loaded faster. This is usually done automatically at
buildtime by rpm. Check the build logs and the permission on the file (some
implementations only strip if the permission is 0755).'''
)
示例#28
0
                        printWarning(pkg, "non-standard-dir-in-var", d)
                        var_list.append(d)


# Create an object to enable the auto registration of the test
check = FHSCheck()

addDetails(
    "non-standard-dir-in-usr",
    """Your package is creating a non-standard subdirectory in /usr. The standard
directories are:
%s."""
    % ", ".join(FHSCheck.usr_subdir),
    "FSSTND-dir-in-var",
    """Your package is creating an illegal directory in /var. The FSSTND (illegal)
ones are:
%s."""
    % ", ".join(FHSCheck.var_fsstnd),
    "non-standard-dir-in-var",
    """Your package is creating a non-standard subdirectory in /var. The standard
directories are:
%s."""
    % ", ".join(FHSCheck.var_subdir),
)

# FHSCheck.py ends here

# Local variables:
# indent-tabs-mode: nil
# py-indent-offset: 4
# End:
示例#29
0
    def check_file(self, pkg, filename):
        pkgfile = pkg.files()[filename]

        if not (stat.S_ISREG(pkgfile.mode) and
                pkgfile.magic.startswith('POSIX shell script')):
            return

        try:
            status, output = Pkg.getstatusoutput(["dash", "-n", filename])
            if status == 2:
                printWarning(pkg, "bin-sh-syntax-error", filename)
            status, output = Pkg.getstatusoutput(
                ["checkbashisms", filename])
            if status == 1:
                printInfo(pkg, "potential-bashisms", filename)
        except (FileNotFoundError, UnicodeDecodeError):
            pass


check = BashismsCheck()

addDetails(
'bin-sh-syntax-error',
'''A /bin/sh shell script contains a POSIX shell syntax error.
This might indicate a potential bash-specific feature being used,
try dash -n <file> for more detailed error message.''',

'potential-bashisms',
'''checkbashisms reported potential bashisms in a /bin/sh shell
script, you might want to manually check this script for bashisms.''')
示例#30
0
        if pkg.isSource():
            return

        for fname, pkgfile in pkg.files().items():

            if '/animations/' in fname:
                continue

            res = self.file_size_regex.search(fname)
            if res:
                sizes = (res.group(1), res.group(2))
                res = self.info_size_regex.search(pkgfile.magic)
                if res:
                    actualsizes = (res.group(1), res.group(2))

                    if abs(int(sizes[0]) - int(actualsizes[0])) > 2 or \
                            abs(int(sizes[1]) - int(actualsizes[1])) > 2:
                        printError(pkg, "wrong-icon-size", fname, "expected:",
                                   "x".join(sizes), "actual:",
                                   "x".join(actualsizes))


check = IconSizesCheck()

addDetails(
    'wrong-icon-size',
    """Your icon file is installed in a fixed-size directory, but has a
largely incorrect size. Some desktop environments (e.g. GNOME)
display them incorrectly.""")
示例#31
0
addDetails(
'no-spec-file',
'''No spec file was specified in your RPM building. Please specify a valid
SPEC file to build a valid RPM package.''',

'invalid-spec-name',
'''Your spec filename must end with '.spec'. If it's not the case, rename your
file and rebuild your package.''',

'non-utf8-spec-file',
'''The character encoding of the spec file is not UTF-8.  Convert it for
example using iconv(1).''',

'use-of-RPM_SOURCE_DIR',
'''You use $RPM_SOURCE_DIR or %{_sourcedir} in your spec file. If you have to
use a directory for building, use $RPM_BUILD_ROOT instead.''',

'patch-not-applied',
'''A patch is included in your package but was not applied. Refer to the
patches documentation to see what's wrong.''',

'obsolete-tag',
'''The following tags are obsolete: Copyright and Serial. They must
be replaced by License and Epoch respectively.''',

'deprecated-grep',
'''Direct use of grep as egrep or fgrep is deprecated in GNU grep and
historical in POSIX, use grep -E and grep -F instead.''',

'no-buildroot-tag',
'''The BuildRoot tag isn't used in your spec. It must be used in order to
allow building the package as non root on some systems. For some rpm versions
(e.g. rpm.org >= 4.6) the BuildRoot tag is not necessary in specfiles and is
ignored by rpmbuild; if your package is only going to be built with such rpm
versions you can ignore this warning.''',

'hardcoded-path-in-buildroot-tag',
'''A path is hardcoded in your Buildroot tag. It should be replaced
by something like %{_tmppath}/%name-root.''',

'hardcoded-packager-tag',
'''The Packager tag is hardcoded in your spec file. It should be removed, so
as to use rebuilder's own defaults.''',

'buildarch-instead-of-exclusivearch-tag',
'''Use ExclusiveArch instead of BuildArch (or BuildArchitectures)
to restrict build on some specific architectures.
Only use BuildArch with noarch''',

'hardcoded-prefix-tag',
'''The Prefix tag is hardcoded in your spec file. It should be removed, so as
to allow package relocation.''',

'hardcoded-library-path',
'''A library path is hardcoded to one of the following paths: /lib,
/usr/lib. It should be replaced by something like /%{_lib} or %{_libdir}.''',

'configure-without-libdir-spec',
'''A configure script is run without specifying the libdir. configure
options must be augmented with something like --libdir=%{_libdir} whenever
the script supports it.''',

'no-%prep-section',
'''The spec file does not contain a %prep section.  Even if some packages don't
directly need it, section markers may be overridden in rpm's configuration
to provide additional "under the hood" functionality.  Add the section, even
if empty.''',

'no-%build-section',
'''The spec file does not contain a %build section.  Even if some packages
don't directly need it, section markers may be overridden in rpm's
configuration to provide additional "under the hood" functionality, such as
injection of automatic -debuginfo subpackages.  Add the section, even if
empty.''',

'no-%install-section',
'''The spec file does not contain an %install section.  Even if some packages
don't directly need it, section markers may be overridden in rpm's
configuration to provide additional "under the hood" functionality.  Add the
section, even if empty.''',

'no-%clean-section',
'''The spec file doesn't contain a %clean section to remove the files installed
by the %install section.''',

'more-than-one-%changelog-section',
'''The spec file unnecessarily contains more than one %changelog section;
remove the extra ones.''',

'lib-package-without-%mklibname',
'''The package name must be built using %mklibname to allow lib64 and lib32
coexistence.''',

'%ifarch-applied-patch',
'''A patch is applied inside an %ifarch block. Patches must be applied
on all architectures and may contain necessary configure and/or code
patch to be effective only on a given arch.''',

'prereq-use',
'''The use of PreReq is deprecated. In the majority of cases, a plain Requires
is enough and the right thing to do. Sometimes Requires(pre), Requires(post),
Requires(preun) and/or Requires(postun) can also be used instead of PreReq.''',

'buildprereq-use',
'''The use of BuildPreReq is deprecated, build dependencies are always required
before a package can be built.  Use plain BuildRequires instead.''',

'broken-syntax-in-scriptlet-requires',
'''Comma separated context marked dependencies are silently broken in some
versions of rpm.  One way to work around it is to split them into several ones,
eg. replace "Requires(post,preun): foo" with "Requires(post): foo" and
"Requires(preun): foo".''',

'setup-not-in-prep',
'''The %setup macro should only be used within the %prep section because it may
not expand to anything outside of it and can break the build in unpredictable
ways.''',

'setup-not-quiet',
'''Use the -q option to the %setup macro to avoid useless build output from
unpacking the sources.''',

'no-cleaning-of-buildroot',
'''You should clean $RPM_BUILD_ROOT in the %clean section and in the beginning
of the %install section. Use "rm -rf $RPM_BUILD_ROOT". Some rpm configurations
do this automatically; if your package is only going to be built in such
configurations, you can ignore this warning for the section(s) where your rpm
takes care of it.''',

'rpm-buildroot-usage',
'''$RPM_BUILD_ROOT should not be touched during %build or %prep stage, as it
may break short circuit builds.''',

'make-check-outside-check-section',
'''Make check or other automated regression test should be run in %check, as
they can be disabled with a rpm macro for short circuiting purposes.''',

'macro-in-%changelog',
'''Macros are expanded in %changelog too, which can in unfortunate cases lead
to the package not building at all, or other subtle unexpected conditions that
affect the build.  Even when that doesn\'t happen, the expansion results in
possibly "rewriting history" on subsequent package revisions and generally
odd entries eg. in source rpms, which is rarely wanted.  Avoid use of macros
in %changelog altogether, or use two '%'s to escape them, like '%%foo'.''',

'depscript-without-disabling-depgen',
'''In some common rpm configurations/versions, defining __find_provides and/or
__find_requires has no effect if rpm's internal dependency generator has not
been disabled for the build.  %define _use_internal_dependency_generator to 0
to disable it in the specfile, or don't define __find_provides/requires.''',

'mixed-use-of-spaces-and-tabs',
'''The specfile mixes use of spaces and tabs for indentation, which is a
cosmetic annoyance.  Use either spaces or tabs for indentation, not both.''',

'unversioned-explicit-provides',
'''The specfile contains an unversioned Provides: token, which will match all
older, equal, and newer versions of the provided thing.  This may cause
update problems and will make versioned dependencies, obsoletions and conflicts
on the provided thing useless -- make the Provides versioned if possible.''',

'unversioned-explicit-obsoletes',
'''The specfile contains an unversioned Obsoletes: token, which will match all
older, equal and newer versions of the obsoleted thing.  This may cause update
problems, restrict future package/provides naming, and may match something it
was originally not inteded to match -- make the Obsoletes versioned if
possible.''',

'libdir-macro-in-noarch-package',
'''The %{_libdir} or %{_lib} macro was found in a noarch package in a section
that gets included in binary packages.  This is most likely an error because
these macros are expanded on the build host and their values vary between
architectures, probably resulting in a package that does not work properly
on all architectures at runtime. Investigate whether the package is really
architecture independent or if some other dir/macro should be instead.''',

'non-break-space',
'''The spec file contains a non-break space, which looks like a regular space
in some editors but can lead to obscure errors. It should be replaced by a
regular space.''',

'files-attr-not-set',
'''A file or a directory entry in a %files section does not have attributes
set which may result in unexpected file permissions and thus security issues
in the resulting binary package depending on the build environment and rpmbuild
version (typically < 4.4).  Add default attributes using %defattr before it in
the %files section, or use per entry %attr's.''',

'non-standard-group',
'''The value of the Group tag in the package is not valid.  Valid groups are:
"%s".''' % '", "'.join(VALID_GROUPS),

'specfile-error',
'''This error occurred when rpmlint used rpm to query the specfile.  The error
is output by rpm and the message should contain more information.''',

'comparison-operator-in-deptoken',
'''This dependency token contains a comparison operator (<, > or =).  This is
usually not intended and may be caused by missing whitespace between the
token's name, the comparison operator and the version string.''',

'macro-in-comment',
'''There is a unescaped macro after a shell style comment in the specfile.
Macros are expanded everywhere, so check if it can cause a problem in this
case and escape the macro with another leading % if appropriate.''',

'file-size-mismatch',
'''The size of the file in the package does not match the size indicated by
peeking at its URL.  Verify that the file in the package has the intended
contents.''',

'file-md5-mismatch',
'''The MD5 hash of the file in the package does not match the MD5 hash
indicated by peeking at its URL.  Verify that the file in the package has the
intended contents.''',

'patch-fuzz-is-changed',
'''The internal patch fuzz value was changed, and could hide patchs issues, or
could lead to applying a patch at the wrong location. Usually, this is often
the sign that someone didn't check if a patch is still needed and do not want
to rediff it. It is usually better to rediff the patch and try to send it
upstream.'''
)
示例#32
0
                printWarning(pkg, 'source-or-patch-not-compressed',
                             compress_ext, fname)
            perm = pkgfile.mode & 0o7777
            if perm not in valid_src_perms:
                printWarning(pkg, 'strange-permission', fname, "%o" % perm)


check = SourceCheck()

addDetails(
'multiple-specfiles',
'''Your package contains multiple spec files. To build a
correct package, you need to have only one spec file containing
all your RPM information.''',

'source-or-patch-not-compressed',
'''A source archive or file in your package is not compressed using the %s
compression method (doesn't have the %s extension).''' %
(compress_ext, compress_ext),

'strange-permission',
'''A file that you listed to include in your package has strange
permissions. Usually, a file should have 0644 permissions.''',

'inconsistent-file-extension',
'''The file name extension indicates a different compression format than
what is actually used (as checked by file(1))''',
)

# SourceCheck.py ends here
示例#33
0
        if not res or res[0] != 0:
            if res and res[1]:
                kres = SignatureCheck.unknown_key_regex.search(res[1])
            else:
                kres = None
            if kres:
                printError(pkg, "unknown-key", kres.group(1))
            else:
                Pkg.warn("Error checking signature of %s: %s" %
                         (pkg.filename, res[1]))
        else:
            if not SignatureCheck.pgp_regex.search(res[1]):
                printError(pkg, "no-signature")

# Create an object to enable the auto registration of the test
check = SignatureCheck()

addDetails(
'no-signature',
'''You have to include your pgp or gpg signature in your package.
For more information on signatures, please refer to www.gnupg.org.''',

'unknown-key',
'''The package was signed, but with an unknown key.
See the rpm --import option for more information.''',
)

# SignatureCheck.py ends here

# ex: ts=4 sw=4 et
示例#34
0
                        continue
                    if d in FHSCheck.var_fsstnd:
                        printWarning(pkg, "FSSTND-dir-in-var", fname)
                        var_list.append(d)
                    elif d not in FHSCheck.var_subdir:
                        printWarning(pkg, "non-standard-dir-in-var", d)
                        var_list.append(d)


# Create an object to enable the auto registration of the test
check = FHSCheck()

addDetails(
    'non-standard-dir-in-usr',
    """Your package is creating a non-standard subdirectory in /usr. The standard
directories are:
%s.""" % ", ".join(FHSCheck.usr_subdir),
    'FSSTND-dir-in-var',
    """Your package is creating an illegal directory in /var. The FSSTND (illegal)
ones are:
%s.""" % ", ".join(FHSCheck.var_fsstnd),
    'non-standard-dir-in-var',
    """Your package is creating a non-standard subdirectory in /var. The standard
directories are:
%s.""" % ", ".join(FHSCheck.var_subdir),
)

# FHSCheck.py ends here

# ex: ts=4 sw=4 et
示例#35
0
                printWarning(pkg, 'suse-alternative-link-not-ghost',
                             etc_alt_file)

            # generic-name should be a symlink to /etc/alternatives/$(basename)
            if af not in files:
                printWarning(pkg, 'suse-alternative-generic-name-missing', af)
            elif not stat.S_ISLNK(files[af].mode):
                printWarning(pkg, 'suse-alternative-generic-name-not-symlink',
                             af)

            # TODO check that %post contains --install call
            # TODO check that %preun contains --remove call


check = CheckUpdateAlternatives()

if Config.info:
    addDetails(
        'suse-alternative-generic-name-not-symlink',
        '''The update-alternative generic-name is not a symlink pointing to
%{_sysconfdir}/alternatives/$(basename generic-name).
''', 'suse-alternative-link-not-ghost',
        '''The %{_sysconfdir}/alternatives/$(basename generic-name) link exists but is
not marked as ghost. Mark it as %ghost.''', 'suse-alternative-link-missing',
        '''The file %{_sysconfdir}/alternatives/$(basename generic-name) is missing
in the file list. Mark it as %ghost and add it to the file list.''',
        'suse-alternative-generic-name-missing',
        '''The update-alternatives generic name is not in the filelist. Create it as
a symlink to %{_sysconfdir}/alternatives/$(basename generic-name) and add it
to the file list.''')
示例#36
0
                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()

if Config.info:
    for check in _checks:

        if 'details' not in check:
            continue

        if 'error' not in check:
            continue

        addDetails('suse-filelist-forbidden', """
Your package installs files or directories in a location that have
previously been blacklisted. Please have a look at the particular
file and see if the SUSE Packaging Guidelines propose a better place
on where to install the file or not install it at all.""")

        addDetails(check['error'], check['details'])
addDetails(
'init-script-without-chkconfig-postin',
'''The package contains an init script but doesn't contain a %post with
a call to chkconfig.''',

'postin-without-chkconfig',
'''The package contains an init script but doesn't call chkconfig in its
%post script.''',

'init-script-without-chkconfig-preun',
'''The package contains an init script but doesn't contain a %preun with
a call to chkconfig.''',

'preun-without-chkconfig',
'''The package contains an init script but doesn't call chkconfig in its
%preun script.''',

'missing-lsb-keyword',
'''The package contains an init script that does not contain one of the LSB
init script comment block convention keywords that are recommendable for all
init scripts.  If there is nothing to add to a keyword's value, include the
keyword in the script with an empty value.  Note that as of version 3.2, the
LSB specification does not mandate presence of any keywords.''',

'no-status-entry',
'''In your init script (/etc/rc.d/init.d/your_file), you don't
have a 'status' entry, which is necessary for good functionality.''',

'no-reload-entry',
'''In your init script (/etc/rc.d/init.d/your_file), you don't
have a 'reload' entry, which is necessary for good functionality.''',

'no-chkconfig-line',
'''The init script doesn't contain a chkconfig line to specify the runlevels
at which to start and stop it.''',

'no-default-runlevel',
'''The default runlevel isn't specified in the init script.''',

'service-default-enabled',
'''The service is enabled by default after "chkconfig --add"; for security
reasons, most services should not be. Use "-" as the default runlevel in the
init script's "chkconfig:" line and/or remove the "Default-Start:" LSB keyword
to fix this if appropriate for this service.''',

'subsys-unsupported',
'''The init script uses /var/lock/subsys which is not supported by
this distribution.''',

'subsys-not-used',
'''While your daemon is running, you have to put a lock file in
/var/lock/subsys/. To see an example, look at this directory on your
machine and examine the corresponding init scripts.''',

'incoherent-subsys',
'''The filename of your lock file in /var/lock/subsys/ is incoherent
with your actual init script name. For example, if your script name
is httpd, you have to use 'httpd' as the filename in your subsys directory.
It is also possible that rpmlint gets this wrong, especially if the init
script contains nontrivial shell variables and/or assignments.  These
cases usually manifest themselves when rpmlint reports that the subsys name
starts a with '$'; in these cases a warning instead of an error is reported
and you should check the script manually.''',

'incoherent-init-script-name',
'''The init script name should be the same as the package name in lower case,
or one with 'd' appended if it invokes a process by that name.''',

'init-script-name-with-dot',
'''The init script name should not contain a dot in its name. Some versions
of chkconfig don't work as expected with init script names like that.''',

'init-script-non-executable',
'''The init script should have at least the execution bit set for root
in order for it to run at boot time.''',
)
addDetails(
'suse-branding-branding-conflict',
'''Branding packages should conflict with other flavors of the branding package by using
Conflicts: pkg-branding = brandingversion
and not directly by numerating a name with -branding- in it.''',

'suse-branding-specific-branding-req',
"""packages must not require a specific branding or theme package to allow for different themes""",

'suse-branding-no-branding-provides',
"""Please add a provides entry similar to 'Provides: %name-branding = %version'.""",

'suse-branding-unversioned-provides',
"""Please make sure that your provides entry reads like:
Provides: %name-branding = %version'.""",

'suse-branding-wrong-branding-supplement',
"""For consistency, the branding package should be in the form
Supplements: packageand(basebackage:branding-<flavor>
""",

'suse-branding-supplement-missing',
"""branding packages should provide a supplement in the form
Supplements: packageand(basepackage:branding-<flavour>)
""",

'suse-branding-unversioned-requires',
"""Please make sure that your requires entry is similar to:
Requires: %name-branding = <versionnumber>'.""",

'suse-branding-missing-conflicts',
"""Any branding flavor package that provides the generic branding
must also conflict with all other branding packages via conflict
on the generic branding name""",
)
示例#39
0
addDetails(
'no-spec-file',
'''No spec file was specified in your RPM building. Please specify a valid
SPEC file to build a valid RPM package.''',

'invalid-spec-name',
'''Your spec filename must end with '.spec'. If it's not the case, rename your
file and rebuild your package.''',

'non-utf8-spec-file',
'''The character encoding of the spec file is not UTF-8.  Convert it for
example using iconv(1).''',

'use-of-RPM_SOURCE_DIR',
'''You use $RPM_SOURCE_DIR or %{_sourcedir} in your spec file. If you have to
use a directory for building, use $RPM_BUILD_ROOT instead.''',

'patch-not-applied',
'''A patch is included in your package but was not applied. Refer to the
patches documentation to see what's wrong.''',

'obsolete-tag',
'''The following tags are obsolete: Copyright and Serial. They must
be replaced by License and Epoch respectively.''',

'deprecated-grep',
'''Direct use of grep as egrep or fgrep is deprecated in GNU grep and
historical in POSIX, use grep -E and grep -F instead.''',

'no-buildroot-tag',
'''The BuildRoot tag isn't used in your spec. It must be used in order to
allow building the package as non root on some systems. For some rpm versions
(e.g. rpm.org >= 4.6) the BuildRoot tag is not necessary in specfiles and is
ignored by rpmbuild; if your package is only going to be built with such rpm
versions you can ignore this warning.''',

'hardcoded-path-in-buildroot-tag',
'''A path is hardcoded in your Buildroot tag. It should be replaced
by something like %{_tmppath}/%name-root.''',

'hardcoded-packager-tag',
'''The Packager tag is hardcoded in your spec file. It should be removed, so
as to use rebuilder's own defaults.''',

'buildarch-instead-of-exclusivearch-tag',
'''Use ExclusiveArch instead of BuildArch (or BuildArchitectures)
to restrict build on some specific architectures.
Only use BuildArch with noarch''',

'hardcoded-prefix-tag',
'''The Prefix tag is hardcoded in your spec file. It should be removed, so as
to allow package relocation.''',

'hardcoded-library-path',
'''A library path is hardcoded to one of the following paths: /lib,
/usr/lib. It should be replaced by something like /%{_lib} or %{_libdir}.''',

'configure-without-libdir-spec',
'''A configure script is run without specifying the libdir. configure
options must be augmented with something like --libdir=%{_libdir} whenever
the script supports it.''',

'no-%prep-section',
'''The spec file does not contain a %prep section.  Even if some packages don't
directly need it, section markers may be overridden in rpm's configuration
to provide additional "under the hood" functionality.  Add the section, even
if empty.''',

'no-%build-section',
'''The spec file does not contain a %build section.  Even if some packages
don't directly need it, section markers may be overridden in rpm's
configuration to provide additional "under the hood" functionality, such as
injection of automatic -debuginfo subpackages.  Add the section, even if
empty.''',

'no-%install-section',
'''The spec file does not contain an %install section.  Even if some packages
don't directly need it, section markers may be overridden in rpm's
configuration to provide additional "under the hood" functionality.  Add the
section, even if empty.''',

'no-%clean-section',
'''The spec file doesn't contain a %clean section to remove the files installed
by the %install section.''',

'more-than-one-%changelog-section',
'''The spec file unnecessarily contains more than one %changelog section;
remove the extra ones.''',

'lib-package-without-%mklibname',
'''The package name must be built using %mklibname to allow lib64 and lib32
coexistence.''',

'%ifarch-applied-patch',
'''A patch is applied inside an %ifarch block. Patches must be applied
on all architectures and may contain necessary configure and/or code
patch to be effective only on a given arch.''',

'prereq-use',
'''The use of PreReq is deprecated. In the majority of cases, a plain Requires
is enough and the right thing to do. Sometimes Requires(pre), Requires(post),
Requires(preun) and/or Requires(postun) can also be used instead of PreReq.''',

'buildprereq-use',
'''The use of BuildPreReq is deprecated, build dependencies are always required
before a package can be built.  Use plain BuildRequires instead.''',

'broken-syntax-in-scriptlet-requires',
'''Comma separated context marked dependencies are silently broken in some
versions of rpm.  One way to work around it is to split them into several ones,
eg. replace "Requires(post,preun): foo" with "Requires(post): foo" and
"Requires(preun): foo".''',

'setup-not-in-prep',
'''The %setup macro should only be used within the %prep section because it may
not expand to anything outside of it and can break the build in unpredictable
ways.''',

'setup-not-quiet',
'''Use the -q option to the %setup macro to avoid useless build output from
unpacking the sources.''',

'no-cleaning-of-buildroot',
'''You should clean $RPM_BUILD_ROOT in the %clean section and in the beginning
of the %install section. Use "rm -rf $RPM_BUILD_ROOT". Some rpm configurations
do this automatically; if your package is only going to be built in such
configurations, you can ignore this warning for the section(s) where your rpm
takes care of it.''',

'rpm-buildroot-usage',
'''$RPM_BUILD_ROOT should not be touched during %build or %prep stage, as it
may break short circuit builds.''',

'make-check-outside-check-section',
'''Make check or other automated regression test should be run in %check, as
they can be disabled with a rpm macro for short circuiting purposes.''',

'macro-in-%changelog',
'''Macros are expanded in %changelog too, which can in unfortunate cases lead
to the package not building at all, or other subtle unexpected conditions that
affect the build.  Even when that doesn\'t happen, the expansion results in
possibly "rewriting history" on subsequent package revisions and generally
odd entries eg. in source rpms, which is rarely wanted.  Avoid use of macros
in %changelog altogether, or use two '%'s to escape them, like '%%foo'.''',

'depscript-without-disabling-depgen',
'''In some common rpm configurations/versions, defining __find_provides and/or
__find_requires has no effect if rpm's internal dependency generator has not
been disabled for the build.  %define _use_internal_dependency_generator to 0
to disable it in the specfile, or don't define __find_provides/requires.''',

'mixed-use-of-spaces-and-tabs',
'''The specfile mixes use of spaces and tabs for indentation, which is a
cosmetic annoyance.  Use either spaces or tabs for indentation, not both.''',

'unversioned-explicit-provides',
'''The specfile contains an unversioned Provides: token, which will match all
older, equal, and newer versions of the provided thing.  This may cause
update problems and will make versioned dependencies, obsoletions and conflicts
on the provided thing useless -- make the Provides versioned if possible.''',

'unversioned-explicit-obsoletes',
'''The specfile contains an unversioned Obsoletes: token, which will match all
older, equal and newer versions of the obsoleted thing.  This may cause update
problems, restrict future package/provides naming, and may match something it
was originally not inteded to match -- make the Obsoletes versioned if
possible.''',

'libdir-macro-in-noarch-package',
'''The %{_libdir} or %{_lib} macro was found in a noarch package in a section
that gets included in binary packages.  This is most likely an error because
these macros are expanded on the build host and their values vary between
architectures, probably resulting in a package that does not work properly
on all architectures at runtime. Investigate whether the package is really
architecture independent or if some other dir/macro should be instead.''',

'non-break-space',
'''The spec file contains a non-break space, which looks like a regular space
in some editors but can lead to obscure errors. It should be replaced by a
regular space.''',

'non-standard-group',
'''The value of the Group tag in the package is not valid.  Valid groups are:
"%s".''' % '", "'.join(VALID_GROUPS),

'specfile-error',
'''This error occurred when rpmlint used rpm to query the specfile.  The error
is output by rpm and the message should contain more information.''',

'comparison-operator-in-deptoken',
'''This dependency token contains a comparison operator (<, > or =).  This is
usually not intended and may be caused by missing whitespace between the
token's name, the comparison operator and the version string.''',

'macro-in-comment',
'''There is a unescaped macro after a shell style comment in the specfile.
Macros are expanded everywhere, so check if it can cause a problem in this
case and escape the macro with another leading % if appropriate.''',

'file-size-mismatch',
'''The size of the file in the package does not match the size indicated by
peeking at its URL.  Verify that the file in the package has the intended
contents.''',

'file-md5-mismatch',
'''The MD5 hash of the file in the package does not match the MD5 hash
indicated by peeking at its URL.  Verify that the file in the package has the
intended contents.''',

'patch-fuzz-is-changed',
'''The internal patch fuzz value was changed, and could hide patchs issues, or
could lead to applying a patch at the wrong location. Usually, this is often
the sign that someone didn't check if a patch is still needed and do not want
to rediff it. It is usually better to rediff the patch and try to send it
upstream.'''
)
示例#40
0
# Create an object to enable the auto registration of the test
check = DistributionCheck()

addDetails(
'invalid-vendor',
'In the "%s" distribution, vendor should be "%s".' % (distribution, vendor),

'invalid-distribution',
'The distribution value should be "' + distribution + '".',

'manpage-not-compressed',
'''This manual page is not compressed with the %s compression method
(does not have the %s extension). If the compression does not happen
automatically when the package is rebuilt, make sure that you have the
appropriate rpm helper and/or config packages for your target distribution
installed and try rebuilding again; if it still does not happen automatically,
you can compress this file in the %%install section of the spec file.'''
% (compress_ext, compress_ext),

'infopage-not-compressed',
'''This info page is not compressed with the %s compression method
(does not have the %s extension). If the compression does not happen
automatically when the package is rebuilt, make sure that you have the
appropriate rpm helper and/or config packages for your target distribution
installed and try rebuilding again; if it still does not happen automatically,
you can compress this file in the %%install section of the spec file.'''
% (compress_ext, compress_ext),
)

# DistributionCheck.py ends here
示例#41
0
文件: MenuCheck.py 项目: Fak3/rpmlint
addDetails(
'non-file-in-menu-dir',
'''/usr/lib/menu must not contain anything else than normal files.''',

'non-coherent-menu-filename',
'''The menu file name should be /usr/lib/menu/<package>.''',

'non-readable-menu-file',
'''The menu file isn't readable. Check the permissions.''',

'old-menu-entry',
'''
''',

'non-transparent-xpm',
'''xpm icon should be transparent for use in menus.''',

'menu-without-postin',
'''A menu file exists in the package but no %post scriptlet is present to call
update-menus.''',

'postin-without-update-menus',
'''A menu file exists in the package but its %post scriptlet doesn't call
update-menus.''',

'menu-without-postun',
'''A menu file exists in the package but no %postun scriptlet is present to
call update-menus.''',

'postun-without-update-menus',
'''A menu file exists in the package but its %postun scriptlet doesn't call
update-menus.''',

'incoherent-package-value-in-menu',
'''The package field of the menu entry isn't the same as the package name.''',

'use-of-launcher-in-menu-but-no-requires-on',
'''The menu command uses a launcher but there is no dependency in the package
that contains it.''',

'menu-command-not-in-package',
'''The command used in the menu isn't included in the package.''',

'menu-longtitle-not-capitalized',
'''The longtitle field of the menu doesn't start with a capital letter.''',

'version-in-menu-longtitle',
'''The longtitle filed of the menu entry contains a version. This is bad
because it will be prone to error when the version of the package changes.''',

'no-longtitle-in-menu',
'''The longtitle field isn't present in the menu entry.''',

'menu-title-not-capitalized',
'''The title field of the menu entry doesn't start with a capital letter.''',

'version-in-menu-title',
'''The title filed of the menu entry contains a version. This is bad
because it will be prone to error when the version of the package changes.''',

'no-title-in-menu',
'''The title field isn't present in the menu entry.''',

'invalid-menu-section',
'''The section field of the menu entry isn't standard.''',

'unable-to-parse-menu-section',
'''rpmlint wasn't able to parse the menu section. Please report.''',

'hardcoded-path-in-menu-icon',
'''The path of the icon is hardcoded in the menu entry. This prevent multiple
sizes of the icon from being found.''',

'normal-icon-not-in-package',
'''The normal icon isn't present in the package.''',

'mini-icon-not-in-package',
'''The mini icon isn't present in the package.''',

'large-icon-not-in-package',
'''The large icon isn't present in the package.''',

'no-icon-in-menu',
'''The menu entry doesn't contain an icon field.''',

'invalid-title',
'''The menu title contains invalid characters like /.''',

'missing-menu-command',
'''The menu file doesn't contain a command.''',

'menu-in-wrong-directory',
'''The menu files must be under /usr/lib/menu.''',

'non-xdg-migrated-menu',
'''The menu file has not been migrated to new XDG menu system.''',

)
示例#42
0
addDetails(
    'undeclared-scl',
    '''Specfile contains %scl* macros, but was not recognized as SCL metapackage or
SCL ready package. If this should be an SCL metapackage, don't forget to define
the %scl macro. If this should be an SCL ready package, run %scl
conditionalized %scl_package macro, e.g. %{?scl:%scl_package foo}.''',
    'no-runtime-in-scl-metapackage',
    'SCL metapackage must have runtime subpackage.',
    'no-build-in-scl-metapackage',
    'SCL metapackage must have build subpackage.',
    'weird-subpackage-in-scl-metapackage',
    'Only allowed subpackages in SCL metapackage are build and runtime.',
    'scl-metapackage-without-scl-utils-build-br',
    'SCL metapackage must BuildRequire scl-utils-build.',
    'scl-build-without-requiring-scl-utils-build',
    'SCL runtime package should Require scl-utils-build.',
    'scl-metapackage-without-%scl_install',
    'SCL metapackage must call %scl_install in the %install section.',
    'noarch-scl-metapackage-with-libdir',
    '''If "enable" script of SCL metapackage contains %{_libdir}, the package must
be arch specific, otherwise it may be noarch.''',
    'scl-main-metapackage-contains-files',
    'Main package of SCL metapackage should not contain any files.',
    'scl-runtime-package-without-%scl_files',
    'SCL runtime package must contain %scl_files in %files section.',
    'scl-build-package-without-rpm-macros',
    '''SCL build package must contain %{_root_sysconfdir}/rpm/macros. %{scl}-config
in %files section.''',
    'missing-pkg_name-definition',
    '%{!?scl:%global pkg_name %{name}} is missing in the specfile.',
    'name-without-scl-prefix',
    'Name of SCL package must start with %{?scl_prefix}.',
    'scl-prefix-without-condition',
    '''The SCL prefix is used without condition - this won't work if the package is
build outside of SCL - use %{?scl_prefix} with questionmark.''',
    'obsoletes-or-conflicts-without-scl-prefix',
    '''Obsoletes, Conflicts and Build Conflicts must always be prefixed with
%{?scl_prefix}. This is extremely important, as the SCLs are often used for
deploying new packages on older systems (that may contain old packages, now
obsoleted by the new ones), but they shouldn't Obsolete or Conflict with the
non-SCL RPMs installed on the system (that's the idea of SCL).''',
    'provides-without-scl-prefix',
    'Provides tag must always be prefixed with %{?scl_prefix}.',
    'doesnt-require-scl-runtime-or-other-scl-package',
    '''The package must require %{scl}-runtime, unless it depends on another
package that requires %{scl}-runtime. It's impossible to check what other
packages require, so this simply checks if this package requires at least
something from its collection.''',
    'subpackage-with-n-without-scl-prefix',
    '''If (and only if) a package defines its name with -n, the name must be
prefixed with %{?scl_prefix}.''',
    'scl-setup-without-n',
    '''The %setup macro needs the -n argument for SCL builds, because the directory
with source probably doesn't include SCL prefix in its name.''',
    'scl-name-screwed-up',
    '''SCL package's name starts with SCL prefix. That prefix is used as a
directory, where files are stored: If the prefix is foo, the directory is
/opt/provides/foo. This package doesn't respect that. This means either the
name of the package is wrong, or the directory.''',
    'file-outside-of-scl-tree',
    '''SCL package should only contain files in /opt/provider/scl-name directory or
in other allowed directories such as some directories in /etc or /var. Wrapper
scripts in /usr/bin are also allowed.''',
    'scl-rpm-macros-outside-of-build',
    '''RPM macros in SCL packages should belong to -build subpackage of the SCL
metapackage.''',
)
示例#43
0
addDetails(
    'non-file-in-menu-dir',
    '''/usr/lib/menu must not contain anything else than normal files.''',
    'non-coherent-menu-filename',
    '''The menu file name should be /usr/lib/menu/<package>.''',
    'non-readable-menu-file',
    '''The menu file isn't readable. Check the permissions.''',
    'old-menu-entry',
    '''
''',
    'non-transparent-xpm',
    '''xpm icon should be transparent for use in menus.''',
    'menu-without-postin',
    '''A menu file exists in the package but no %post scriptlet is present to call
update-menus.''',
    'postin-without-update-menus',
    '''A menu file exists in the package but its %post scriptlet doesn't call
update-menus.''',
    'menu-without-postun',
    '''A menu file exists in the package but no %postun scriptlet is present to
call update-menus.''',
    'postun-without-update-menus',
    '''A menu file exists in the package but its %postun scriptlet doesn't call
update-menus.''',
    'incoherent-package-value-in-menu',
    '''The package field of the menu entry isn't the same as the package name.''',
    'use-of-launcher-in-menu-but-no-requires-on',
    '''The menu command uses a launcher but there is no dependency in the package
that contains it.''',
    'menu-command-not-in-package',
    '''The command used in the menu isn't included in the package.''',
    'menu-longtitle-not-capitalized',
    '''The longtitle field of the menu doesn't start with a capital letter.''',
    'version-in-menu-longtitle',
    '''The longtitle filed of the menu entry contains a version. This is bad
because it will be prone to error when the version of the package changes.''',
    'no-longtitle-in-menu',
    '''The longtitle field isn't present in the menu entry.''',
    'menu-title-not-capitalized',
    '''The title field of the menu entry doesn't start with a capital letter.''',
    'version-in-menu-title',
    '''The title filed of the menu entry contains a version. This is bad
because it will be prone to error when the version of the package changes.''',
    'no-title-in-menu',
    '''The title field isn't present in the menu entry.''',
    'invalid-menu-section',
    '''The section field of the menu entry isn't standard.''',
    'unable-to-parse-menu-section',
    '''rpmlint wasn't able to parse the menu section. Please report.''',
    'hardcoded-path-in-menu-icon',
    '''The path of the icon is hardcoded in the menu entry. This prevent multiple
sizes of the icon from being found.''',
    'normal-icon-not-in-package',
    '''The normal icon isn't present in the package.''',
    'mini-icon-not-in-package',
    '''The mini icon isn't present in the package.''',
    'large-icon-not-in-package',
    '''The large icon isn't present in the package.''',
    'no-icon-in-menu',
    '''The menu entry doesn't contain an icon field.''',
    'invalid-title',
    '''The menu title contains invalid characters like /.''',
    'missing-menu-command',
    '''The menu file doesn't contain a command.''',
    'menu-in-wrong-directory',
    '''The menu files must be under /usr/lib/menu.''',
    'non-xdg-migrated-menu',
    '''The menu file has not been migrated to new XDG menu system.''',
)
示例#44
0
appdata_checker = Config.getOption("AppDataChecker", DEFAULT_APPDATA_CHECKER)


class AppDataCheck(AbstractCheck.AbstractFilesCheck):
    def __init__(self):
        # desktop file need to be in $XDG_DATA_DIRS
        # $ echo $XDG_DATA_DIRS/applications
        # /var/lib/menu-xdg:/usr/share
        AbstractCheck.AbstractFilesCheck.__init__(
            self, "AppDataCheck", r"/usr/share/appdata/.*\.appdata.xml$")

    def check_file(self, pkg, filename):
        root = pkg.dirName()
        f = root + filename
        try:
            st = getstatusoutput(appdata_checker + (f, ))
        except OSError:
            # ignore if the checker is not installed
            return
        if st[0]:
            printError(pkg, 'invalid-appdata-file', filename)


check = AppDataCheck()

addDetails(
    'invalid-appdata-file',
    '''appdata file is not valid, check with %s''' %
    (" ".join(appdata_checker)),
)
示例#45
0
addDetails(
    'init-script-without-chkconfig-postin',
    '''The package contains an init script but doesn't contain a %post with
a call to chkconfig.''',
    'postin-without-chkconfig',
    '''The package contains an init script but doesn't call chkconfig in its
%post script.''',
    'init-script-without-chkconfig-preun',
    '''The package contains an init script but doesn't contain a %preun with
a call to chkconfig.''',
    'preun-without-chkconfig',
    '''The package contains an init script but doesn't call chkconfig in its
%preun script.''',
    'missing-lsb-keyword',
    '''The package contains an init script that does not contain one of the LSB
init script comment block convention keywords that are recommendable for all
init scripts.  If there is nothing to add to a keyword's value, include the
keyword in the script with an empty value.  Note that as of version 3.2, the
LSB specification does not mandate presence of any keywords.''',
    'no-status-entry',
    '''In your init script (/etc/rc.d/init.d/your_file), you don't
have a 'status' entry, which is necessary for good functionality.''',
    'no-reload-entry',
    '''In your init script (/etc/rc.d/init.d/your_file), you don't
have a 'reload' entry, which is necessary for good functionality.''',
    'no-chkconfig-line',
    '''The init script doesn't contain a chkconfig line to specify the runlevels
at which to start and stop it.''',
    'no-default-runlevel',
    '''The default runlevel isn't specified in the init script.''',
    'service-default-enabled',
    '''The service is enabled by default after "chkconfig --add"; for security
reasons, most services should not be. Use "-" as the default runlevel in the
init script's "chkconfig:" line and/or remove the "Default-Start:" LSB keyword
to fix this if appropriate for this service.''',
    'subsys-unsupported',
    '''The init script uses /var/lock/subsys which is not supported by
this distribution.''',
    'subsys-not-used',
    '''While your daemon is running, you have to put a lock file in
/var/lock/subsys/. To see an example, look at this directory on your
machine and examine the corresponding init scripts.''',
    'incoherent-subsys',
    '''The filename of your lock file in /var/lock/subsys/ is incoherent
with your actual init script name. For example, if your script name
is httpd, you have to use 'httpd' as the filename in your subsys directory.
It is also possible that rpmlint gets this wrong, especially if the init
script contains nontrivial shell variables and/or assignments.  These
cases usually manifest themselves when rpmlint reports that the subsys name
starts a with '$'; in these cases a warning instead of an error is reported
and you should check the script manually.''',
    'incoherent-init-script-name',
    '''The init script name should be the same as the package name in lower case,
or one with 'd' appended if it invokes a process by that name.''',
    'init-script-name-with-dot',
    '''The init script name should not contain a dot in its name. Some versions
of chkconfig don't work as expected with init script names like that.''',
    'init-script-non-executable',
    '''The init script should have at least the execution bit set for root
in order for it to run at boot time.''',
)
示例#46
0
            printError(pkg, 'non-lsb-compliant-version', version)

        release = pkg[rpm.RPMTAG_RELEASE]
        if release and not version_regex.search(release):
            printError(pkg, 'non-lsb-compliant-release', release)

# Create an object to enable the auto registration of the test
check = LSBCheck()

addDetails(
'non-lsb-compliant-package-name',
"""Your package name contains an illegal character. Use only
alphanumeric symbols in your package name.""",

'non-lsb-compliant-version',
"""Your version number contains an illegal character. Use only
lowercase letters and/or numbers.""",

'non-lsb-compliant-release',
"""Your version number contains an illegal character. Use only
lowercase letters and/or numbers.""",

)

# LSBCheck.py ends here

# Local variables:
# indent-tabs-mode: nil
# py-indent-offset: 4
# End:
# ex: ts=4 sw=4 et
addDetails(
'undeclared-scl',
'''Specfile contains %scl* macros, but was not recognized as SCL metapackage or
SCL ready package. If this should be an SCL metapackage, don't forget to define
the %scl macro. If this should be an SCL ready package, run %scl
conditionalized %scl_package macro, e.g. %{?scl:%scl_package foo}.''',

'no-runtime-in-scl-metapackage',
'SCL metapackage must have runtime subpackage.',

'no-build-in-scl-metapackage',
'SCL metapackage must have build subpackage.',

'weird-subpackage-in-scl-metapackage',
'Only allowed subpackages in SCL metapackage are build and runtime.',

'scl-metapackage-without-scl-utils-build-br',
'SCL metapackage must BuildRequire scl-utils-build.',

'scl-build-without-requiring-scl-utils-build',
'SCL runtime package should Require scl-utils-build.',

'scl-metapackage-without-%scl_install',
'SCL metapackage must call %scl_install in the %install section.',

'noarch-scl-metapackage-with-libdir',
'''If "enable" script of SCL metapackage contains %{_libdir}, the package must
be arch specific, otherwise it may be noarch.''',

'scl-main-metapackage-contains-files',
'Main package of SCL metapackage should not contain any files.',

'scl-runtime-package-without-%scl_files',
'SCL runtime package must contain %scl_files in %files section.',

'scl-build-package-without-rpm-macros',
'''SCL build package must contain %{_root_sysconfdir}/rpm/macros. %{scl}-config
in %files section.''',

'missing-pkg_name-definition',
'%{!?scl:%global pkg_name %{name}} is missing in the specfile.',

'name-without-scl-prefix',
'Name of SCL package must start with %{?scl_prefix}.',

'scl-prefix-without-condition',
'''The SCL prefix is used without condition - this won't work if the package is
build outside of SCL - use %{?scl_prefix} with questionmark.''',

'obsoletes-or-conflicts-without-scl-prefix',
'''Obsoletes, Conflicts and Build Conflicts must always be prefixed with
%{?scl_prefix}. This is extremely important, as the SCLs are often used for
deploying new packages on older systems (that may contain old packages, now
obsoleted by the new ones), but they shouldn't Obsolete or Conflict with the
non-SCL RPMs installed on the system (that's the idea of SCL).''',

'provides-without-scl-prefix',
'Provides tag must always be prefixed with %{?scl_prefix}.',

'doesnt-require-scl-runtime-or-other-scl-package',
'''The package must require %{scl}-runtime, unless it depends on another
package that requires %{scl}-runtime. It's impossible to check what other
packages require, so this simply checks if this package requires at least
something from its collection.''',

'subpackage-with-n-without-scl-prefix',
'''If (and only if) a package defines its name with -n, the name must be
prefixed with %{?scl_prefix}.''',

'scl-setup-without-n',
'''The %setup macro needs the -n argument for SCL builds, because the directory
with source probably doesn't include SCL prefix in its name.''',

'scl-name-screwed-up',
'''SCL package's name starts with SCL prefix. That prefix is used as a
directory, where files are stored: If the prefix is foo, the directory is
/opt/provides/foo. This package doesn't respect that. This means either the
name of the package is wrong, or the directory.''',

'file-outside-of-scl-tree',
'''SCL package should only contain files in /opt/provider/scl-name directory or
in other allowed directories such as some directories in /etc or /var. Wrapper
scripts in /usr/bin are also allowed.''',

'scl-rpm-macros-outside-of-build',
'''RPM macros in SCL packages should belong to -build subpackage of the SCL
metapackage.''',
)
示例#48
0
                    printWarning(pkg, 'ghost-files-without-postin')
                if (not postin or f not in postin) and \
                        (not prein or f not in prein):
                    printWarning(pkg,
                                 'postin-without-ghost-file-creation', f)


check = TmpFilesCheck()

addDetails(
'postin-without-ghost-file-creation',
'''A file tagged as ghost is not created during %prein nor during %postin.''',

'postin-without-tmpfile-creation',
'''Please use the %tmpfiles_create macro in %post for each of your
tmpfiles.d files''',

'tmpfile-not-regular-file',
'''files in tmpfiles.d need to be regular files''',

'tmpfile-not-in-filelist',
'''please add the specified file to your %files section as %ghost so
users can easily query who created the file, it gets uninstalled on
package removal and finally other rpmlint checks see it''',

'tmpfile-not-ghost',
'''the specified file is not marked as %ghost although created at
runtime via tmpfiles mechanism.'''
)
# vim: sw=4 et
    addDetails(
        "shlib-policy-missing-suffix",
        """Your package containing shared libraries does not end in a digit and
should probably be split.""",
        "shlib-policy-devel-file",
        """Your shared library package contains development files. Split them into
a -devel subpackage.""",
        "shlib-policy-name-error",
        """Your package contains a single shared library but is not named after its SONAME.""",
        "shlib-policy-nonversioned-dir",
        """Your shared library package contains non-versioned directories. Those will not
allow to install multiple versions of the package in parallel.""",
        "shlib-legacy-policy-name-error",
        """Your shared library package is not named after its SONAME, but it has been added to the list
of legacy exceptions. Please do not rename the package until SONAME changes, but if you have
to rename it for another reason, make sure you name it correctly.""",
        "shlib-policy-excessive-dependency",
        """Your package starts with 'lib' as part of its name, but also contains binaries
that have more dependencies than those that already required by the libraries.
Those binaries should probably not be part of the library package, but split into
a seperate one to reduce the additional dependencies for other users of this library.""",
        "shlib-policy-missing-lib",
        """Your package starts with 'lib' as part of its name, but does not provide
any libraries. It must not be called a lib-package then. Give it a more
sensible name.""",
        "shlib-fixed-dependency",
        """Your shared library package requires a fixed version of another package. The
intention of the Shared Library Policy is to allow parallel installation of
multiple versions of the same shared library, hard dependencies likely make that
impossible. Please remove this dependency and instead move it to the runtime uses
of your library.""",
        "shlib-unversioned-lib",
        """Your package matches the Shared Library Policy Naming Scheme but contains an
unversioned library. Therefore it is very unlikely that your package can be installed
in parallel to another version of this library package. Consider moving unversioned
parts into a runtime package.""",
    )
示例#50
0
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import os

import AbstractCheck
from Filter import addDetails, printWarning


class RpmFileCheck(AbstractCheck.AbstractCheck):
    def __init__(self):
        AbstractCheck.AbstractCheck.__init__(self, "RpmFileCheck")

    def check(self, pkg):
        # http://en.wikipedia.org/wiki/Joliet_(file_system)
        rpmfile_name = os.path.basename(pkg.filename)
        if len(rpmfile_name) > 64:
            printWarning(pkg, 'filename-too-long-for-joliet', rpmfile_name)


check = RpmFileCheck()

addDetails(
    'filename-too-long-for-joliet',
    '''This filename is too long to fit on a joliet filesystem (limit is 64 unicode
chars).''',
)
示例#51
0
            elif prog.endswith('sh'):
                res = single_command_regex.search(script)
                if res:
                    printWarning(pkg, 'one-line-command-in-' + tag,
                                 res.group(1))

        elif prog not in empty_shells and prog in valid_shells:
            printWarning(pkg, 'empty-' + tag)


# Create an object to enable the auto registration of the test
check = PostCheck()

# Add information about checks
addDetails(
    'postin-without-ghost-file-creation',
    '''A file tagged as ghost is not created during %prein nor during %postin.''',
)
for scriptlet in map(lambda x: '%' + x, RPM_SCRIPTLETS):
    addDetails(
        'one-line-command-in-%s' % scriptlet,
        '''You should use %s -p <command> instead of using:

%s
<command>

It will avoid the fork of a shell interpreter to execute your command as
well as allows rpm to automatically mark the dependency on your command
for the execution of the scriptlet.''' % (scriptlet, scriptlet),
        'percent-in-%s' % scriptlet,
        '''The %s scriptlet contains a "%%" in a context which might indicate it being
fallout from an rpm macro/variable which was not expanded during build.
示例#52
0
# Purpose         : Apply pam policy
#############################################################################

import re

import AbstractCheck
from Filter import addDetails, printError


pam_stack_re = re.compile(r'^\s*[^#].*pam_stack\.so\s*service')


class PamCheck(AbstractCheck.AbstractFilesCheck):
    def __init__(self):
        AbstractCheck.AbstractFilesCheck.__init__(self, "PamCheck",
                                                  r"/etc/pam\.d/.*")

    def check_file(self, pkg, filename):
        lines = pkg.grep(pam_stack_re, filename)
        if lines:
            printError(pkg, 'use-old-pam-stack', filename,
                       '(line %s)' % ", ".join(lines))


check = PamCheck()

addDetails(
'use-old-pam-stack',
'''Update pam file to use include instead of pam_stack.''',
)
addDetails(
    'arch-independent-package-contains-binary-or-object',
    '''The package contains a binary or object file but is tagged
noarch.''',
    'arch-dependent-file-in-usr-share',
    '''This package installs an ELF binary in the /usr/share
 hierarchy, which is reserved for architecture-independent files.''',
    'binary-in-etc',
    '''This package installs an ELF binary in /etc.  Both the
FHS and the FSSTND forbid this.''',

    # 'non-sparc32-binary',
    # '',
    'invalid-soname',
    '''The soname of the library is neither of the form lib<libname>.so.<major> or
lib<libname>-<major>.so.''',
    'invalid-ldconfig-symlink',
    '''The symbolic link references the wrong file. It should reference
the shared library.''',
    'no-ldconfig-symlink',
    '''The package should not only include the shared library itself, but
also the symbolic link which ldconfig would produce. (This is
necessary, so that the link gets removed by rpm automatically when
the package gets removed, even if for some reason ldconfig would not be
run at package postinstall phase.)''',
    'shlib-with-non-pic-code',
    '''The listed shared libraries contain object code that was compiled
without -fPIC. All object code in shared libraries should be
recompiled separately from the static libraries with the -fPIC option.

Another common mistake that causes this problem is linking with
``gcc -Wl,-shared'' instead of ``gcc -shared''.''',
    'binary-or-shlib-defines-rpath',
    '''The binary or shared library defines `RPATH'. Usually this is a
bad thing because it hardcodes the path to search libraries and so
makes it difficult to move libraries around.  Most likely you will find a
Makefile with a line like: gcc test.o -o test -Wl,--rpath.  Also, sometimes
configure scripts provide a --disable-rpath flag to avoid this.''',
    'statically-linked-binary',
    '''The package installs a statically linked binary or object file.

Usually this is a packaging bug. If not, contact your rpmlint distributor
about this so that this error gets included in the exception file for rpmlint
and will not be flagged as a packaging bug in the future (or add it to your
local configuration if you installed rpmlint from the source tarball).''',
    'executable-in-library-package',
    '''The package mixes up libraries and executables. Mixing up these
both types of files makes upgrades quite impossible.''',
    'non-versioned-file-in-library-package',
    '''The package contains files in non versioned directories. This makes it
impossible to have multiple major versions of the libraries installed.
One solution can be to change the directories which contain the files
to subdirs of /usr/lib/<name>-<version> or /usr/share/<name>-<version>.
Another solution can be to include a version number in the file names
themselves.''',
    'incoherent-version-in-name',
    '''The package name should contain the major version of the library.''',
    'invalid-directory-reference',
    'This file contains a reference to /tmp or /home.',
    'no-binary',
    '''The package should be of the noarch architecture because it doesn't contain
any binaries.''',

    # http://sources.redhat.com/ml/libc-alpha/2003-05/msg00034.html
    'undefined-non-weak-symbol',
    '''The binary contains undefined non-weak symbols.  This may indicate improper
linkage; check that the binary has been linked as expected.''',

    # http://www.redhat.com/archives/fedora-maintainers/2006-June/msg00176.html
    'unused-direct-shlib-dependency',
    '''The binary contains unused direct shared library dependencies.  This may
indicate gratuitously bloated linkage; check that the binary has been linked
with the intended shared libraries only.''',
    'only-non-binary-in-usr-lib',
    '''There are only non binary files in /usr/lib so they should be in
/usr/share.''',
    'binaryinfo-readelf-failed',
    '''Executing readelf on this file failed, all checks could not be run.''',
    'binaryinfo-tail-failed',
    '''Reading trailing bytes of this file failed, all checks could not be run.''',
    'ldd-failed',
    '''Executing ldd on this file failed, all checks could not be run.''',
    'executable-stack',
    '''The binary declares the stack as executable.  Executable stack is usually an
error as it is only needed if the code contains GCC trampolines or similar
constructs which uses code on the stack.  One common source for needlessly
executable stack cases are object files built from assembler files which
don\'t define a proper .note.GNU-stack section.''',
    'missing-PT_GNU_STACK-section',
    '''The binary lacks a PT_GNU_STACK section.  This forces the dynamic linker to
make the stack executable.  Usual suspects include use of a non-GNU linker or
an old GNU linker version.''',
    'shared-lib-calls-exit',
    '''This library package calls exit() or _exit(), probably in a non-fork()
context. Doing so from a library is strongly discouraged - when a library
function calls exit(), it prevents the calling program from handling the
error, reporting it to the user, closing files properly, and cleaning up any
state that the program has. It is preferred for the library to return an
actual error code and let the calling program decide how to handle the
situation.''',
    'ocaml-mixed-executable',
    '''Executables built with ocamlc -custom are deprecated.  Packagers should ask
upstream maintainers to build these executables without the -custom option.  If
this cannot be changed and the executable needs to be packaged in its current
form, make sure that rpmbuild does not strip it during the build, and on setups
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''',
    'non-position-independent-executable',
    '''This executable must be position independent.  Check that it is built with
-fPIE/-fpie in compiler flags and -pie in linker flags.''',
    'missing-call-to-setgroups-before-setuid',
    '''This executable is calling setuid and setgid without setgroups or
initgroups. There is a high probability this means it didn't relinquish all
groups, and this would be a potential security issue to be fixed. Seek POS36-C
on the web for details about the problem.''',
    'missing-call-to-chdir-with-chroot',
    '''This executable appears to call chroot without using chdir to change the
current directory. This is likely an error and permits an attacker to break out
of the chroot by using fchdir. While that's not always a security issue, this
has to be checked.''',
    'call-to-mktemp',
    '''This executable calls mktemp. As advised by the manpage (mktemp(3)), this
function should be avoided. Some implementations are deeply insecure, and there
is a race condition between the time of check and time of use (TOCTOU).
See http://capec.mitre.org/data/definitions/29.html for details, and contact
upstream to have this issue fixed.''',
    'unstripped-binary-or-object',
    '''This executable should be stripped from debugging symbols, in order to take
less space and be loaded faster. This is usually done automatically at
buildtime by rpm. Check the build logs and the permission on the file (some
implementations only strip if the permission is 0755).''')
示例#54
0
        if binary:
            found = False
            if binary.startswith('/'):
                found = os.path.exists(root + binary)
            else:
                for i in STANDARD_BIN_DIRS:
                    if os.path.exists(root + i + binary):
                        # no need to check if the binary is +x, rpmlint does it
                        # in another place
                        found = True
                        break
            if not found:
                printWarning(pkg, 'desktopfile-without-binary', filename,
                             binary)

check = MenuXDGCheck()

addDetails(
'invalid-desktopfile',
'''.desktop file is not valid, check with desktop-file-validate''',

'non-utf8-desktopfile',
'''.desktop file is not encoded in UTF-8''',

'desktopfile-without-binary',
'''the .desktop file is for a file not present in the package. You
should check the requires or see if this is not a error''',
)

# ex: ts=4 sw=4 et
示例#55
0
            elif not c.startswith("/etc/") and not c.startswith("/var/"):
                printWarning(pkg, "non-etc-or-var-file-marked-as-conffile", c)

            if c not in noreplace_files:
                printWarning(pkg, "conffile-without-noreplace-flag", c)


# Create an object to enable the auto registration of the test
check = ConfigCheck()

# Add information about checks
addDetails(
'score-file-must-not-be-conffile',
"""A file in /var/lib/games/ is a configuration file. Store your conf
files in /etc instead.""",

'non-etc-or-var-file-marked-as-conffile',
"""A file not in /etc or /var is marked as being a configuration file.
Please put your conf files in /etc or /var.""",

'conffile-without-noreplace-flag',
"""A configuration file is stored in your package without the noreplace flag.
A way to resolve this is to put the following in your SPEC file:

%config(noreplace) /etc/your_config_file_here
""",

)

# ConfigCheck.py ends here
示例#56
0
STANDARD_BIN_DIRS = ["/bin/", "/sbin/", "/usr/bin/", "/usr/sbin/"]
DEFAULT_APPDATA_CHECKER = ("appstream-util", "validate-relax")

appdata_checker = Config.getOption("AppDataChecker", DEFAULT_APPDATA_CHECKER)


class AppDataCheck(AbstractCheck.AbstractFilesCheck):
    def __init__(self):
        # desktop file need to be in $XDG_DATA_DIRS
        # $ echo $XDG_DATA_DIRS/applications
        # /var/lib/menu-xdg:/usr/share
        AbstractCheck.AbstractFilesCheck.__init__(self, "AppDataCheck", "/usr/share/appdata/.*\.appdata.xml$")

    def check_file(self, pkg, filename):
        root = pkg.dirName()
        f = root + filename
        try:
            st = getstatusoutput(appdata_checker + (f,))
        except OSError:
            # ignore if the checker is not installed
            return
        if st[0]:
            printError(pkg, "invalid-appdata-file", filename)


check = AppDataCheck()

addDetails("invalid-appdata-file", """appdata file is not valid, check with %s""" % (" ".join(appdata_checker)))

# ex: ts=4 sw=4 et
                    printWarning(pkg,
                                 'systemd-service-without-service_add_post',
                                 os.path.basename(fname))
                if not processed['preun']:
                    printWarning(pkg,
                                 'systemd-service-without-service_del_preun',
                                 os.path.basename(fname))
                if not processed['postun']:
                    printWarning(pkg,
                                 'systemd-service-without-service_del_postun',
                                 os.path.basename(fname))


# Create an object to enable the auto registration of the test
check = CheckSystemdInstall()

addDetails(
    'systemd-service-without-service_add_pre',
    '''The package contains a systemd service but doesn't contain a %pre with
a call to service_add_pre.''',
    'systemd-service-without-service_add_post',
    '''The package contains a systemd service but doesn't contain a %post with
a call to service_add_post.''',
    'systemd-service-without-service_del_preun',
    '''The package contains a systemd service but doesn't contain a %preun with
a call to service_del_preun.''',
    'systemd-service-without-service_del_postun',
    '''The package contains a systemd service but doesn't contain a %postun with
a call to service_del_postun.''',
)
            return

        for fname, pkgfile in pkg.files().items():

            if '/animations/' in fname:
                continue

            res = self.file_size_regex.search(fname)
            if res:
                sizes = (res.group(1), res.group(2))
                res = self.info_size_regex.search(pkgfile.magic)
                if res:
                    actualsizes = (res.group(1), res.group(2))

                    if abs(int(sizes[0])-int(actualsizes[0])) > 2 or \
                            abs(int(sizes[1])-int(actualsizes[1])) > 2:
                        printError(pkg, "wrong-icon-size", fname, "expected:",
                                   "x".join(sizes),
                                   "actual:", "x".join(actualsizes))


check = IconSizesCheck()

if Config.info:
    addDetails(
        'wrong-icon-size',
        """Your icon file is installed in a fixed-size directory, but has a
        largely incorrect size. Some desktop environments (e.g. GNOME)
        display them incorrectly."""
    )