Bug 134276 - [linux][patch] MSG_NOSIGNAL not translated for recv(), socket timeout incorrect for 64-bit hosts
Summary: [linux][patch] MSG_NOSIGNAL not translated for recv(), socket timeout incorre...
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 7.2-STABLE
Hardware: Any Any
: Normal Affects Only Me
Assignee: Dmitry Chagin
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-05-06 18:00 UTC by Thomas Mueller
Modified: 2009-05-29 15:39 UTC (History)
0 users

See Also:


Attachments
file.diff (1.23 KB, patch)
2009-05-06 18:00 UTC, Thomas Mueller
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Mueller 2009-05-06 18:00:07 UTC
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.

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:
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2009-05-08 04:45:32 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-emulation

Over to maintainer(s).
Comment 2 Dmitry Chagin freebsd_committer freebsd_triage 2009-05-08 21:10:03 UTC
On Wed, May 06, 2009 at 04:57:50PM +0000, Thomas Mueller wrote:
> 
> >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@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.
> 


What the Linux application you have mentioned?
I should know it to test patches. Thank you.

-- 
Have fun!
chd
Comment 3 Thomas Mueller 2009-05-09 07:30:53 UTC
On Sat, 9 May 2009 00:10:03 +0400, Chagin Dmitry wrote:
> On Wed, May 06, 2009 at 04:57:50PM +0000, Thomas Mueller wrote:
> > 
> > >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@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.
> > 
> 
> What the Linux application you have mentioned?
> I should know it to test patches. Thank you.

Sorry for not mentioning it in the PR. The applications are part of the
LM-X License Manager package by X-Formation (http://www.x-formation.com/).
It looks like they offer a trial download but require registration.

When back in the office (next weeek), I could revert my local changes
and provide you with an output of linux_kdump if that helps. I would
also test patches.


-- 
Thomas Mueller
Comment 4 dfilter service freebsd_committer freebsd_triage 2009-05-11 14:42:55 UTC
Author: dchagin
Date: Mon May 11 13:42:40 2009
New Revision: 191988
URL: http://svn.freebsd.org/changeset/base/191988

Log:
  Add forgotten linux to bsd flags argument mapping into the linux_recv().
  
  PR:		kern/134276
  Submitted by:	Thomas Mueller <tmueller sysgo com>
  Approved by:	kib (mentor)
  MFC after:	2 weeks

Modified:
  head/sys/compat/linux/linux_socket.c

Modified: head/sys/compat/linux/linux_socket.c
==============================================================================
--- head/sys/compat/linux/linux_socket.c	Mon May 11 07:57:29 2009	(r191987)
+++ head/sys/compat/linux/linux_socket.c	Mon May 11 13:42:40 2009	(r191988)
@@ -924,7 +924,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));
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 5 dfilter service freebsd_committer freebsd_triage 2009-05-11 14:50:53 UTC
Author: dchagin
Date: Mon May 11 13:50:42 2009
New Revision: 191989
URL: http://svn.freebsd.org/changeset/base/191989

Log:
  Translate l_timeval arg to native struct timeval in
  linux_setsockopt()/linux_getsockopt() for SO_RCVTIMEO,
  SO_SNDTIMEO opts as l_timeval has MD members.
  
  Remove bogus __packed attribute from l_timeval struct on __amd64__.
  
  PR:		kern/134276
  Submitted by:	Thomas Mueller <tmueller sysgo com>
  Approved by:	kib (mentor)
  MFC after:	2 weeks

Modified:
  head/sys/amd64/linux32/linux.h
  head/sys/compat/linux/linux_socket.c

Modified: head/sys/amd64/linux32/linux.h
==============================================================================
--- head/sys/amd64/linux32/linux.h	Mon May 11 13:42:40 2009	(r191988)
+++ head/sys/amd64/linux32/linux.h	Mon May 11 13:50:42 2009	(r191989)
@@ -96,7 +96,7 @@ typedef struct {
 typedef struct {
 	l_time_t	tv_sec;
 	l_suseconds_t	tv_usec;
-} __packed l_timeval;
+} l_timeval;
 
 #define	l_fd_set	fd_set
 

