Reading from socket: recv works read doesn't. Why ?

Luca Lizzeri (
Thu, 6 Mar 1997 13:06:51 +0100 (MET)

I am porting a motif application from SunOs to Linux.

I have two processes communicating over unix domain sockets.

On the Sun everything works fine (apart from permitting double freeing a
memory area and the like :), on Linux I have a problem with read():

socketpair(PF_UNIX, SOCK_STREAM, , 0, [8, 9]) = 0
fork() = 380
close(9) = 0
oldselect(1024, [8], NULL, NULL, {3600, 0}) = 1 (in [8], left {3598, 910000})
read(8, 0xbffff67c, 4096) = -1 EFAULT (Bad address)

read() returns EFAULT whether the read buffer is allocated on the stack
or is malloc'ed (both of size 4096).

Everything else being equal, recv works:

socketpair(PF_UNIX, SOCK_STREAM, , 0, [7, 8]) = 0
fork() = 519
close(8) = 0
oldselect(1024, [7], NULL, NULL, {3600, 0}) = 1 (in [7], left {3598, 730000})
recv(7, "OK\0", 4096, 0) = 3

This happens with kernel version 2.1.28 and libc-5.4.23. I must double
check on the university computer, (2.0.20 and libc-5.3.12), but the error
seems the same.

Upon further investigation, the code returning the error in the kernel is
in net/socket.c, in sock_read (line 367):

if ((err=verify_area(VERIFY_WRITE,ubuf,size))<0)
return err;

Of the two one: something is wrong in the app, therefore recv should
return the error too (it doesn't seem to do the above check), or read is
returning a bogus error.

Now, which one is it ? Me being clueless or a bug ? ( I usually try to
be as clueful as I can: double check Stevens' APUE, the man pages, follow
the path of the code in the kernel... I hope I didn't miss anything
obvious and am sticking my foot in my mouth :)