bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bug#187391: PortingIssues sockaddr_un


From: Ognyan Kulev
Subject: Re: Bug#187391: PortingIssues sockaddr_un
Date: Mon, 14 Apr 2003 16:19:03 +0300
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3) Gecko/20030327 Debian/1.3-4

Robert Millan wrote:
On Sun, Apr 13, 2003 at 04:19:53PM +0300, Ognyan Kulev wrote:

Now I've made it clear in the page that this example is about constant C string that one is sure to be of length no longer than 100.

No. you need to pay attention to the API docs. It says you are _garanteed_
an alloced space of 108 (no more, no less) bytes for sun_path.

This arbitrary limit (108) is just for *nix compatibility -- programs expect to be able to do something like:

struct sockaddr_un su;
su.sun_family = AF_LOCAL;
strcpy (su.sun_path, "/path/to/socket"); /* for constant strings!  */

By using Niels' test program it comes out that on GNU/Linux you have
exactly 108 chars and on GNU you have more space. In my system it came
to be that i have 260 bytes, but attempting to use 261 fails.

Ext2 has limitation on path name _component_ and this limit is 255. So we have strlen("/tmp/")=5 + 255 = 260. This limitation is in ext2, not in sockaddr_un. If the prefix was something like "/tmp/1234/" then the limit would be 265.

So, we have these choices:

1- strictly adhering to the API docs, and using 108 bytes (no less, if
the string is shorter fill with 0es with strncpy) for Glibc.

This is not the GNU way.

2- assuming there's no limitation on GNU, which is wrong and will lead
to overflows.

This is exactly the case. All we need to do is to alloca sockaddr_un with the correct size (that can be of any length) and fill it.

3- assuming the limit on GNU is 260 bytes, which is also wrong as you
have no garantee that this will change for future versions or other
system instances.

As I showed above there is no such limit in GNU.

4- using SUN_LEN to determine it, which is wrong as SUN_LEN is unrelated
to sun_path's length. see the docs:
>
>    You should compute the LENGTH parameter for a socket address in the
>    local namespace as the sum of the size of the `sun_family' component
>    and the string length (_not_ the allocation size!) of the file name
>    string.  This can be done using the macro `SUN_LEN':
>

SUN_LEN is just a helper macro. We can perfectly go without it. For example:

size_t filename_len = strlen (filename);
socklen_t su_len =
  offsetof (struct sockaddr_un, sun_path) + filename_len;
struct sockaddr_un *su = alloca (su_len);
su->sun_family = AF_LOCAL;
memcpy (su->sun_path, filename, filename_len);
if (bind (sock, (struct sockaddr *)su, su_len))
...

the problem here is that sun_path is NOT a nul-terminated string. if it
was, you could just use strlen to determine its string length. so in order
to obtain the string length, you can use SUN_LEN for that. but this _IS NOT_
the allocation size! the allocation size is in the sun_path definition
and it's a constant of 108 chars. it just means you have this:

sun_path[0..SUN_LEN] --> your string
sun_path[SUN_LEN..108] --> useless junk. typicaly 0es if you used strncpy

SUN_LEN is macro that calculates what value you should pass to bind, etc. It is not something like #define SUN_LEN 108.

but we don't need to care about the string length at all, this is something
the program implementation should (or should not) do already. our issue
is this simple: a "const char *" satisfies sun_path on GNU/Linux but doesn't
satisfy sun_path on GNU. so the solution is to adhere strictly to the API
and copy the actual string instead of a pointer to it. this is why we need
to set the 108 byte limit in strncpy. (with a const char * there's no need
to hardcode a limit, just write short enough strings..)

of course, a better solution could be to allow the pointer in
sockaddr_un.sun_path to be replaced by a const char * for GNU. then we
wouldn't have to fix anything else.

I have a question for you: how do you interpret RMS's suggestion to use `alloca'? Nowhere he mentions that alloca is for sun_path, and I think that it is about the whole sockaddr_un.

5- using an autoconf check to determine length of sockaddr_un.sun_len
in a sane way (say, iteratively attempting sizes untill it fails or
untill hell is frozen). this is correct and will allow GNU to use
its suposed 260 byte "advantage". but the rest of the code in all
programs is made sure to fit in 108 bytes, so this is a real overkill.

Again, there is no such limit in GNU, exactly like not having PATH_MAX.

Regards
--
Ognyan Kulev <ogi@fmi.uni-sofia.bg>, "\"Programmer\""





reply via email to

[Prev in Thread] Current Thread [Next in Thread]