def load_debian_issue(f): deb_issue = deb822.Deb822(f) issue = {} issue['description'] = deb_issue['Description'] references = [ ref for ref in (LINE_BREAK_RE.split(deb_issue['References'].strip()) + LINE_BREAK_RE.split(deb_issue['Bugs'].strip())) if ref ] if references: issue['references'] = references # Group and join comment lines by name comments = {} for line in LINE_BREAK_RE.split(deb_issue['Notes'].strip()): if not line: continue match = COMMENT_RE.match(line) if match: name = 'Debian-' + match.group(1) rest = match.group(2) else: name = 'Debian' rest = line comments.setdefault(name, []).append(rest) if comments: issue['comments'] = dict( (name, '\n'.join(lines)) for (name, lines) in comments.items()) # Branch status for key in deb_issue: if key == 'upstream': branch = 'mainline' elif key.endswith('-upstream-stable'): branch = 'linux-%s.y' % key.replace('-upstream-stable', '') else: continue match = STATUS_RE.match(deb_issue[key]) if match and \ match.group('state') in ['pending', 'released'] and \ match.group('changerefs'): # These are *usually* git commit hashes but could be patch names hashes = [ ref for ref in COMMA_SEP_RE.split(match.group('changerefs')) if kernel_sec.issue.is_git_hash(ref) ] if hashes: issue.setdefault('fixed-by', {})[branch] = hashes if match and \ match.group('state') == 'ignored' and \ match.group('reason'): issue.setdefault('ignore', {})[branch] = match.group('reason') return issue
def load_ubuntu_issue(f): ubu_issue = load_cve(f) issue = {} assert ubu_issue['Candidate'] == os.path.basename(f.name) if 'linux' not in ubu_issue['pkgs']: raise NonKernelIssue() # Issues with Android in the description almost always refer to things # not in mainline, that we should not track if DESCRIPTION_ANDROID_RE.search(ubu_issue['Description']): raise NonKernelIssue() issue['description'] = ubu_issue['Description'].strip() refs = [ ref for ref in (ubu_issue.get('References', '').strip().split() + ubu_issue.get('Bugs', '').strip().split()) if ':' in ref ] if refs: issue['references'] = refs comments = {} name = 'Ubuntu' for line in ubu_issue['Notes'].split('\n'): if not line: continue match = COMMENT_RE.match(line) if match: name = 'Ubuntu-' + match.group(1) rest = match.group(2) else: rest = line comments.setdefault(name, []).append(rest) if comments: issue['comments'] = dict( (name, '\n'.join(lines)) for (name, lines) in comments.items()) disc = ubu_issue.get('Discovered-by', '').strip() if disc: issue['reporters'] = DISCOVERED_BY_SEP_RE.split(disc) patches = ubu_issue.get('Patches_linux', '').strip() match = BREAK_FIX_RE.match(patches) if match and match.group(1): issue.setdefault('introduced-by', {})['mainline'] = [match.group(1)] if match and match.group(2): issue.setdefault('fixed-by', {})['mainline'] = [match.group(2)] return issue
def load_ubuntu_issue(f, branches): ubu_issue = load_cve(f) issue = {} assert ubu_issue['Candidate'] == os.path.basename(f.name) if 'linux' not in ubu_issue['pkgs']: raise NonKernelIssue() issue['description'] = ubu_issue['Description'].strip() refs = [ ref for ref in (ubu_issue.get('References', '').strip().split() + ubu_issue.get('Bugs', '').strip().split()) if ':' in ref ] if refs: issue['references'] = refs comments = {} name = 'ubuntu' for line in ubu_issue['Notes'].split('\n'): if not line: continue match = COMMENT_RE.match(line) if match: name = 'ubuntu/' + match.group(1) rest = match.group(2) else: rest = line comments.setdefault(name, []).append(rest) if comments: issue['comments'] = dict( (name, '\n'.join(lines)) for (name, lines) in comments.items()) disc = ubu_issue.get('Discovered-by', '').strip() if disc: issue['reporters'] = DISCOVERED_BY_SEP_RE.split(disc) patches = ubu_issue.get('Patches_linux', '').strip() match = BREAK_FIX_RE.match(patches) if match and match.group(1): issue.setdefault('introduced-by', {})['mainline'] = [match.group(1)] if match and match.group(2): issue.setdefault('fixed-by', {})['mainline'] = [match.group(2)] for branch in branches: branch_name = branch['short_name'] assert branch_name.startswith('ubuntu/') branch_state, branch_notes = \ ubu_issue['pkgs']['linux'].get(branch_name[7:], (None, None)) if branch_state in ['released', 'not-affected'] \ and VERSION_RE.match(branch_notes): # Just record the version for now. This can hopefully be # converted into a list of commits by the find_commits() # function. Note that this is usually the first version # that is fixed *and* was released to users. issue.setdefault('fixed-by', {})[branch_name] = \ ['version:' + branch_notes] return issue
def load_debian_issue(f, branches): deb_issue = deb822.Deb822(f) issue = {} issue['description'] = deb_issue['Description'] references = \ [ref for ref in LINE_BREAK_RE.split(deb_issue['References'].strip()) if ref] + \ [bug_url(ref) for ref in LINE_BREAK_RE.split(deb_issue['Bugs'].strip()) if ref] if references: issue['references'] = references # Group and join comment lines by name comments = {} for line in LINE_BREAK_RE.split(deb_issue['Notes'].strip()): if not line: continue match = COMMENT_RE.match(line) if match: name = 'debian/' + match.group(1) rest = match.group(2) else: name = 'debian' rest = line comments.setdefault(name, []).append(rest) if comments: issue['comments'] = dict( (name, '\n'.join(lines)) for (name, lines) in comments.items()) def get_fixes(branch_name, branch_format, match): if branch_format == BranchFormat.STANDARD: if match.group('changerefs'): hashes = [ ref_name for ref_name in COMMA_SEP_RE.split( match.group('changerefs')) if kernel_sec.issue.change_is_git_hash(ref_name) ] if hashes: return hashes else: assert branch_format == BranchFormat.PATCH_QUEUE is_debian = branch_name.startswith('debian/') state = match.group('state') if is_debian: if state == 'released': version = match.group('version') if version is None or ',' in version or '-' not in version: return None ref_name = 'debian/' + version.replace('~', '_') else: assert state == 'pending' ref_name = branch_name[7:] else: ref_name = 'master' if match.group('changerefs'): assert branch_format == BranchFormat.PATCH_QUEUE patches = COMMA_SEP_RE.split(match.group('changerefs')) if patches: return [ 'patch:%s:%s' % (ref_name, file_name) for file_name in patches ] elif is_debian and state == 'released': # Fixed in this version but without any changes listed. # Probably fixed by importing a newer upstream. return ['version:' + ref_name] return None # Branch status for key in deb_issue: # Parse the branch name and determine format of the branch # dependent on state match = BRANCH_RE.match(key) if not match: continue base_ver = match.group('base_ver') if match.group('mainline'): branch_format = { 'pending': BranchFormat.STANDARD, 'released': BranchFormat.STANDARD, } branch_name = 'mainline' elif not match.group('debian'): branch_format = { 'pending': BranchFormat.PATCH_QUEUE, 'released': BranchFormat.STANDARD, } branch_name = 'stable/' + base_ver else: branch_format = { 'pending': BranchFormat.PATCH_QUEUE, 'released': BranchFormat.PATCH_QUEUE, } branch_name = 'debian/' + match.group('debian') if branch_name not in branches: continue # For mainline, fixes may span multiple releases for match in STATUS_RE.finditer(deb_issue[key]): state = match.group('state') if state in ['pending', 'released']: fixes = get_fixes(branch_name, branch_format[state], match) if fixes: issue.setdefault('fixed-by', {}).setdefault(branch_name, []).extend(fixes) # However, there will be only one "ignored" entry if state == 'ignored' and match.group('reason'): issue.setdefault('ignore', {})[branch_name] = match.group('reason') # Fill in status for Debian stable branches fixed before the # Debian branch point. These will only be explicitly marked as # fixed in sid, though they may have a free-form comment # explaining why the stable branch wasn't affected. if 'sid' in deb_issue: match = STATUS_RE.match(deb_issue['sid']) version = match and match.group('version') if match \ and match.group('state') == 'released' \ and version and ',' not in version: fixes = get_fixes('debian/sid', BranchFormat.PATCH_QUEUE, match) if fixes: for branch_name, branch in branches.items(): if branch_name.startswith('debian/') \ and branch_name not in issue.get('fixed-by', {}) \ and dpkg_version_cmp( version, branch['debian_branch_point']) <= 0: issue.setdefault('fixed-by', {})[branch_name] = fixes return issue