2002-08-08 16:13:27

by Michael Procter

[permalink] [raw]
Subject: Unix-domain sockets - abstract addresses

I have been trying to use unix domain datagram sockets in an application,
but have found what appears to be an inconsistency between the kernel and
the manpage unix(7).

I have a server, which creates a socket, binds it to an address and then
does a recvfrom(). When it gets a packet, it tries to respond with
sendto(), supplying the address information from the recvfrom() call.

All this works fine when the client binds it's socket to an address in the
filesystem before issuing the connect(). But I don't want another
filesystem entity, so I am trying to use an address in the abstract
namespace.

Abstract addresses work fine when the client calls bind() with an address
length of 2, and also if it sets the socket option SO_PASSCRED before
connect(). But if the client does neither and simply calls connect(),
the server gets an invalid 'from' address (address family usually zero,
but I have seen 0x0BA5, 0x7FA8, 0x1FA8 and others).

According to the man page 'unix(7)':
When a socket is connected and it doesn't already have a local address a
unique address in the abstract namespace will be generated automatically.

So, the question is: which is right? The man page, or af_unix.c?

I have been doing my tests on 2.4.9-34 (RedHat 7.2), but looking at 2.4.19
from kernel.org, the results should be the same.

Regards,

Michael Procter


2002-08-08 18:33:09

by Alexey Kuznetsov

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

Hello!

> According to the man page 'unix(7)':
> When a socket is connected and it doesn't already have a local address a
> unique address in the abstract namespace will be generated automatically.

This is wrong. The address is not autogenerated unless SO_PASSCRED
is requested by security&compatibility reasons.
So, if the socket is SOCK_DGRAM it is anounymous and "send-only",
it is impossible to reply to it.


> but I have seen 0x0BA5, 0x7FA8, 0x1FA8 and others).

Yes, this is bug. The fix is enclosed. It should return nil address.

> So, the question is: which is right? The man page, or af_unix.c?

Both of them are wrong.

Alexey


--- af_unix.c.orig Thu Aug 8 22:23:56 2002
+++ af_unix.c Thu Aug 8 22:34:58 2002
@@ -1432,7 +1432,7 @@