Modified: head/sys/compat/linux/linux_socket.c
==============================================================================
--- head/sys/compat/linux/linux_socket.c	Mon May 11 13:42:40 2009	(r191988)
+++ head/sys/compat/linux/linux_socket.c	Mon May 11 13:50:42 2009	(r191989)
@@ -1278,6 +1278,8 @@ linux_setsockopt(struct thread *td, stru
 		caddr_t val;
 		int valsize;
 	} */ bsd_args;
+	l_timeval linux_tv;
+	struct timeval tv;
 	int error, name;
 
 	bsd_args.s = args->s;
@@ -1285,6 +1287,23 @@ linux_setsockopt(struct thread *td, stru
 	switch (bsd_args.level) {
 	case SOL_SOCKET:
 		name = linux_to_bsd_so_sockopt(args->optname);
+		switch (name) {
+		case SO_RCVTIMEO:
+			/* FALLTHROUGH */
+		case SO_SNDTIMEO:
+			error = copyin(PTRIN(args->optval), &linux_tv,
+			    sizeof(linux_tv));
+			if (error)
+				return (error);
+			tv.tv_sec = linux_tv.tv_sec;
+			tv.tv_usec = linux_tv.tv_usec;
+			return (kern_setsockopt(td, args->s, bsd_args.level,
+			    name, &tv, UIO_SYSSPACE, sizeof(tv)));
+			/* NOTREACHED */
+			break;
+		default:
+			break;
+		}
 		break;
 	case IPPROTO_IP:
 		name = linux_to_bsd_ip_sockopt(args->optname);
@@ -1333,6 +1352,9 @@ linux_getsockopt(struct thread *td, stru
 		caddr_t val;
 		int *avalsize;
 	} */ bsd_args;
+	l_timeval linux_tv;
+	struct timeval tv;
+	socklen_t tv_len;
 	int error, name;
 
 	bsd_args.s = args->s;
@@ -1340,6 +1362,24 @@ linux_getsockopt(struct thread *td, stru
 	switch (bsd_args.level) {
 	case SOL_SOCKET:
 		name = linux_to_bsd_so_sockopt(args->optname);
+		switch (name) {
+		case SO_RCVTIMEO:
+			/* FALLTHROUGH */
+		case SO_SNDTIMEO:
+			tv_len = sizeof(tv);
+			error = kern_getsockopt(td, args->s, bsd_args.level,
+			    name, &tv, UIO_SYSSPACE, &tv_len);
+			if (error)
+				return (error);
+			linux_tv.tv_sec = tv.tv_sec;
+			linux_tv.tv_usec = tv.tv_usec;
+			return (copyout(&linux_tv, PTRIN(args->optval),
+			    sizeof(linux_tv)));
+			/* NOTREACHED */
+			break;
+		default:
+			break;
+		}
 		break;
 	case IPPROTO_IP:
 		name = linux_to_bsd_ip_sockopt(args->optname);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 6 Xin LI freebsd_committer freebsd_triage 2009-05-11 15:36:19 UTC
State Changed
From-To: open->patched

dchagin@ has committed a fix as revision 191988 so bump this 
to 'patched' state as MFC reminder. 


Comment 7 Xin LI freebsd_committer freebsd_triage 2009-05-11 15:36:19 UTC
Responsible Changed
From-To: freebsd-emulation->dchagin

Over to dchagin@.
Comment 8 dfilter service freebsd_committer freebsd_triage 2009-05-25 20:55:15 UTC
Author: dchagin
Date: Mon May 25 19:55:00 2009
New Revision: 192767
URL: http://svn.freebsd.org/changeset/base/192767

Log:
  Merge r191988 from HEAD to stable/7:
  Add forgotten linux to bsd flags argument mapping into the linux_recv().
  
  PR:		kern/134276
  Submitted by:	Thomas Mueller <tmueller sysgo com>
  Approved by:	kib (mentor)

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/compat/linux/linux_socket.c
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)

Modified: stable/7/sys/compat/linux/linux_socket.c
==============================================================================
--- stable/7/sys/compat/linux/linux_socket.c	Mon May 25 17:06:24 2009	(r192766)
+++ stable/7/sys/compat/linux/linux_socket.c	Mon May 25 19:55:00 2009	(r192767)
@@ -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));
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 9 dfilter service freebsd_committer freebsd_triage 2009-05-25 21:24:51 UTC
Author: dchagin
Date: Mon May 25 20:24:36 2009
New Revision: 192769
URL: http://svn.freebsd.org/changeset/base/192769

Log:
  Merge r191989 from HEAD to stable/7:
  
  Translate l_timeval arg to native struct timeval in
  linux_setsockopt()/linux_getsockopt() for SO_RCVTIMEO,
  SO_SNDTIMEO opts as l_timeval has MD members.
  
  Remove bogus __packed attribute from l_timeval struct on __amd64__.
  
  PR:		kern/134276
  Submitted by:	Thomas Mueller <tmueller sysgo com>
  Approved by:	kib (mentor)

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/amd64/linux32/linux.h
  stable/7/sys/compat/linux/linux_socket.c
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)

