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.

Title: socketmodule.c`getsockaddrarg() should not check the length of sun_path
Type: behavior Stage: resolved
Components: None Versions: Python 2.6
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: Edward.Pilatowicz, akuchling, loewis, sable
Priority: normal Keywords:

Created on 2010-06-03 01:27 by Edward.Pilatowicz, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (5)
msg106929 - (view) Author: Edward Pilatowicz (Edward.Pilatowicz) Date: 2010-06-03 01:27
recently i was writing some python code that attempted to bind a unix
domain socket to a long filesystem path.  this code was failing and
telling me that the path name was too long.  tracing python i saw that
it wasn't event issuing a system call for my bind() request.  eventually
i tracked down the problem to socketmodule.c`getsockaddrarg():

there we see that getsockaddrarg() checks to verify that the specified
path is less than "sizeof addr->sun_path", where addr is a struct
sockaddr_un.  this seems incorrect to me.

on most systems sockaddr_un.sun_path is defined as a small character
array.  this limit is an ancient bit of unix legacy and most modern
systems do not actually limit domain socket names to a path as short as
sun_path.  on solaris the real limit is MAXPATHLEN, there by allowing
unix domain sockets to be bound to any filesystem path.

the posix specification also says that users of the sockaddr_un 
structure should not make any assumptions about the maximum supported
length of sun_path.


we have:
    char        sun_path[]    socket pathname

    The size of sun_path has intentionally been left undefined. This is
    because different implementations use different sizes. For example,
    4.3 BSD uses a size of 108, and 4.4 BSD uses a size of 104. Since
    most implementations originate from BSD versions, the size is
    typically in the range 92 to 108.

    Applications should not assume a particular length for sun_path or
    assume that it can hold {_POSIX_PATH_MAX} characters (255).

hence, it seems to me that python should not actually be doing any size
checks on the path passed to getsockaddrarg().  instead is should
dynamically allocate a sockaddr_un large enough to hold whatever string
was pass in.  this structure can then be passed on to system calls which
can they check if the specified path is of a supported length.  (if you
look at the posix definitions for bind() and connect() you'll see that 
they both can return ENAMETOOLONG if the passed in pathname is too 
msg106931 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2010-06-03 06:56
>      Applications should not assume a particular length for sun_path or
>      assume that it can hold {_POSIX_PATH_MAX} characters (255).
> hence, it seems to me that python should not actually be doing any size
> checks on the path passed to getsockaddrarg().

You are misinterpreting the specification. What they say is that the 
right way of doing it is the way Python currently does it.

"not assume a particular length" means "not assume, in the source code,
and specific fixed length, such as 108, or 255". Now, if the program 
must not assume any specific length, it must use sizeof instead to 
determine how large sun_path is.

If your operating system declares sun_path to be shorter than the 
strings it actually supports, complain to your operating system vendor 
that they fix their header files.
msg106993 - (view) Author: Edward Pilatowicz (Edward.Pilatowicz) Date: 2010-06-03 22:25
so i wrote a simple test program that tells me the defined length of
sun_path and then uses bind() with increasingly long paths to determine
the actually supported length of sun_path.  here's what i've found:

    defined sun_path = 108
    max sun_path = 1024

FreeBSD 8.0:
    defined sun_path = 104
    max sun_path = 254

Fedora 11:
    defined sun_path = 108
    max sun_path = 108

i have requested access to an AIX system to check what length of
sun_path is defined and supported there.

while i could request that this value be changed in the OS, that would 
likely cause problems with pre-existing compiled code.  i'm guessing
that most OS vendors would not be eager to update this value, which is
probably why it's been the same small value for such a long time.
msg107118 - (view) Author: Edward Pilatowicz (Edward.Pilatowicz) Date: 2010-06-05 00:52
some additional data.

AIX 6.1:
    defined sun_path = 1023
    max sun_path = 1023

i'll also point out the existence of the SUN_LEN() macro, which is
defined on all the previously mentioned operating systems, and which
calculates the size of a sockaddr_un structure using strlen() of
sun_path, not sizeof().

that said, as a counter argument, UNIX Network Programming by Richard
Stevens explicitly mentions that the use of sizeof() is ok.

still, personally, i think it's pretty risky for an OS to change this
definition.  (it seems that AIX is the only OS i've seen that has done
so.)  i say this because use of the sockaddr_un structure is so
prevalent.  it's commonly embedded into other structures and passed
around via APIs that (unlike bind(), connect(), etc) don't take a size
parameter which specifies the size of the structure.
msg240925 - (view) Author: A.M. Kuchling (akuchling) * (Python committer) Date: 2015-04-14 16:03
No changes seems to be necessary, per MvL's comment.
Date User Action Args
2022-04-11 14:57:01adminsetgithub: 53128
2015-04-14 16:03:43akuchlingsetstatus: open -> closed

nosy: + akuchling
messages: + msg240925

resolution: wont fix
stage: resolved
2010-09-14 13:07:45sablesetnosy: + sable
2010-06-05 00:53:00Edward.Pilatowiczsetmessages: + msg107118
2010-06-03 22:25:01Edward.Pilatowiczsetmessages: + msg106993
2010-06-03 06:56:55loewissetnosy: + loewis
title: socketmodule.c`getsockaddrarg() should not check the length of sun_path -> socketmodule.c`getsockaddrarg() should not check the length of sun_path
messages: + msg106931
2010-06-03 01:27:48Edward.Pilatowiczcreate