Hi Barry,

Thanks again for having a look at these. I don't think any of these are likely to cause issues in practice, but they're still good to fix.

On Mon 19 Sep 2011 10:16:33 PM CEST, Barry Warsaw wrote:

I did a very quick review of the C code here (branched from debianlp:subvertpy
on Launchpad, so should be the sid package), and found a number of
questionable things. I don't know the library code or the svn API very well,
so it's entirely possible that some or all of these are false alarms. It's
also possible I missed some things. I list them here because they made me go
"hmm" and I think they're worth a second look.

Most issues I think are not that serious, e.g. leaking a refcount in a rare error condition, either by not decref'ing an object in a short-circuit exit, or not checking return values for Python API calls. I'll list these farther
down. The most serious issue appears to be in util.c in
config_hash_from_object().

Potentially serious:

Notice how when config is a dictionary, you set `dict = config` but when it's
not, you PyObject_GetAttrString() the config's __dict__. This sets up a
situation where outside this conditional, you are inconsistent with dict's
refcount. The if-clause has one lower reference than the else-clause because
PyObject_GetAttrString returns a new reference. Thus it's possible that
PyDict_Check and PyDict_Next are operating on an object for which the client doesn't hold sufficient references. You're also leaking dict when you've gone through the else-clause. Suggestion: incref dict in the if-clause and add a
decref of dict before the return at the end of the function.
This is dead code. configs as dictionaries have never worked and aren't used anywhere. We always just pass in None as the config so the default config gets used. I've removed this bit of code.


client.c:318 client_set_notify_funct() where notify_baton2 has inconsistent
refcounting between the if-clause and else-clause. When you go through the
if-clause, notify_baton2 steals a reference to Py_None, which is going to get decref'd in client_dealloc(). The Py_XDECREF there does not protect you from
the extra decref of Py_None! You can see that if you go through the
else-clause, func will get incref'd, but if you go through the if-clause, you
actually leak func! Suggestion: incref notify_baton2 instead of func.
I don't follow - further down in that function we Py_INCREF func, so we always increment the reference count of func if we assign it to notify_baton2.


client_proplist, inside the props->nelts loop, the PyList_Append return value
is not checked. Not likely to fail, but more seriously, `value` is leaked.
Py_BuildValue returns a new reference, but PyList_Append does not steal its
reference. Thus you leak every `value`.
fixed.


editor.c:58, new_editor_object: you (probably, haven't checked the call-sites) need to incref commit_callback, since it gets decref'd in py_editor_dealloc.
Looks like the refcounts are unmatched.
The caller is responsible for increasing the ref counter of commit_callback.

Other problems:

* wrap_py_commit_items(): leaks ret when the PyList_SetItem returns on line
118.

Fixed.


* client.c:145: PyList_Append return value unchecked, probably harmless though
a (void) should be added.

Fixed.


* client.c:167: similar for PyDict_SetItemString

Fixed.


* client.c:256: py_cancel_check should be incref'd?

It's a C function, I don't see why it could go away.


* client.c, multiple locations: PyArg_Parse* does not incref 'O' arguments, so
be careful about calling back into Python with any such parsed object. You
need to ensure your library increfs such objects before a potential call
back into Python, and then decrefs it when you're done with the Python
call. I haven't audited all the places this happens, so this could be a
false alarm (i.e. you don't call back into Python).
I'm not aware of any places where we do that in client.c.


* client.c:925: prop_list leaks in the error condition return
* client.c:1037: leaks ret when PyList_SetItem returns non-zero.
fixed.
* client.c:1086: leaks entry_dict in the error return path




* client.c:1251: PyList_SetItem return value not checked

fixed.


* client.c:1279: PyDict_SetItemString return value not checked

fixed.



* client.c:1473: leaks `data` when data->pool is NULL.

Fixed.

Cheers,

Jelmer



--
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to