Modified: stable/7/sys/amd64/linux32/linux.h
==============================================================================
--- stable/7/sys/amd64/linux32/linux.h	Mon May 25 20:07:41 2009	(r192768)
+++ stable/7/sys/amd64/linux32/linux.h	Mon May 25 20:24:36 2009	(r192769)
@@ -94,7 +94,7 @@ typedef struct {
 typedef struct {
 	l_time_t	tv_sec;
 	l_suseconds_t	tv_usec;
-} __packed l_timeval;
+} l_timeval;
 
 #define	l_fd_set	fd_set
 

Modified: stable/7/sys/compat/linux/linux_socket.c
==============================================================================
--- stable/7/sys/compat/linux/linux_socket.c	Mon May 25 20:07:41 2009	(r192768)
+++ stable/7/sys/compat/linux/linux_socket.c	Mon May 25 20:24:36 2009	(r192769)
@@ -1073,6 +1073,8 @@ linux_setsockopt(struct thread *td, stru
 		caddr_t val;
 		int valsize;
 	} */ bsd_args;
+	l_timeval linux_tv;
+	struct timeval tv;
 	int error, name;
 
 	bsd_args.s = args->s;
@@ -1080,6 +1082,23 @@ linux_setsockopt(struct thread *td, stru
 	switch (bsd_args.level) {
 	case SOL_SOCKET:
 		name = linux_to_bsd_so_sockopt(args->optname);
+		switch (name) {
+		case SO_RCVTIMEO:
+			/* FALLTHROUGH */
+		case SO_SNDTIMEO:
+			error = copyin(PTRIN(args->optval), &linux_tv,
+			    sizeof(linux_tv));
+			if (error)
+				return (error);
+			tv.tv_sec = linux_tv.tv_sec;
+			tv.tv_usec = linux_tv.tv_usec;
+			return (kern_setsockopt(td, args->s, bsd_args.level,
+			    name, &tv, UIO_SYSSPACE, sizeof(tv)));
+			/* NOTREACHED */
+			break;
+		default:
+			break;
+		}
 		break;
 	case IPPROTO_IP:
 		name = linux_to_bsd_ip_sockopt(args->optname);
@@ -1128,6 +1147,9 @@ linux_getsockopt(struct thread *td, stru
 		caddr_t val;
 		int *avalsize;
 	} */ bsd_args;
+	l_timeval linux_tv;
+	struct timeval tv;
+	socklen_t tv_len;
 	int error, name;
 
 	bsd_args.s = args->s;
@@ -1135,6 +1157,24 @@ linux_getsockopt(struct thread *td, stru
 	switch (bsd_args.level) {
 	case SOL_SOCKET:
 		name = linux_to_bsd_so_sockopt(args->optname);
+		switch (name) {
+		case SO_RCVTIMEO:
+			/* FALLTHROUGH */
+		case SO_SNDTIMEO:
+			tv_len = sizeof(tv);
+			error = kern_getsockopt(td, args->s, bsd_args.level,
+			    name, &tv, UIO_SYSSPACE, &tv_len);
+			if (error)
+				return (error);
+			linux_tv.tv_sec = tv.tv_sec;
+			linux_tv.tv_usec = tv.tv_usec;
+			return (copyout(&linux_tv, PTRIN(args->optval),
+			    sizeof(linux_tv)));
+			/* NOTREACHED */
+			break;
+		default:
+			break;
+		}
 		break;
 	case IPPROTO_IP:
 		name = linux_to_bsd_ip_sockopt(args->optname);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 10 Dmitry Chagin freebsd_committer freebsd_triage 2009-05-29 15:37:11 UTC
State Changed
From-To: patched->closed

The submitter confirmed that the problem fixed.