static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
{
- msg->msg_namelen = sizeof(short);
+ msg->msg_namelen = 0;
if (sk->protinfo.af_unix.addr) {
msg->msg_namelen=sk->protinfo.af_unix.addr->len;
memcpy(msg->msg_name,

2002-08-09 00:25:53

by Thunder from the hill

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

Hi,

On Thu, 8 Aug 2002 [email protected] wrote:
> - msg->msg_namelen = sizeof(short);
> + msg->msg_namelen = 0;

This version is for 2.5:

--- linus-2.5/net/unix/af_unix.c Mon Aug 5 12:02:05 2002
+++ thunder-2.5/net/unix/af_unix.c Thu Aug 8 18:28:49 2002
@@ -79,6 +79,8 @@
* with BSD names.
*/

+#undef unix /* KBUILD_MODNAME */
+
#include <linux/module.h>
#include <linux/config.h>
#include <linux/kernel.h>
@@ -1400,7 +1402,9 @@
{
struct unix_sock *u = unix_sk(sk);

- msg->msg_namelen = sizeof(short);
+ // msg->msg_namelen = sizeof(short);
+ msg->msg_namelen = 0;
+
if (u->addr) {
msg->msg_namelen = u->addr->len;
memcpy(msg->msg_name, u->addr->name, u->addr->len);

Thunder
--
.-../../-./..-/-..- .-./..-/.-.././.../.-.-.-

2002-08-09 13:50:31

by Michael Procter

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

[email protected] wrote:
>
> > According to the man page 'unix(7)':
> > When a socket is connected and it doesn't already have a local address a
> > unique address in the abstract namespace will be generated automatically.
>
> This is wrong. The address is not autogenerated unless SO_PASSCRED
> is requested by security&compatibility reasons.
> So, if the socket is SOCK_DGRAM it is anounymous and "send-only",
> it is impossible to reply to it.

Why is the address not generated for 'security & compatibility' reasons?
I've tried to think of a few reasons why this might be the case, but I
can't come up with anything very convincing.

I've been drawing parallels between PF_UNIX/SOCK_DGRAM and
PF_INET/SOCK_DGRAM. From an interface point of view, they are very similar
(to the extend my app cares), apart from this lack of automatic address
generation for unix sockets.

It seems odd that you can send a message to another process, and for the
other end to have no way whatsoever of identifying the sender. The same
situation in PF_INET doesn't exist - you get given a free port if you don't
specify one by the time you connect().


> > but I have seen 0x0BA5, 0x7FA8, 0x1FA8 and others).
> Yes, this is bug. The fix is enclosed. It should return nil address.

Thanks for the patch (thanks also to Thunder who sent one for 2.5).
However, there is still an inconsistency. The function unix_getname()
will return just an address family if no address is present. Here is a
diff that fixes this, and includes your change.

--- af_unix.c.orig Fri Aug 9 14:10:05 2002
+++ af_unix.c Fri Aug 9 14:17:38 2002
@@ -1101,9 +1101,7 @@

unix_state_rlock(sk);
if (!sk->protinfo.af_unix.addr) {
- sunaddr->sun_family = AF_UNIX;
- sunaddr->sun_path[0] = 0;
- *uaddr_len = sizeof(short);
+ *uaddr_len = 0;
} else {
struct unix_address *addr = sk->protinfo.af_unix.addr;

@@ -1385,7 +1383,7 @@

static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
{
- msg->msg_namelen = sizeof(short);
+ msg->msg_namelen = 0;
if (sk->protinfo.af_unix.addr) {
msg->msg_namelen=sk->protinfo.af_unix.addr->len;
memcpy(msg->msg_name,


Regards,

Michael Procter

2002-08-09 16:13:43

by Alexey Kuznetsov

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

Hello!

> Why is the address not generated for 'security & compatibility' reasons?

Compatibility: traditional unix domain sockets are not autobound.
So request for binding must be explicit. SO_RECVCRED, being not present
in traditional api, is consifered as such request, at least it indicates
that you are going to receive something.

Security: interlopers are not able to send to socket which has no address,
except for case when peering was established explicitly f.e. with socketpair().
Actually, (almost) simultaneously with possibility to autobind another
check was added which relieves this security issue: namely, if socket
A is connected to B, we reject all the sends to A from anywhere except for B.
However the problem remains f.e. for the case when socket A was disconnected
due to temporary shutdown of B.


> PF_INET/SOCK_DGRAM. From an interface point of view, they are very similar

The difference is that UDP does not provide any kind of security at all.
Unix domain sockets do and used exactly in circumstances when it is important.


> However, there is still an inconsistency.

Yes. I am not sure, what is right. Most likely, my patchlet was wrong.
Need to compare with another OSes.

Alexey

2002-08-09 22:29:48

by Thunder from the hill

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

Hi,

On Fri, 9 Aug 2002, Michael Procter wrote:
> --- af_unix.c.orig Fri Aug 9 14:10:05 2002
> +++ af_unix.c Fri Aug 9 14:17:38 2002

Well, if it's right, here goes the update:

--- linus-2.5/net/unix/af_unix.c Mon Aug 5 12:02:05 2002
+++ thunder-2.5/net/unix/af_unix.c Fri Aug 9 16:28:36 2002
@@ -79,6 +79,8 @@
* with BSD names.
*/

+#undef unix /* KBUILD_MODNAME */
+
#include <linux/module.h>
#include <linux/config.h>
#include <linux/kernel.h>
@@ -1114,9 +1116,7 @@

unix_state_rlock(sk);
if (!u->addr) {
- sunaddr->sun_family = AF_UNIX;
- sunaddr->sun_path[0] = 0;
- *uaddr_len = sizeof(short);
+ *uaddr_len = 0;
} else {
struct unix_address *addr = u->addr;

@@ -1400,7 +1400,8 @@
{
struct unix_sock *u = unix_sk(sk);

- msg->msg_namelen = sizeof(short);
+ msg->msg_namelen = 0;
+
if (u->addr) {
msg->msg_namelen = u->addr->len;
memcpy(msg->msg_name, u->addr->name, u->addr->len);

Thunder
--
--./../...-/. -.--/---/..-/.-./..././.-../..-. .---/..-/.../- .-
--/../-./..-/-/./--..-- ../.----./.-../.-.. --./../...-/. -.--/---/..-
.- -/---/--/---/.-./.-./---/.--/.-.-.-
--./.-/-.../.-./.././.-../.-.-.-

2002-08-10 01:14:35

by David Miller

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

From: Thunder from the hill <[email protected]>
Date: Fri, 9 Aug 2002 16:33:18 -0600 (MDT)

--- linus-2.5/net/unix/af_unix.c Mon Aug 5 12:02:05 2002
+++ thunder-2.5/net/unix/af_unix.c Fri Aug 9 16:28:36 2002
@@ -79,6 +79,8 @@
* with BSD names.
*/

+#undef unix /* KBUILD_MODNAME */
+

Explain to me what this giblet is for?

2002-08-10 01:31:31

by Keith Owens

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

On Fri, 09 Aug 2002 18:05:00 -0700 (PDT),
"David S. Miller" <[email protected]> wrote:
> --- linus-2.5/net/unix/af_unix.c Mon Aug 5 12:02:05 2002
> +++ thunder-2.5/net/unix/af_unix.c Fri Aug 9 16:28:36 2002
> @@ -79,6 +79,8 @@
> * with BSD names.
> */
>
> +#undef unix /* KBUILD_MODNAME */
> +
>
>Explain to me what this giblet is for?

Rusty's plan to standardize boot and module parameters needs the
overall "module name" in the code, whether the code is built in or a
module. KBUILD_MODNAME defines the overall module name based on the
linkage data.

Sometimes KBUILD_MODNAME is used quoted, sometimes it is used unquoted.
We can quote it easily (__stringify) but AFAIK there is no way in cpp
to strip quotes from a string, so KBUILD_MODNAME has to be passed as a
bare word, without quotes.

af_unix.c is linked into unix.o so we have -DKBUILD_MODNAME=unix. Alas
we also have -Dunix=1. __stringify(KBUILD_MODNAME) -> __stringify(unix) ->
"1" instead of "unix".

2002-08-10 01:50:37

by David Miller

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

From: Keith Owens <[email protected]>
Date: Sat, 10 Aug 2002 11:35:04 +1000

af_unix.c is linked into unix.o so we have -DKBUILD_MODNAME=unix. Alas
we also have -Dunix=1. __stringify(KBUILD_MODNAME) -> __stringify(unix) ->
"1" instead of "unix".

This seems really tacky. There must be a better way to do this.
Perhaps prepending some constant string prefix to these module
names such that they will not collide with the namespace in
this way. For example, "kmod_".

2002-08-10 02:15:42

by Keith Owens

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

On Fri, 09 Aug 2002 18:41:04 -0700 (PDT),
"David S. Miller" <[email protected]> wrote:
> From: Keith Owens <[email protected]>
> Date: Sat, 10 Aug 2002 11:35:04 +1000
>
> af_unix.c is linked into unix.o so we have -DKBUILD_MODNAME=unix. Alas
> we also have -Dunix=1. __stringify(KBUILD_MODNAME) -> __stringify(unix) ->
> "1" instead of "unix".
>
>This seems really tacky. There must be a better way to do this.
>Perhaps prepending some constant string prefix to these module
>names such that they will not collide with the namespace in
>this way. For example, "kmod_".

Adding a constant prefix to every label and string will increase the
size of the kernel. I would much rather find a way for cpp to strip
quotes from a #define, then -DKBUILD_OBJECT=\"unix\" has no problems.
But I don't know any cpp construct to convert KBUILD_OBJECT ("unix") to
bare 'unix' without the quotes. Undefining conflicting names is tacky
but it has the least (zero) impact on the kernel size.

ps. The variable name is KBUILD_OBJECT, not KBUILD_MODNAME. The
comment is wrong.

2002-08-10 02:25:01

by David Miller

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

From: Keith Owens <[email protected]>
Date: Sat, 10 Aug 2002 12:19:13 +1000

Adding a constant prefix to every label and string will increase the
size of the kernel.

It was just an idea.

I rather don't care how you solve the problem. What I do care
about is adding garbage like #undef unix to source files, that
part is the bit I find unacceptable.

2002-08-10 06:25:43

by Thunder from the hill

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

Hi,

On Fri, 9 Aug 2002, David S. Miller wrote:
> +#undef unix /* KBUILD_MODNAME */
> +
>
> Explain to me what this giblet is for?

Piece of the automagic modinit patch... Shouldn't be there...

Thunder
--
--./../...-/. -.--/---/..-/.-./..././.-../..-. .---/..-/.../- .-
--/../-./..-/-/./--..-- ../.----./.-../.-.. --./../...-/. -.--/---/..-
.- -/---/--/---/.-./.-./---/.--/.-.-.-
--./.-/-.../.-./.././.-../.-.-.-

2002-08-10 10:55:47

by Roman Zippel

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

Hi,

On Sat, 10 Aug 2002, Keith Owens wrote:

> Adding a constant prefix to every label and string will increase the
> size of the kernel. I would much rather find a way for cpp to strip
> quotes from a #define, then -DKBUILD_OBJECT=\"unix\" has no problems.
> But I don't know any cpp construct to convert KBUILD_OBJECT ("unix") to
> bare 'unix' without the quotes. Undefining conflicting names is tacky
> but it has the least (zero) impact on the kernel size.

I think prepending an underscore would also be an acceptable solution. The
size increase is minimal and it's easy to remove from the stringified
name.

bye, Roman

2002-08-12 02:31:28

by Oliver Xymoron

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

On Sat, 10 Aug 2002, Keith Owens wrote:

> On Fri, 09 Aug 2002 18:41:04 -0700 (PDT),
> "David S. Miller" <[email protected]> wrote:
> > From: Keith Owens <[email protected]>
> > Date: Sat, 10 Aug 2002 11:35:04 +1000
> >
> > af_unix.c is linked into unix.o so we have -DKBUILD_MODNAME=unix. Alas
> > we also have -Dunix=1. __stringify(KBUILD_MODNAME) -> __stringify(unix) ->
> > "1" instead of "unix".
> >
> >This seems really tacky. There must be a better way to do this.
> >Perhaps prepending some constant string prefix to these module
> >names such that they will not collide with the namespace in
> >this way. For example, "kmod_".
>
> Adding a constant prefix to every label and string will increase the
> size of the kernel. I would much rather find a way for cpp to strip
> quotes from a #define, then -DKBUILD_OBJECT=\"unix\" has no problems.
> But I don't know any cpp construct to convert KBUILD_OBJECT ("unix") to
> bare 'unix' without the quotes. Undefining conflicting names is tacky
> but it has the least (zero) impact on the kernel size.

Might it be simpler to change the overall module name? unix.o is an
especially poor choice of names, compiler defines aside.

--
"Love the dolphins," she advised him. "Write by W.A.S.T.E.."

2002-08-12 02:56:14

by Keith Owens

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

On Sun, 11 Aug 2002 21:35:05 -0500 (CDT),
Oliver Xymoron <[email protected]> wrote:
>> > From: Keith Owens <[email protected]>
>> > Date: Sat, 10 Aug 2002 11:35:04 +1000
>> >
>> > af_unix.c is linked into unix.o so we have -DKBUILD_MODNAME=unix. Alas
>> > we also have -Dunix=1. __stringify(KBUILD_MODNAME) -> __stringify(unix) ->
>> > "1" instead of "unix".
>
>Might it be simpler to change the overall module name? unix.o is an
>especially poor choice of names, compiler defines aside.

I prefer that option, expect that it changes the name of a module. Not
that we haven't done that before ...

A module name of af_unix would be much better, like af_packet. It
would require changing the name of af_unix.c (source and conglomerate
objects cannot have the same basename) and a change to modutils to map
net-pf-1 to af_unix.

2002-08-12 03:08:51

by David Miller

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

From: Keith Owens <[email protected]>
Date: Mon, 12 Aug 2002 12:59:53 +1000

On Sun, 11 Aug 2002 21:35:05 -0500 (CDT),
Oliver Xymoron <[email protected]> wrote:
>Might it be simpler to change the overall module name? unix.o is an
>especially poor choice of names, compiler defines aside.

I prefer that option, expect that it changes the name of a module. Not
that we haven't done that before ...

A module name of af_unix would be much better, like af_packet. It
would require changing the name of af_unix.c (source and conglomerate
objects cannot have the same basename) and a change to modutils to map
net-pf-1 to af_unix.

I don't like this solution, please fix this right and get rid of the
limitations at their source.

If I name a module "foo" and this causes "fo" to become a defined
CPP symbol in when compiling the sources for that module, that is
completely broken!

net/unix is just a trite example. How about a driver for device "foo"
that has a member "foo" in one of it's structures? They have to get
this undef thing too or rename their module, that's rediculious.

2002-08-12 03:16:29

by Keith Owens

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

On Sun, 11 Aug 2002 19:59:06 -0700 (PDT),
"David S. Miller" <[email protected]> wrote:
>I don't like this solution, please fix this right and get rid of the
>limitations at their source.
>
>If I name a module "foo" and this causes "fo" to become a defined
>CPP symbol in when compiling the sources for that module, that is
>completely broken!
>
>net/unix is just a trite example. How about a driver for device "foo"
>that has a member "foo" in one of it's structures? They have to get
>this undef thing too or rename their module, that's rediculious.

I think you misunderstood the problem. Calling a driver "foo" does not
make "foo" a cpp symbol. The problem here is that 'unix' is a driver
name and also a symbol that is defined by gcc.

2002-08-12 03:22:59

by David Miller

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

From: Keith Owens <[email protected]>
Date: Mon, 12 Aug 2002 13:20:09 +1000

The problem here is that 'unix' is
...
a symbol that is defined by gcc.

I see. GCC really shouldn't be doing that as it pollutes the global
namespace. However, I see current 3.x vintage gcc is still doing it
under Linux so there must be a reason it is kept around.

2002-08-12 03:53:55

by Keith Owens

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

On Sun, 11 Aug 2002 20:13:14 -0700 (PDT),
"David S. Miller" <[email protected]> wrote:
> From: Keith Owens <[email protected]>
> Date: Mon, 12 Aug 2002 13:20:09 +1000
>
> The problem here is that 'unix' is
> ...
> a symbol that is defined by gcc.
>
>I see. GCC really shouldn't be doing that as it pollutes the global
>namespace. However, I see current 3.x vintage gcc is still doing it
>under Linux so there must be a reason it is kept around.

Untested, against 2.5.31. It would be better to -Uunix globally but
one header depends on it, drivers/message/fusion/lsi/mpi_type.h.

--- 2.5.31-pristine/net/unix/Makefile.orig Sat May 25 14:50:09 2002
+++ 2.5.31-pristine/net/unix/Makefile Mon Aug 12 13:54:54 2002
@@ -8,5 +8,7 @@
unix-$(CONFIG_SYSCTL) += sysctl_net_unix.o
unix-objs := $(unix-y)

+EXTRA_CFLAGS += -Uunix # avoid gcc namespace pollution
+
include $(TOPDIR)/Rules.make


2002-08-12 07:22:39

by Eric W. Biederman

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses

Keith Owens <[email protected]> writes:

> On Sun, 11 Aug 2002 20:13:14 -0700 (PDT),
> "David S. Miller" <[email protected]> wrote:
> > From: Keith Owens <[email protected]>
> > Date: Mon, 12 Aug 2002 13:20:09 +1000
> >
> > The problem here is that 'unix' is
> > ...
> > a symbol that is defined by gcc.
> >
> >I see. GCC really shouldn't be doing that as it pollutes the global
> >namespace. However, I see current 3.x vintage gcc is still doing it
> >under Linux so there must be a reason it is kept around.
>
> Untested, against 2.5.31. It would be better to -Uunix globally but
> one header depends on it, drivers/message/fusion/lsi/mpi_type.h.

Additionally a version of stringify that did not expand macros would
also solve this problem.

Eric

2002-08-12 14:25:17

by David Woodhouse

[permalink] [raw]
Subject: Re: Unix-domain sockets - abstract addresses


[email protected] said:
> Untested, against 2.5.31. It would be better to -Uunix globally but
> one header depends on it, drivers/message/fusion/lsi/mpi_type.h.

/me looks... Urgh. Let it break.


--
dwmw2