kern/134276: [linux][patch] MSG_NOSIGNAL not translated for recv(),
socket timeout incorrect for 64-bit hosts
Thomas Mueller
tmueller at sysgo.com
Wed May 6 17:00:10 UTC 2009
>Number: 134276
>Category: kern
>Synopsis: [linux][patch] MSG_NOSIGNAL not translated for recv(), socket timeout incorrect for 64-bit hosts
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed May 06 17:00:07 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator: Thomas Mueller
>Release: 7.2-STABLE
>Organization:
>Environment:
FreeBSD tom.ulm.sysgo.com 7.2-STABLE FreeBSD 7.2-STABLE #16: Mon May 4 15:12:43 CEST 2009 toor at tom.ulm.sysgo.com:/usr/obj/usr/src/sys/TOM amd64
>Description:
I've encountered two socket related problems with the Linux emulation:
1. A Linux application passing the MSG_NOSIGNAL flag in calls to
recv() or recvfrom() will still receive a SIGPIPE if the condition
for sending the signal is met.
2. An attempt to set socket timeouts with a call to setsocktopt() using the
SO_RECVTIMEO or SO_SNDTIMEO option will fail with [EINVAL] on amd64.
>How-To-Repeat:
>Fix:
1. Call linux_to_bsd_msg_flags() in linux_recv().
2. Translate l_timeval arg to native struct timeval in linux_setsockopt().
Patch attached.
Patch attached with submission follows:
Index: linux_socket.c
===================================================================
RCS file: /usr/home/tmu/repos/FreeBSD/repo/src/sys/compat/linux/linux_socket.c,v
retrieving revision 1.74.2.1
diff -u -p -r1.74.2.1 linux_socket.c
--- linux_socket.c 17 Sep 2008 08:05:39 -0000 1.74.2.1
+++ linux_socket.c 6 May 2009 16:51:16 -0000
@@ -871,7 +871,7 @@ linux_recv(struct thread *td, struct lin
bsd_args.s = args->s;
bsd_args.buf = (caddr_t)PTRIN(args->msg);
bsd_args.len = args->len;
- bsd_args.flags = args->flags;
+ bsd_args.flags = linux_to_bsd_msg_flags(args->flags);
bsd_args.from = NULL;
bsd_args.fromlenaddr = 0;
return (recvfrom(td, &bsd_args));
@@ -1104,6 +1104,17 @@ linux_setsockopt(struct thread *td, stru
bsd_args.valsize);
error = setsockopt(td, &bsd_args);
bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.val);
+ } else if (name == SO_RCVTIMEO || name == SO_SNDTIMEO) {
+ l_timeval lnx_tv;
+ struct timeval tv;
+
+ error = copyin(bsd_args.val, &lnx_tv, sizeof(lnx_tv));
+ if (!error) {
+ tv.tv_sec = lnx_tv.tv_sec;
+ tv.tv_usec = lnx_tv.tv_usec;
+ error = kern_setsockopt(td, bsd_args.s, bsd_args.level,
+ bsd_args.name, &tv, UIO_SYSSPACE, sizeof(tv));
+ }
} else
error = setsockopt(td, &bsd_args);
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list