summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal Norwitz <nnorwitz@gmail.com>2006-07-23 08:01:43 (GMT)
committerNeal Norwitz <nnorwitz@gmail.com>2006-07-23 08:01:43 (GMT)
commitdce937f32c323be92844185e0db768dc91f0a728 (patch)
treed1d6299019786facff9a4ea53ca39ff1f78e81f1
parent9029b5f28934f78c5c13c62e8565f468955eb4df (diff)
downloadcpython-dce937f32c323be92844185e0db768dc91f0a728.zip
cpython-dce937f32c323be92844185e0db768dc91f0a728.tar.gz
cpython-dce937f32c323be92844185e0db768dc91f0a728.tar.bz2
Ensure we don't write beyond errText. I think I got this right, but
it definitely could use some review to ensure I'm not off by one and there's no possible overflow/wrap-around of bytes_left. Reported by Klocwork #1. Fix a problem if there is a failure allocating self->db. Found with failmalloc.
-rw-r--r--Modules/_bsddb.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
index a88f01f..9e302bc 100644
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -528,6 +528,7 @@ static int makeDBError(int err)
PyObject *errObj = NULL;
PyObject *errTuple = NULL;
int exceptionRaised = 0;
+ unsigned int bytes_left;
switch (err) {
case 0: /* successful, no error */ break;
@@ -535,12 +536,15 @@ static int makeDBError(int err)
#if (DBVER < 41)
case DB_INCOMPLETE:
#if INCOMPLETE_IS_WARNING
- our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
- if (_db_errmsg[0]) {
+ bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
+ /* Ensure that bytes_left never goes negative */
+ if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
+ bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
+ assert(bytes_left >= 0);
strcat(errTxt, " -- ");
- strcat(errTxt, _db_errmsg);
- _db_errmsg[0] = 0;
+ strncat(errTxt, _db_errmsg, bytes_left);
}
+ _db_errmsg[0] = 0;
#ifdef HAVE_WARNINGS
exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt);
#else
@@ -588,12 +592,15 @@ static int makeDBError(int err)
}
if (errObj != NULL) {
- our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
- if (_db_errmsg[0]) {
+ bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
+ /* Ensure that bytes_left never goes negative */
+ if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
+ bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
+ assert(bytes_left >= 0);
strcat(errTxt, " -- ");
- strcat(errTxt, _db_errmsg);
- _db_errmsg[0] = 0;
+ strncat(errTxt, _db_errmsg, bytes_left);
}
+ _db_errmsg[0] = 0;
errTuple = Py_BuildValue("(is)", err, errTxt);
PyErr_SetObject(errObj, errTuple);
@@ -798,10 +805,12 @@ newDBObject(DBEnvObject* arg, int flags)
MYDB_BEGIN_ALLOW_THREADS;
err = db_create(&self->db, db_env, flags);
- self->db->set_errcall(self->db, _db_errorCallback);
+ if (self->db != NULL) {
+ self->db->set_errcall(self->db, _db_errorCallback);
#if (DBVER >= 33)
- self->db->app_private = (void*)self;
+ self->db->app_private = (void*)self;
#endif
+ }
MYDB_END_ALLOW_THREADS;
/* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
* list so that a DBEnv can refuse to close without aborting any open