Index: SpecCheck.py =================================================================== --- SpecCheck.py.orig +++ SpecCheck.py @@ -34,7 +34,7 @@ prefix_regex = re.compile('^Prefix\s*:\s packager_regex = re.compile('^Packager\s*:\s*([^\s]+)', re.IGNORECASE) noarch_regex = re.compile('^BuildArch(?:itectures)?\s*:\s*\\bnoarch\\b', re.IGNORECASE) make_check_regex = re.compile('(^|\s|%{?__)make}?\s+(check|test)') -rm_regex = re.compile('(^|\s)((.*/)?rm|%{?__rm}?) ') +rm_rf_regex = re.compile('(^|\s)((.*/)?rm|%{?__rm}?) -[fF]?[rR][^/]*$') rpm_buildroot_regex = re.compile('(\\\*)\${?RPM_BUILD_ROOT}?|(%+){?buildroot}?') configure_start_regex = re.compile('\./configure') configure_libdir_spec_regex = re.compile('ln |\./configure[^#]*--libdir=([^\s]+)[^#]*') @@ -145,6 +145,14 @@ def contains_buildroot(line): return 0 +def contains_create_buildroot(line): + '''Check if the line is of the form mkdir %{buildroot}.''' + line = line.strip() + if contains_buildroot(line) and line.startswith("mkdir") and \ + not line.count("-p"): + return True + return False + class SpecCheck(AbstractCheck.AbstractCheck): def __init__(self): @@ -192,6 +200,7 @@ class SpecCheck(AbstractCheck.AbstractCh ifarch_depth = -1 current_section = 'package' buildroot_clean = {'clean': 0, 'install' : 0} + buildroot_created={'clean':False , 'install':True} depscript_override = 0 depgen_disabled = 0 indent_spaces = 0 @@ -261,8 +270,13 @@ class SpecCheck(AbstractCheck.AbstractCh printWarning(pkg, 'make-check-outside-check-section', line[:-1]) if current_section in buildroot_clean: - if contains_buildroot(line) and rm_regex.search(line): + if buildroot_created[current_section] and \ + contains_buildroot(line) and rm_rf_regex.search(line): buildroot_clean[current_section] = 1 + buildroot_created[current_section] = False + + if contains_create_buildroot(line): + buildroot_created[current_section] = True if ifarch_regex.search(line): if_depth = if_depth + 1 @@ -441,6 +455,9 @@ class SpecCheck(AbstractCheck.AbstractCh if not buildroot_clean[sect]: printError(pkg, 'no-cleaning-of-buildroot', '%' + sect) + if buildroot_clean['install'] and not buildroot_created['install']: + printError(pkg, '%install-no-mkdir-buildroot') + if not buildroot: printError(pkg, 'no-buildroot-tag') @@ -598,6 +615,12 @@ unpacking the sources.''', '''You should clean $RPM_BUILD_ROOT in the %clean section and just after the beginning of %install section. Use "rm -Rf $RPM_BUILD_ROOT".''', +'%install-no-mkdir-buildroot', +"""Your install section removes the buildroot but does not create them +afterwards in a secure way, which allows attackers to trivially play tricks +with symlinks on you. use mkdir %buildroot (no -p option!) or don't clean +the buildroot in %install, because that's anyway already done for you by rpm.""", + 'rpm-buildroot-usage', '''$RPM_BUILD_ROOT should not be touched during %build or %prep stage, as it will break short circuiting.''',