Blame SOURCES/BZ-1234967-handle-invalid-yumdb.patch

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