commit f5c953e2b8c49187f8e874a53f1bb6ed89e4d810 Author: Michal Domonkos Date: Tue Feb 16 13:42:20 2016 +0100 Allow for validating attributes read from yumdb Make sure we don't expose corrupted attributes read from the yumdb to the consumers. There's at least one report of such a corruption: BZ 1234967. Instead, make requesting a malformed yumdb attribute equivalent to requesting a non-existent one -- which is a valid scenario, already handled by the consumers. Note that the actual validator function that fixes the above bug will be committed separately. diff --git a/yum/rpmsack.py b/yum/rpmsack.py index 229e1a1..270ade9 100644 --- a/yum/rpmsack.py +++ b/yum/rpmsack.py @@ -1755,6 +1755,9 @@ class RPMDBAdditionalDataPackage(object): 'group_member', 'command_line']) + # Validate these attributes when they are read from a file + _validators = {} + def __init__(self, conf, pkgdir, yumdb_cache=None): self._conf = conf self._mydir = pkgdir @@ -1903,6 +1906,15 @@ class RPMDBAdditionalDataPackage(object): fo.close() del fo + # Validate the attribute we just read from the file. Some attributes + # may require being in a specific format and we can't guarantee the + # file has not been tampered with outside of yum. + if attr in self._validators: + valid = self._validators[attr] + if not valid(value): + raise AttributeError, \ + "Invalid value of attribute %s on %s" % (attr, self) + if info.st_nlink > 1 and self._yumdb_cache is not None: self._yumdb_cache[key] = value self._auto_cache(attr, value, fn, info) commit 6972a28059790177ab95e0bce92311aa882ae465 Author: Michal Domonkos Date: Tue Feb 16 13:53:04 2016 +0100 Don't crash on invalid from_repo in yumdb. BZ 1234967 Implement a yumdb validator function for the from_repo attribute. This prevents yum from crashing if an implicit conversion to unicode takes place somewhere and the attribute contains non-ascii chars due to some yumdb corruption. Reproducers: $ yum install foo $ yumdb set from_repo foo $ yum list foo # crash $ yum --disablerepo= reinstall foo # crash $ yum --verbose version installed # crash diff --git a/yum/__init__.py b/yum/__init__.py index 84bea3e..1f6ce16 100644 --- a/yum/__init__.py +++ b/yum/__init__.py @@ -95,7 +95,6 @@ from yum.rpmtrans import RPMTransaction,SimpleCliCallBack from yum.i18n import to_unicode, to_str, exception2msg from yum.drpm import DeltaInfo, DeltaPackage -import string import StringIO from weakref import proxy as weakref @@ -476,17 +475,7 @@ class YumBase(depsolve.Depsolve): continue # Check the repo.id against the valid chars - bad = None - for byte in section: - if byte in string.ascii_letters: - continue - if byte in string.digits: - continue - if byte in "-_.:": - continue - - bad = byte - break + bad = misc.validate_repoid(section) if bad: self.logger.warning("Bad id for repo: %s, byte = %s %d" % diff --git a/yum/misc.py b/yum/misc.py index f72f028..345934b 100644 --- a/yum/misc.py +++ b/yum/misc.py @@ -24,6 +24,7 @@ import bz2 import gzip import shutil import urllib +import string _available_compression = ['gz', 'bz2'] try: import lzma @@ -1248,3 +1249,12 @@ def filter_pkgs_repoid(pkgs, repoid): continue ret.append(pkg) return ret + +def validate_repoid(repoid): + """Return the first invalid char found in the repoid, or None.""" + allowed_chars = string.ascii_letters + string.digits + '-_.:' + for char in repoid: + if char not in allowed_chars: + return char + else: + return None diff --git a/yum/rpmsack.py b/yum/rpmsack.py index 270ade9..11814f1 100644 --- a/yum/rpmsack.py +++ b/yum/rpmsack.py @@ -1756,7 +1756,10 @@ class RPMDBAdditionalDataPackage(object): 'command_line']) # Validate these attributes when they are read from a file - _validators = {} + _validators = { + # Fixes BZ 1234967 + 'from_repo': lambda repoid: misc.validate_repoid(repoid) is None, + } def __init__(self, conf, pkgdir, yumdb_cache=None): self._conf = conf commit c02805ed3b23f97843931e0784d2823b8024e441 Author: Michal Domonkos Date: Tue Feb 16 17:20:26 2016 +0100 docs: mention special case for unknown from_repo diff --git a/docs/yum.8 b/docs/yum.8 index e428148..eb52fb7 100644 --- a/docs/yum.8 +++ b/docs/yum.8 @@ -964,6 +964,8 @@ The format of the output of yum list is: name.arch [epoch:]version-release repo or @installed-from-repo +Note that if the repo cannot be determined, "installed" is printed instead. + .IP "\fByum list [all | glob_exp1] [glob_exp2] [\&.\&.\&.]\fP" List all available and installed packages\&. .IP "\fByum list available [glob_exp1] [\&.\&.\&.]\fP"