This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: socket.getsockopt may require custom buffer contents
Type: enhancement Stage:
Components: Extension Modules Versions: Python 3.2
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: neologix, pitrou, python-dev, ximaera
Priority: normal Keywords: patch

Created on 2011-09-25 17:12 by ximaera, last changed 2022-04-11 14:57 by admin.

Files
File name Uploaded Description Edit
getsockopt_buffer_input.patch ximaera, 2011-09-25 17:12
getsockopt_buffer_input_v2.patch ximaera, 2011-10-03 18:29
Messages (4)
msg144526 - (view) Author: Artyom Gavrichenkov (ximaera) Date: 2011-09-25 17:12
Currently the Python implementation of socket.getsockopt allows only option name, level name and buffer size as its arguments. However, IEEE Standard 1003.1-2008 allows one further argument -- an actual buffer to modify at the kernel level. POSIX does not prohibit the kernel from reading this buffer before modification, and the contents of the buffer may be used together with option and level names to specify an exact socket option to return.

In fact, this is how some applications already work, ipset (http://ipset.netfilter.org/) being a noticeable example.

The patch, written against Python 3.2 and aiming at providing this functionality, is attached. It may also apply to previous Python versions, though it's not tested against anything except Python 3.2.
msg144824 - (view) Author: Charles-François Natali (neologix) * (Python committer) Date: 2011-10-03 17:04
Hello,

method:: socket.getsockopt(level, optname[, optarg])

The overloading of the third parameter is confusing: it can already be an integer value or a buffer size, I don't think that adding a third possibility is a good idea. It might be better to add another optional `buffer` argument (and ignore `buflen` if this argument is provided).

Also, it would be nice to have a corresponding unit test: since I doubt this buffer argument is supported by many Unices out there, you can probably reuse a subset of what ipset does (just take care and guard it by @support.requires_linux_version() if applicable).
msg144828 - (view) Author: Artyom Gavrichenkov (ximaera) Date: 2011-10-03 18:29
Hi Charles-François,

I've attached an update for the previous patch. Now there's no more overloading for the third argument and socket.getsockopt accepts one more optional argument -- a buffer to use as an input to kernel.

I can provide a manual sample script, with getsockopt being used this way, that depends on Linux ipset kernel module being installed and modprobe'd. However, automatic unit test is not that easy to implement. Generally ipset requires certain kernel modules to operate, and we either have to install ipset in order to run a unit test, or to implement some mock Linux kernel module purely for testing and support it against all possible kernel versions. Not to mention that such a test should be carried out by root user only.

By the way, I don't really think that any POSIX-compliant UNIX out there would treat the buffer given to getsockopt in any way different from what Linux does. It is very easy to copy the buffer from user to kernel and back, and it is so inconvenient to prevent kernel from reading it prior to modification, that I bet no one has ever bothered to do this.
msg144958 - (view) Author: Charles-François Natali (neologix) * (Python committer) Date: 2011-10-05 16:45
> I've attached an update for the previous patch. Now there's no more
> overloading for the third argument and socket.getsockopt accepts one more
> optional argument -- a buffer to use as an input to kernel.

Remarks:
"""
+   length.  If *buffer* is absent and *buflen* is an integer, then *buflen*
[...]
+   this buffer is returned as a bytes object.  If *buflen* is absent,
an integer
"""
There's a problem here, the first buflen part should probably be removed.

Also, you might want to specify that if a custom buffer is provided,
the length argument will be ignored.

> By the way, I don't really think that any POSIX-compliant UNIX out there
> would treat the buffer given to getsockopt in any way different from what
> Linux does. It is very easy to copy the buffer from user to kernel and back,
> and it is so inconvenient to prevent kernel from reading it prior to
> modification, that I bet no one has ever bothered to do this.

Me neither, I don't expect the syscall to return EINVAL: the goal is
just to test the correct passing of the input buffer, and the length
computation.

If we can't test this easily within test_socket, it's ok, I guess the
following should be enough:
- try supplying a non-buffer argument as fourth parameter (e.g. and
int), and check that you get a ValueError
- supply a buffer with a size == sizeof(int) (SIZEOF_INT is defined in
Lib/test/test_socket.py), and call getsockopt(socket.SOL_SOCKET,
socket.SO_REUSEADDR, 0, <buffer>): this should normally succeed, and
return a buffer (check the return type)
History
Date User Action Args
2022-04-11 14:57:21adminsetgithub: 57254
2011-10-05 16:45:31neologixsetmessages: + msg144958
2011-10-03 18:29:28ximaerasetfiles: + getsockopt_buffer_input_v2.patch

messages: + msg144828
2011-10-03 17:04:46neologixsetmessages: + msg144824
2011-10-03 16:48:27ximaerasetnosy: + pitrou
2011-10-03 16:41:08ximaerasetnosy: + neologix
2011-10-03 15:19:15ximaerasetnosy: + python-dev
2011-09-25 20:25:45ximaerasettitle: [PATCH] socket.getsockopt may require custom buffer contents -> socket.getsockopt may require custom buffer contents
2011-09-25 17:12:20ximaeracreate