-
-
Notifications
You must be signed in to change notification settings - Fork 30.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
socket: Buffer overrun while reading unterminated AF_UNIX addresses #52619
Comments
|
The makesockaddr() function in the socket module assumes that When receiving such an address (e.g. in accept() from a This can't currently be tested from within Python as Python also Python 2.7a4+ (trunk, Apr 8 2010, 18:20:28)
[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> s = socket.socket(socket.AF_UNIX)
>>> s.bind("a" * 108)
>>> s.getsockname()
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\xfa\xbf\xa8)\xfa\xbf\xec\x15\n\x08l\xaaY\xb7\xb8CZ\xb7'
>>> len(_)
126Also attached are some unit tests for use with the above patch, a Firstly, the return-unterminated-* patches make makesockaddr() However, there's one more catch before this will work on Linux, The addrlen-* patches handle this by always calling There is one other issue: the patches for 3.x retain the |
|
Attaching the C test programs I forgot to attach yesterday - Unlike Linux, FreeBSD also accepted oversized sockaddr_un |
|
With the patches applied except linux-pass-unterminated.diff, I get the following test failure: ====================================================================== Traceback (most recent call last):
File "/home/antoine/py3k/__svn__/Lib/test/test_socket.py", line 1435, in testMaxPathLen
self.sock.bind(path)
socket.error: AF_UNIX path too longI guess this test should simply removed. |
(not sure which test you are referring to: the test case, or the Instead, I think that testMaxPathLen is incorrect: it doesn't |
The test passes (I assume) if linux-pass-unterminated.diff is applied. The latter patch is only meant to exhibit the issue, though, not to be checked in. |
No, I meant for linux-pass-unterminated.diff to be checked in so |
|
baikie, coming back to your original message: what precisely makes you believe that sun_path does not need to be null-terminated on Linux? |
That's the way I demonstrated the bug - the only way to bind to a However, it does now occur to me that a replacement libc Attaching four-space-indent versions of the original patches (for |
|
I've updated the PEP-383 patches at issue bpo-8373 with separate If it's not essential to have unit tests for the overrun issue, |
|
I see. Looking at net/unix/af_unix.c:unix_mkname of Linux 2.6, there is a comment that says Check unix socket name: [...] However, the code then just does /*
* This may look like an off by one error but it is a bit more
* subtle. 108 is the longest valid AF_UNIX path for a binding.
* sun_path[108] doesnt as such exist. However in kernel space
* we are guaranteed that it is a valid memory location in our
* kernel address buffer.
*/
((char *)sunaddr)[len] = 0;
len = strlen(sunaddr->sun_path)+1+sizeof(short);
return len;So it doesn't actually check that it's null-terminated, but always sets the null termination in kernel based on the address length. Interesting. With all the effort that went into the patch, I recommend to get it right: if there is space for the \0, include it. If the string size is exactly 108, and it's linux, write it unterminated. Else fail. As for testing: we should then definitely have a test that, if you can create an 108 byte unix socket that its socket name is what we said it should be. |
The attached patches do those things, if I understand you If you're talking about including the null in the address passed |
|
I meant to say that FreeBSD provides the SUN_LEN macro, but it The examples in Stevens/Rago's "Advanced Programming in the Unix |
I didn't (mean to) suggest that the null must be included in the |
|
Is this a security issue or just a regular bug? |
|
It's a potential security issue. |
|
The patches look good to me, except that instead of passing as addrlen argument every time makesockaddr is called, I'd prefer if this min was done inside makesockaddr itself, i.e. perform min(addrlen, sizeof(struct sockaddr_un)) in the AF_UNIX switch case (especially since addrlen is only used for AF_UNIX). |
|
On Sun 12 Jun 2011, Charles-François Natali wrote:
Actually, I think it should be clamped at the top of the I'm also attaching new return-unterminated patches to handle the This may well never happen (Python's existing code would raise (I think the decoders for other address families should also Also, I noticed that on Linux, Python 3.x currently returns empty To sum up the patch order: 2.x: 3.2: default: |
|
As this is flagged as a high priority security issue shouldn't we be implementing needed source code changes? According to msg138224 "The patches look good to me". |
|
I've rebased the patches onto all the currently released The fix-overrun patches can be applied on their own, but don't The 3.5 branch has some more substantial changes which stop the |
|
Attaching patches for 3.5. |

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.

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:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: