Kaydet (Commit) dce937f3 authored tarafından Neal Norwitz's avatar Neal Norwitz

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.
üst 9029b5f2
...@@ -528,6 +528,7 @@ static int makeDBError(int err) ...@@ -528,6 +528,7 @@ static int makeDBError(int err)
PyObject *errObj = NULL; PyObject *errObj = NULL;
PyObject *errTuple = NULL; PyObject *errTuple = NULL;
int exceptionRaised = 0; int exceptionRaised = 0;
unsigned int bytes_left;
switch (err) { switch (err) {
case 0: /* successful, no error */ break; case 0: /* successful, no error */ break;
...@@ -535,12 +536,15 @@ static int makeDBError(int err) ...@@ -535,12 +536,15 @@ static int makeDBError(int err)
#if (DBVER < 41) #if (DBVER < 41)
case DB_INCOMPLETE: case DB_INCOMPLETE:
#if INCOMPLETE_IS_WARNING #if INCOMPLETE_IS_WARNING
our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt)); bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
if (_db_errmsg[0]) { /* 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, " -- ");
strcat(errTxt, _db_errmsg); strncat(errTxt, _db_errmsg, bytes_left);
_db_errmsg[0] = 0;
} }
_db_errmsg[0] = 0;
#ifdef HAVE_WARNINGS #ifdef HAVE_WARNINGS
exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt); exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt);
#else #else
...@@ -588,12 +592,15 @@ static int makeDBError(int err) ...@@ -588,12 +592,15 @@ static int makeDBError(int err)
} }
if (errObj != NULL) { if (errObj != NULL) {
our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt)); bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
if (_db_errmsg[0]) { /* 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, " -- ");
strcat(errTxt, _db_errmsg); strncat(errTxt, _db_errmsg, bytes_left);
_db_errmsg[0] = 0;
} }
_db_errmsg[0] = 0;
errTuple = Py_BuildValue("(is)", err, errTxt); errTuple = Py_BuildValue("(is)", err, errTxt);
PyErr_SetObject(errObj, errTuple); PyErr_SetObject(errObj, errTuple);
...@@ -798,10 +805,12 @@ newDBObject(DBEnvObject* arg, int flags) ...@@ -798,10 +805,12 @@ newDBObject(DBEnvObject* arg, int flags)
MYDB_BEGIN_ALLOW_THREADS; MYDB_BEGIN_ALLOW_THREADS;
err = db_create(&self->db, db_env, flags); 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) #if (DBVER >= 33)
self->db->app_private = (void*)self; self->db->app_private = (void*)self;
#endif #endif
}
MYDB_END_ALLOW_THREADS; MYDB_END_ALLOW_THREADS;
/* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs /* 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 * list so that a DBEnv can refuse to close without aborting any open
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment