diff --git a/.cvsignore b/.cvsignore index b80caad..4446147 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -Python-2.5.1.tar.bz2 +Python-2.5.2.tar.bz2 diff --git a/python-2.5-CVE-2008-2316.patch b/python-2.5-CVE-2008-2316.patch new file mode 100644 index 0000000..450354b --- /dev/null +++ b/python-2.5-CVE-2008-2316.patch @@ -0,0 +1,156 @@ +Index: Lib/test/test_hashlib.py +=================================================================== +--- Lib/test/test_hashlib.py (revision 64642) ++++ Lib/test/test_hashlib.py (working copy) +@@ -9,8 +9,8 @@ + import hashlib + import unittest + from test import test_support ++from test.test_support import _4G, precisionbigmemtest + +- + def hexstr(s): + import string + h = string.hexdigits +@@ -55,7 +55,6 @@ + m2.update(aas + bees + cees) + self.assertEqual(m1.digest(), m2.digest()) + +- + def check(self, name, data, digest): + # test the direct constructors + computed = getattr(hashlib, name)(data).hexdigest() +@@ -74,8 +73,23 @@ + def test_case_md5_2(self): + self.check('md5', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', + 'd174ab98d277d9f5a5611c2c9f419d9f') ++ ++ @precisionbigmemtest(size=_4G + 5, memuse=1) ++ def test_case_md5_huge(self, size): ++ if size == _4G + 5: ++ try: ++ self.check('md5', 'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d') ++ except OverflowError: ++ pass # 32-bit arch ++ ++ @precisionbigmemtest(size=_4G - 1, memuse=1) ++ def test_case_md5_uintmax(self, size): ++ if size == _4G - 1: ++ try: ++ self.check('md5', 'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3') ++ except OverflowError: ++ pass # 32-bit arch + +- + # use the three examples from Federal Information Processing Standards + # Publication 180-1, Secure Hash Standard, 1995 April 17 + # http://www.itl.nist.gov/div897/pubs/fip180-1.htm +Index: Modules/_hashopenssl.c +=================================================================== +--- Modules/_hashopenssl.c (revision 64642) ++++ Modules/_hashopenssl.c (working copy) +@@ -19,7 +19,9 @@ + /* EVP is the preferred interface to hashing in OpenSSL */ + #include + ++#define MUNCH_SIZE INT_MAX + ++ + #ifndef HASH_OBJ_CONSTRUCTOR + #define HASH_OBJ_CONSTRUCTOR 0 + #endif +@@ -164,9 +166,18 @@ + if (!PyArg_ParseTuple(args, "s#:update", &cp, &len)) + return NULL; + ++ if (len > 0 && len <= MUNCH_SIZE) { + EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t, + unsigned int)); +- ++ } else { ++ Py_ssize_t offset = 0; ++ while (len) { ++ unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len; ++ EVP_DigestUpdate(&self->ctx, cp + offset, process); ++ len -= process; ++ offset += process; ++ } ++ } + Py_INCREF(Py_None); + return Py_None; + } +@@ -255,10 +266,21 @@ + self->name = name_obj; + Py_INCREF(self->name); + +- if (cp && len) ++ if (cp && len) { ++ if (len > 0 && len <= MUNCH_SIZE) { + EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t, + unsigned int)); +- ++ } else { ++ Py_ssize_t offset = 0; ++ while (len) { ++ unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len; ++ EVP_DigestUpdate(&self->ctx, cp + offset, process); ++ len -= process; ++ offset += process; ++ } ++ } ++ } ++ + return 0; + } + #endif +@@ -328,7 +350,7 @@ + static PyObject * + EVPnew(PyObject *name_obj, + const EVP_MD *digest, const EVP_MD_CTX *initial_ctx, +- const unsigned char *cp, unsigned int len) ++ const unsigned char *cp, Py_ssize_t len) + { + EVPobject *self; + +@@ -346,8 +368,20 @@ + EVP_DigestInit(&self->ctx, digest); + } + +- if (cp && len) +- EVP_DigestUpdate(&self->ctx, cp, len); ++ if (cp && len) { ++ if (len > 0 && len <= MUNCH_SIZE) { ++ EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t, ++ unsigned int)); ++ } else { ++ Py_ssize_t offset = 0; ++ while (len) { ++ unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len; ++ EVP_DigestUpdate(&self->ctx, cp + offset, process); ++ len -= process; ++ offset += process; ++ } ++ } ++ } + + return (PyObject *)self; + } +@@ -384,8 +418,7 @@ + + digest = EVP_get_digestbyname(name); + +- return EVPnew(name_obj, digest, NULL, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t, +- unsigned int)); ++ return EVPnew(name_obj, digest, NULL, cp, len); + } + + /* +@@ -410,7 +443,7 @@ + CONST_ ## NAME ## _name_obj, \ + NULL, \ + CONST_new_ ## NAME ## _ctx_p, \ +- cp, Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int)); \ ++ cp, len); \ + } + + /* a PyMethodDef structure for the constructor */ diff --git a/python-2.5.2-binutils-no-dep.patch b/python-2.5.2-binutils-no-dep.patch new file mode 100644 index 0000000..6792c9f --- /dev/null +++ b/python-2.5.2-binutils-no-dep.patch @@ -0,0 +1,20 @@ +diff -ru Python-2.5.2-orig/Lib/ctypes/util.py Python-2.5.2/Lib/ctypes/util.py +--- Python-2.5.2-orig/Lib/ctypes/util.py 2007-09-14 16:05:26.000000000 -0400 ++++ Python-2.5.2/Lib/ctypes/util.py 2008-09-24 17:30:06.000000000 -0400 +@@ -83,9 +83,14 @@ + if not f: + return None + cmd = "objdump -p -j .dynamic 2>/dev/null " + f +- res = re.search(r'\sSONAME\s+([^\s]+)', os.popen(cmd).read()) ++ try: ++ res = re.search(r'\sSONAME\s+([^\s]+)', os.popen(cmd).read()) ++ except: ++ res = None + if not res: +- return None ++ return os.path.basename(f) # This is good for GLibc, I think, ++ # and a dep on binutils is big (for ++ # live CDs). + return res.group(1) + + if (sys.platform.startswith("freebsd") diff --git a/python-2.5.2-db47.patch b/python-2.5.2-db47.patch new file mode 100644 index 0000000..5dd3af2 --- /dev/null +++ b/python-2.5.2-db47.patch @@ -0,0 +1,78 @@ +diff -ru Python-2.5.2-orig/Modules/_bsddb.c Python-2.5.2/Modules/_bsddb.c +--- Python-2.5.2-orig/Modules/_bsddb.c 2008-02-03 02:26:23.000000000 -0500 ++++ Python-2.5.2/Modules/_bsddb.c 2008-09-24 17:01:50.000000000 -0400 +@@ -5335,11 +5335,13 @@ + DBEnv_getattr(DBEnvObject* self, char *name) + { + if (!strcmp(name, "db_home")) { ++ const char *home = NULL; + CHECK_ENV_NOT_CLOSED(self); +- if (self->db_env->db_home == NULL) { ++ self->db_env->get_home(self->db_env, &home); ++ if (home == NULL) { + RETURN_NONE(); + } +- return PyString_FromString(self->db_env->db_home); ++ return PyString_FromString(home); + } + + return Py_FindMethod(DBEnv_methods, (PyObject* )self, name); +@@ -5961,22 +5963,37 @@ + ADD_INT(d, DB_TIME_NOTGRANTED); + ADD_INT(d, DB_TXN_NOT_DURABLE); + ADD_INT(d, DB_TXN_WRITE_NOSYNC); +- ADD_INT(d, DB_LOG_AUTOREMOVE); +- ADD_INT(d, DB_DIRECT_LOG); + ADD_INT(d, DB_DIRECT_DB); + ADD_INT(d, DB_INIT_REP); + ADD_INT(d, DB_ENCRYPT); + ADD_INT(d, DB_CHKSUM); + #endif + ++#if (DBVER >= 42) && (DBVER < 47) ++ ADD_INT(d, DB_LOG_AUTOREMOVE); ++ ADD_INT(d, DB_DIRECT_LOG); ++#endif ++ ++#if (DBVER >= 47) ++ ADD_INT(d, DB_LOG_DIRECT); ++ ADD_INT(d, DB_LOG_DSYNC); ++ ADD_INT(d, DB_LOG_IN_MEMORY); ++ ADD_INT(d, DB_LOG_AUTO_REMOVE); ++ ADD_INT(d, DB_LOG_ZERO); ++#endif ++ + #if (DBVER >= 43) +- ADD_INT(d, DB_LOG_INMEMORY); + ADD_INT(d, DB_BUFFER_SMALL); + ADD_INT(d, DB_SEQ_DEC); + ADD_INT(d, DB_SEQ_INC); + ADD_INT(d, DB_SEQ_WRAP); + #endif + ++#if (DBVER >= 43) && (DBVER < 47) ++ ADD_INT(d, DB_LOG_INMEMORY); ++ ADD_INT(d, DB_DSYNC_LOG); ++#endif ++ + #if (DBVER >= 41) + ADD_INT(d, DB_ENCRYPT_AES); + ADD_INT(d, DB_AUTO_COMMIT); +diff -ru Python-2.5.2-orig/setup.py Python-2.5.2/setup.py +--- Python-2.5.2-orig/setup.py 2008-09-24 17:01:02.000000000 -0400 ++++ Python-2.5.2/setup.py 2008-09-24 17:03:05.000000000 -0400 +@@ -608,12 +608,12 @@ + # a release. Most open source OSes come with one or more + # versions of BerkeleyDB already installed. + +- max_db_ver = (4, 5) ++ max_db_ver = (4, 7) + # NOTE: while the _bsddb.c code links against BerkeleyDB 4.6.x + # we leave that version disabled by default as it has proven to be + # quite a buggy library release on many platforms. + min_db_ver = (3, 3) +- db_setup_debug = False # verbose debug prints from this script? ++ db_setup_debug = True # verbose debug prints from this script? + + # construct a list of paths to look for the header file in on + # top of the normal inc_dirs. diff --git a/python-2.5.2-set_wakeup_fd4.patch b/python-2.5.2-set_wakeup_fd4.patch new file mode 100644 index 0000000..77ae208 --- /dev/null +++ b/python-2.5.2-set_wakeup_fd4.patch @@ -0,0 +1,86 @@ +diff -ru Python-2.5.2-orig/Modules/signalmodule.c Python-2.5.2/Modules/signalmodule.c +--- Python-2.5.2-orig/Modules/signalmodule.c 2007-12-10 18:03:55.000000000 -0500 ++++ Python-2.5.2/Modules/signalmodule.c 2008-09-24 17:32:45.000000000 -0400 +@@ -12,6 +12,8 @@ + + #include + ++#include ++ + #ifndef SIG_ERR + #define SIG_ERR ((PyOS_sighandler_t)(-1)) + #endif +@@ -75,6 +77,8 @@ + PyObject *func; + } Handlers[NSIG]; + ++static int wakeup_fd = -1; ++ + /* Speed up sigcheck() when none tripped */ + static volatile sig_atomic_t is_tripped = 0; + +@@ -113,6 +117,7 @@ + static void + signal_handler(int sig_num) + { ++ const char dummy_byte = '\0'; + #ifdef WITH_THREAD + #ifdef WITH_PTH + if (PyThread_get_thread_ident() != main_thread) { +@@ -128,6 +133,8 @@ + cleared in PyErr_CheckSignals() before .tripped. */ + is_tripped = 1; + Py_AddPendingCall(checksignals_witharg, NULL); ++ if (wakeup_fd != -1) ++ write(wakeup_fd, &dummy_byte, 1); + #ifdef WITH_THREAD + } + #endif +@@ -267,6 +274,39 @@ + anything else -- the callable Python object used as a handler"); + + ++static PyObject * ++signal_set_wakeup_fd(PyObject *self, PyObject *args) ++{ ++ struct stat buf; ++ int fd, old_fd; ++ if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd)) ++ return NULL; ++#ifdef WITH_THREAD ++ if (PyThread_get_thread_ident() != main_thread) { ++ PyErr_SetString(PyExc_ValueError, ++ "set_wakeup_fd only works in main thread"); ++ return NULL; ++ } ++#endif ++ if (fd != -1 && fstat(fd, &buf) != 0) { ++ PyErr_SetString(PyExc_ValueError, "invalid fd"); ++ return NULL; ++ } ++ old_fd = wakeup_fd; ++ wakeup_fd = fd; ++ return PyLong_FromLong(old_fd); ++} ++ ++PyDoc_STRVAR(set_wakeup_fd_doc, ++"set_wakeup_fd(fd) -> fd\n\ ++\n\ ++Sets the fd to be written to (with '\\0') when a signal\n\ ++comes in. A library can use this to wakeup select or poll.\n\ ++The previous fd is returned.\n\ ++\n\ ++The fd must be non-blocking."); ++ ++ + /* List of functions defined in the module */ + static PyMethodDef signal_methods[] = { + #ifdef HAVE_ALARM +@@ -274,6 +314,7 @@ + #endif + {"signal", signal_signal, METH_VARARGS, signal_doc}, + {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc}, ++ {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc}, + #ifdef HAVE_PAUSE + {"pause", (PyCFunction)signal_pause, + METH_NOARGS,pause_doc}, diff --git a/python.spec b/python.spec index 4af3e72..a06fe67 100644 --- a/python.spec +++ b/python.spec @@ -21,8 +21,8 @@ Summary: An interpreted, interactive, object-oriented programming language. Name: %{python} -Version: 2.5.1 -Release: 30%{?dist} +Version: 2.5.2 +Release: 1%{?dist} License: Python Group: Development/Languages Provides: python-abi = %{pybasever} @@ -39,7 +39,7 @@ Patch6: python-2.5.1-plural-fix.patch Patch7: python-2.5.1-sqlite-encoding.patch Patch8: python-2.5-xmlrpclib-marshal-objects.patch Patch9: python-2.5-tkinter.patch -Patch10: python-2.5.1-binutils-no-dep.patch +Patch10: python-2.5.2-binutils-no-dep.patch Patch11: python-2.5.1-codec-ascii-tolower.patch Patch12: python-2.5.1-pysqlite.patch Patch13: python-2.5.1-socketmodule-constants.patch @@ -51,16 +51,17 @@ Patch15: python-2.5.1-listdir.patch Patch50: python-2.5-disable-egginfo.patch # new db version -Patch60: python-2.5.1-db47.patch +Patch60: python-2.5.2-db47.patch # lib64 patches Patch101: python-2.3.4-lib64-regex.patch Patch102: python-2.5-lib64.patch # New API from 2.6 -Patch260: python2.6-set_wakeup_fd4.patch +Patch260: python-2.5.2-set_wakeup_fd4.patch Patch999: python-2.5.CVE-2007-4965-int-overflow.patch +Patch998: python-2.5-CVE-2008-2316.patch %if %{main_python} @@ -206,7 +207,6 @@ code that uses more than just unittest and/or test_support.py. %patch102 -p1 -b .lib64 %endif -%patch9 -p1 -b .tkinter %patch10 -p1 -b .binutils-no-dep %patch11 -p1 -b .ascii-tolower %patch12 -p1 -b .pysqlite-2.3.3-minimal @@ -222,6 +222,7 @@ code that uses more than just unittest and/or test_support.py. %patch260 -p1 -b .set_wakeup_fd %patch999 -p1 -b .cve2007-4965 +%patch998 -p0 -b .cve2008-2316 # This shouldn't be necesarry, but is right now (2.2a3) find -name "*~" |xargs rm -f @@ -510,6 +511,10 @@ rm -fr $RPM_BUILD_ROOT %{_libdir}/python%{pybasever}/lib-dynload/_testcapimodule.so %changelog +* Tue Sep 30 2008 James Antill - 2.5.2-1 +- Move to 2.5.2 +- Fix CVE-2008-2316 hashlib overflow. + * Thu Jul 17 2008 Jeremy Katz - 2.5.1-30 - Fix up the build for new rpm - And actually build against db4-4.7 (#455170) diff --git a/sources b/sources index e8a2035..3e35aea 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -70084ffa561660f07de466c2c8c4842d Python-2.5.1.tar.bz2 +afb5451049eda91fbde10bd5a4b7fadc Python-2.5.2.tar.bz2