You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Reference counting bug in PyArg_ParseTuple and PyArg_ParseTupleAndKeywords #50333
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2009-05-22.08:18:54.577>labels= ['interpreter-core', 'type-crash']
title='Reference counting bug in PyArg_ParseTuple and PyArg_ParseTupleAndKeywords'updated_at=<Date2020-02-20.07:51:55.428>user='https://bugs.python.org/billm'
The code for resource_setrlimit in Modules/resource.c does not handle
reference counting properly. The following Python code segfaults for me
on Ubuntu 8.10 in Python 2.5.2 and also a custom-built 2.6.1.
The references curobj and maxobj are borrowed. The second argument can
be passed as a mutable list rather than a tuple, so it's possible to
update the list in the middle of setrlimit, causing maxobj to be
destroyed before setrlimit is done with it.
I've attached a patch that INCREFs both variables immediately after
parsing them to avoid this problem.
In my opinion it seems dangerous to allow format strings with the 'O'
specifier appearing in parentheses. You normally expect that objects
returned from PyArg_ParseTuple are pretty safe, but the fact that the
inner sequence may be mutable violates this assumption. Might it make
sense to ban this use case? I only found one other instance of it in the
Python source tree, inside ctypes. This one may also be a crashing
bug--I didn't look at it carefully enough.
IMO, any refcounting bug has the potential as a security risk. So I
think we should deprecate this with a warning, and eventually remove it,
as billm proposes.
It's probably debatable whether to backport the warning to 2.6 or
earlier; I think we shouldn't, as many applications are probably valid.
Actually, this can't be fixed without modifying C API methods PyArg_ParseTuple and PyArg_ParseTupleAndKeywords, because it's possible to make an object deallocated before PyArg_ParseTuple returns, so Py_INCREF immediately after parsing would be already too late.
changed the title [-]Reference counting bug in setrlimit[/-][+]Reference counting bug in PyArg_ParseTuple and PyArg_ParseTupleAndKeywords[/+]on Nov 16, 2010
Let me summarize the issue: the PyArg_ParseTuple format code 'O' returns a borrowed reference. However, when the 'O' code appears inside parenthesis, there may not be an object to hold the reference to borrow from. This is what happens in the test-functools.py crasher: partial.__setstate__() takes a 4-tuple argument that is unpacked using a "(OOOO)" format. The test case passes an instance instead of a tuple that supports the sequence methods, but does not hold the reference to the "items" that its []-operator returns. This is not a problem at the top level because args argument to PyArg_ParseTuple is always a real tuple.
I think that rather than deprecating the use of 'O' format inside parentheses, "(..O..)" unpacking should reject to unpack arguments other than tuples or maybe lists.
Attached patch passes the regrtest and makes test-functools.py raise an exception rather than crash. The proposed change will make functions like partial.__setstate__ require tuple argument even though currently it would accept any container. This is not an issue with __setstate__ because it should only be called with arguments produced by __reduce__ and in the case of partial, __reduce__ produces state as a tuple. Other functions may need to be modified if they need to continue to accept arbitrary sequences.
#128374 implements a more lenient variant of the initial deprecation plan. Non-tuple sequences are only deprecated if the nested format units store borrowed buffer or reference (e.g. "s" and "O"). If "(items)" only contains format units like "i" or "d" (or "s*"), general sequences are still accepted.
Activity
billm commentedon May 22, 2009
The code for resource_setrlimit in Modules/resource.c does not handle
reference counting properly. The following Python code segfaults for me
on Ubuntu 8.10 in Python 2.5.2 and also a custom-built 2.6.1.
--
--
The problem is that setrlimit gets its arguments by calling:
The references curobj and maxobj are borrowed. The second argument can
be passed as a mutable list rather than a tuple, so it's possible to
update the list in the middle of setrlimit, causing maxobj to be
destroyed before setrlimit is done with it.
I've attached a patch that INCREFs both variables immediately after
parsing them to avoid this problem.
In my opinion it seems dangerous to allow format strings with the 'O'
specifier appearing in parentheses. You normally expect that objects
returned from PyArg_ParseTuple are pretty safe, but the fact that the
inner sequence may be mutable violates this assumption. Might it make
sense to ban this use case? I only found one other instance of it in the
Python source tree, inside ctypes. This one may also be a crashing
bug--I didn't look at it carefully enough.
birkenfeld commentedon May 22, 2009
That is a good point. IMHO we'll be fine with a warning in the docs,
and fixing our own two instances. Martin, what do you think?
loewis commentedon May 22, 2009
IMO, any refcounting bug has the potential as a security risk. So I
think we should deprecate this with a warning, and eventually remove it,
as billm proposes.
It's probably debatable whether to backport the warning to 2.6 or
earlier; I think we shouldn't, as many applications are probably valid.
abacabadabacaba commentedon Nov 16, 2010
Actually, this can't be fixed without modifying C API methods PyArg_ParseTuple and PyArg_ParseTupleAndKeywords, because it's possible to make an object deallocated before PyArg_ParseTuple returns, so Py_INCREF immediately after parsing would be already too late.
Here are my test cases:
test-resource.py - in Modules/resource.c, and python-bug-01.patch won't work against it.
test-ctypes.py - in Modules/_ctypes/_ctypes.c.
test-functools.py - in Modules/_functoolsmodule.c (py3k only).
[-]Reference counting bug in setrlimit[/-][+]Reference counting bug in PyArg_ParseTuple and PyArg_ParseTupleAndKeywords[/+]abalkin commentedon Jan 14, 2011
Let me summarize the issue: the PyArg_ParseTuple format code 'O' returns a borrowed reference. However, when the 'O' code appears inside parenthesis, there may not be an object to hold the reference to borrow from. This is what happens in the test-functools.py crasher: partial.__setstate__() takes a 4-tuple argument that is unpacked using a "(OOOO)" format. The test case passes an instance instead of a tuple that supports the sequence methods, but does not hold the reference to the "items" that its []-operator returns. This is not a problem at the top level because args argument to PyArg_ParseTuple is always a real tuple.
I think that rather than deprecating the use of 'O' format inside parentheses, "(..O..)" unpacking should reject to unpack arguments other than tuples or maybe lists.
abalkin commentedon Jan 14, 2011
Attached patch passes the regrtest and makes test-functools.py raise an exception rather than crash. The proposed change will make functions like partial.__setstate__ require tuple argument even though currently it would accept any container. This is not an issue with __setstate__ because it should only be called with arguments produced by __reduce__ and in the case of partial, __reduce__ produces state as a tuple. Other functions may need to be modified if they need to continue to accept arbitrary sequences.
serhiy-storchaka commentedon Oct 14, 2012
Here is a patch which get rid of all three PyArg_ParseTuple usage with parsing nested sequences. Thanks Evgeny for reproducers.
18 remaining items
imz commentedon Mar 22, 2018
And will the next call be effective (do anything), if we have already set the limit with the testing call?
serhiy-storchaka commentedon Mar 22, 2018
LGTM.
(ValueError, OSError)
This doesn't matter. We test that it doesn't crash when parse arguments.
taleinat commentedon Jul 25, 2018
Ivan, can you supply a PR or would you like someone else to do so?
ananthan-123 commentedon Feb 20, 2020
I want to do a PR,if this is still needeed.
taleinat commentedon Feb 20, 2020
Please do, Ananthakrishnan!
arhadthedev commentedon Apr 29, 2023
No longer relevant because
resource.setrlimitis now ported to Argument Clinic.serhiy-storchaka commentedon Dec 31, 2024
While the issue was fixed for
resource.setrlimitand others (before it was ported to Argument Clinic), the root issue has not yet been fixed.pythongh-50333: Deprecate support of non-tuple sequences in PyArg_Par…
serhiy-storchaka commentedon Dec 31, 2024
#128374 implements a more lenient variant of the initial deprecation plan. Non-tuple sequences are only deprecated if the nested format units store borrowed buffer or reference (e.g. "s" and "O"). If "(items)" only contains format units like "i" or "d" (or "s*"), general sequences are still accepted.
gh-50333: Deprecate support of non-tuple sequences in PyArg_ParseTupl…