jstanek pushed to libdb4 (master). "Add upstream fix for memp_stat heap corruption. (..more)"

notifications at fedoraproject.org notifications at fedoraproject.org
Fri May 22 12:48:44 UTC 2015


From 255740284d0179996cee15de7b2e619e309c8c3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Stan=C4=9Bk?= <jstanek at redhat.com>
Date: Fri, 22 May 2015 14:48:25 +0200
Subject: Add upstream fix for memp_stat heap corruption.

- Resolves: rhbz#1211871

diff --git a/db-4.7.25-memp_stat-upstream-fix.patch b/db-4.7.25-memp_stat-upstream-fix.patch
new file mode 100644
index 0000000..51888d6
--- /dev/null
+++ b/db-4.7.25-memp_stat-upstream-fix.patch
@@ -0,0 +1,185 @@
+diff -up db-4.8.30/mp/mp_stat.c.memp_stat db-4.8.30/mp/mp_stat.c
+--- db-4.8.30/mp/mp_stat.c.memp_stat	2010-04-12 22:25:34.000000000 +0200
++++ db-4.8.30/mp/mp_stat.c	2015-05-22 14:42:28.731436789 +0200
+@@ -88,6 +88,13 @@ __memp_stat(env, gspp, fspp, flags)
+ 	u_int32_t i, st_bytes, st_gbytes, st_hash_buckets, st_pages;
+ 	uintmax_t tmp_wait, tmp_nowait;
+ 
++  /*
++  * The array holding the lengths related to the buffer allocated for *fspp.
++  * The first element of the array holds the number of entries allocated.
++  * The second element of the array holds the total number of bytes allocated.
++  */
++  u_int32_t fsp_len[2];
++
+ 	dbmp = env->mp_handle;
+ 	mp = dbmp->reginfo[0].primary;
+ 
+@@ -202,31 +209,53 @@ __memp_stat(env, gspp, fspp, flags)
+ 	if (fspp != NULL) {
+ 		*fspp = NULL;
+ 
+-		/* Count the MPOOLFILE structures. */
+-		i = 0;
+-		len = 0;
+-		if ((ret = __memp_walk_files(env,
+-		     mp, __memp_count_files, &len, &i, flags)) != 0)
+-			return (ret);
++		while (*fspp == NULL) {
++			/* Count the MPOOLFILE structures. */
++			i = 0;
++			/*
++			 * Allow space for the first __memp_get_files() to align the
++			 * structure array to uintmax_t, DB_MPOOL_STAT's most
++			 * restrictive field.  [#23150]
++			 */
++			len = sizeof(uintmax_t);
++			if ((ret = __memp_walk_files(env,
++			     mp, __memp_count_files, &len, &i, flags)) != 0)
++				return (ret);
++
++			if (i == 0)
++				return (0);
++
++			/* 
++			 * Copy the number of DB_MPOOL_FSTAT entries and the number of
++			 * bytes allocated for them into fsp_len. Do not count the space
++			 * reserved for allignment.
++			 */
++			fsp_len[0] = i;
++			fsp_len[1] = len - sizeof(uintmax_t);
+ 
+-		if (i == 0)
+-			return (0);
+-		len += sizeof(DB_MPOOL_FSTAT *);	/* Trailing NULL */
++			len += sizeof(DB_MPOOL_FSTAT *);	/* Trailing NULL */
+ 
+-		/* Allocate space */
+-		if ((ret = __os_umalloc(env, len, fspp)) != 0)
+-			return (ret);
++			/* Allocate space */
++			if ((ret = __os_umalloc(env, len, fspp)) != 0)
++				return (ret);
+ 
+-		tfsp = *fspp;
+-		*tfsp = NULL;
++			tfsp = *fspp;
++			*tfsp = NULL;
+ 
+-		/*
+-		 * Files may have been opened since we counted, don't walk
+-		 * off the end of the allocated space.
+-		 */
+-		if ((ret = __memp_walk_files(env,
+-		    mp, __memp_get_files, &tfsp, &i, flags)) != 0)
+-			return (ret);
++			/*
++			 * Files may have been opened since we counted, if we walk off
++			 * the end of the allocated space specified in fsp_len, retry.
++			 */
++			if ((ret = __memp_walk_files(env,
++			    mp, __memp_get_files, &tfsp, fsp_len, flags)) != 0) {
++				if (ret == DB_BUFFER_SMALL) {
++					__os_ufree(env, *fspp);
++					*fspp = NULL;
++					tfsp = NULL;
++				} else
++					return (ret);
++			}
++		}
+ 
+ 		*++tfsp = NULL;
+ 	}
+@@ -298,29 +327,36 @@ __memp_count_files(env, mfp, argp, count
+  * for the text file names.
+  */
+ static int
+-__memp_get_files(env, mfp, argp, countp, flags)
++__memp_get_files(env, mfp, argp, fsp_len, flags)
+ 	ENV *env;
+ 	MPOOLFILE *mfp;
+ 	void *argp;
+-	u_int32_t *countp;
++	u_int32_t fsp_len[];
+ 	u_int32_t flags;
+ {
+ 	DB_MPOOL *dbmp;
+ 	DB_MPOOL_FSTAT **tfsp, *tstruct;
+ 	char *name, *tname;
+-	size_t nlen;
++	size_t nlen, tlen;
+ 	u_int32_t pagesize;
+ 
+-	if (*countp == 0)
+-		return (0);
++	/* We walked through more files than argp was allocated for. */
++	if (fsp_len[0] == 0)
++		return DB_BUFFER_SMALL;
+ 
+ 	dbmp = env->mp_handle;
+ 	tfsp = *(DB_MPOOL_FSTAT ***)argp;
+ 
+ 	if (*tfsp == NULL) {
+-		/* Add 1 to count because we need to skip over the NULL. */
+-		tstruct = (DB_MPOOL_FSTAT *)(tfsp + *countp + 1);
+-		tname = (char *)(tstruct + *countp);
++		/*
++		 * Add 1 to count because to skip over the NULL end marker.
++		 * Align it further for DB_MPOOL_STAT's most restrictive field
++		 * because uintmax_t might require stricter alignment than
++		 * pointers; e.g., IP32 LL64 SPARC. [#23150]
++		 */
++		tstruct = (DB_MPOOL_FSTAT *)&tfsp[fsp_len[0] + 1];
++		tstruct = ALIGNP_INC(tstruct, sizeof(uintmax_t));
++		tname = (char *)&tstruct[fsp_len[0]];
+ 		*tfsp = tstruct;
+ 	} else {
+ 		tstruct = *tfsp + 1;
+@@ -330,12 +366,26 @@ __memp_get_files(env, mfp, argp, countp,
+ 
+ 	name = __memp_fns(dbmp, mfp);
+ 	nlen = strlen(name) + 1;
++
++	/* The space required for file names is larger than argp was allocated for. */
++	tlen = sizeof(DB_MPOOL_FSTAT *) + sizeof(DB_MPOOL_FSTAT) + nlen;
++	if (fsp_len[1] < tlen)
++		return DB_BUFFER_SMALL;
++	else
++		/* Count down the number of bytes left in argp. */
++		fsp_len[1] -= tlen;
++
+ 	memcpy(tname, name, nlen);
+-	*tstruct = mfp->stat;
++	memcpy(tstruct, &mfp->stat, sizeof(mfp->stat));
+ 	tstruct->file_name = tname;
+ 
++	/* Grab the pagesize from the mfp. */
++	tstruct->st_pagesize = mfp->stat.st_pagesize;
++
+ 	*(DB_MPOOL_FSTAT ***)argp = tfsp;
+-	(*countp)--;
++
++	/* Count down the number of entries left in argp. */
++	fsp_len[0]--;
+ 
+ 	if (LF_ISSET(DB_STAT_CLEAR)) {
+ 		pagesize = mfp->stat.st_pagesize;
+diff -up db-4.8.30/mp/mp_sync.c.memp_stat db-4.8.30/mp/mp_sync.c
+--- db-4.8.30/mp/mp_sync.c.memp_stat	2010-04-12 22:25:34.000000000 +0200
++++ db-4.8.30/mp/mp_sync.c	2015-05-22 14:38:17.711150804 +0200
+@@ -57,11 +57,13 @@ __memp_walk_files(env, mp, func, arg, co
+ 			if ((t_ret = func(env,
+ 			    mfp, arg, countp, flags)) != 0 && ret == 0)
+ 				ret = t_ret;
+-			if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
++			if (ret != 0 &&
++			    (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == DB_BUFFER_SMALL))
+ 				break;
+ 		}
+ 		MUTEX_UNLOCK(env, hp->mtx_hash);
+-		if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
++		if (ret != 0 &&
++		    (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == DB_BUFFER_SMALL))
+ 			break;
+ 	}
+ 	return (ret);
diff --git a/libdb4.spec b/libdb4.spec
index 245f1af..75dd878 100644
--- a/libdb4.spec
+++ b/libdb4.spec
@@ -4,7 +4,7 @@
 Summary: The Berkeley DB database library (version 4) for C
 Name: libdb4
 Version: 4.8.30
-Release: 17%{?dist}
+Release: 18%{?dist}
 URL: http://www.oracle.com/database/berkeley-db/
 License: Sleepycat and BSD
 Group: System Environment/Libraries
@@ -22,6 +22,7 @@ Patch21: db-4.6.21-1.85-compat.patch
 Patch22: db-4.5.20-jni-include-dir.patch
 Patch23: db-4.8.30-quotas-segfault.patch
 Patch24: db-4.8.30-format-security.patch
+Patch25: db-4.7.25-memp_stat-upstream-fix.patch
 
 Conflicts: filesystem < 3
 Obsoletes: db4 < 5.0.0
@@ -167,6 +168,7 @@ popd
 %patch22 -p1 -b .4.5.20.jni
 %patch23 -p1 -b .quotas-segfault
 %patch24 -p1 -b .format-security
+%patch25 -p1 -b .memp_stat
 
 # Fix HREF references in the docs which would otherwise break when we split the docs up into subpackages.
 set +x
@@ -390,6 +392,10 @@ chrpath -d ${RPM_BUILD_ROOT}%{_libdir}/*.so ${RPM_BUILD_ROOT}%{_bindir}/*
 %{_libdir}/%{name}/libdb_java.so
 
 %changelog
+* Fri May 22 2015 Jan Stanek <jstanek at redhat.com> - 4.8.30-18
+- Add upstream fix for memp_stat heap corruption.
+- Resolves: rhbz#1211871
+
 * Sat May 02 2015 Kalev Lember <kalevlember at gmail.com> - 4.8.30-17
 - Rebuilt for GCC 5 C++11 ABI change
 
-- 
cgit v0.10.2


	http://pkgs.fedoraproject.org/cgit/libdb4.git/commit/?h=master&id=255740284d0179996cee15de7b2e619e309c8c3e


More information about the scm-commits mailing list