2004-06-05 20:43:37

by Olaf Hering

[permalink] [raw]
Subject: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing


packet_recvmsg() gets the flags from the compat_sys_socketcall(), but it
does not check for the active MSG_CMSG_COMPAT bit. As a result, it
returns -EINVAL and makes the user rather unhappy


diff -purN linux-2.6.7-rc2-bk5.orig/net/packet/af_packet.c linux-2.6.7-rc2-bk5/net/packet/af_packet.c
--- linux-2.6.7-rc2-bk5.orig/net/packet/af_packet.c 2004-06-05 09:34:48.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/packet/af_packet.c 2004-06-05 22:32:16.000000000 +0200
@@ -1037,7 +1037,7 @@ static int packet_recvmsg(struct kiocb *
int copied, err;

err = -EINVAL;
- if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
+ if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
goto out;

#if 0
--
USB is for mice, FireWire is for men!

sUse lINUX ag, nÜRNBERG


2004-06-05 21:04:22

by David Miller

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

On Sat, 5 Jun 2004 22:43:34 +0200
Olaf Hering <[email protected]> wrote:

> packet_recvmsg() gets the flags from the compat_sys_socketcall(), but it
> does not check for the active MSG_CMSG_COMPAT bit. As a result, it
> returns -EINVAL and makes the user rather unhappy

Not just packet_recvmsg() (frankly, I'm stumped how tcpdump is working
on my sparc64 boxes due to this bug!), every other sendmsg/recvmsg
implementation has a test like this verifying the msg_flags for bogons.

Let's ask a better question, why do we need to pass this thing down
into the implementations anyways?

I can't see a reason, can anyone else? If there is no reason, the
right fix is simply to mask it out at the top level, for both
sendmsg and recvmsg.

2004-06-05 21:08:12

by David Miller

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing


[ Replying to myself :-) ]

On Sat, 5 Jun 2004 14:01:53 -0700
"David S. Miller" <[email protected]> wrote:

> Let's ask a better question, why do we need to pass this thing down
> into the implementations anyways?

It's for net/core/scm.c handling, sigh.

This means also that Olaf's patch is broken, when CONFIG_COMPAT is not
set, MSG_CMSG_COMPAT is zero, thus ~MSG_CMSG_COMPAT is the unexpected
value all 1's thus breaking the tests for unexpected flags completely.

Any better ideas?

2004-06-05 21:14:17

by Olaf Hering

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

On Sat, Jun 05, Olaf Hering wrote:

>
> packet_recvmsg() gets the flags from the compat_sys_socketcall(), but it
> does not check for the active MSG_CMSG_COMPAT bit. As a result, it
> returns -EINVAL and makes the user rather unhappy

possible related bugs are in:

ipx_sendmsg
pfkey_recvmsg
x25_sendmsg
ax25_sendmsg
irda_sendmsg
irda_sendmsg_dgram
irda_sendmsg_ultra
rose_sendmsg
atalk_sendmsg
dn_recvmsg
dn_sendmsg
econet_sendmsg
wanpipe_sendmsg
nr_sendmsg


--
USB is for mice, FireWire is for men!

sUse lINUX ag, nÜRNBERG

2004-06-05 21:17:14

by Olaf Hering

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

On Sat, Jun 05, David S. Miller wrote:

> I can't see a reason, can anyone else? If there is no reason, the
> right fix is simply to mask it out at the top level, for both
> sendmsg and recvmsg.

I did it first this way, but the result was a long delay until the dhcp
server replied, the patch sent earlier leads to a fast reply.

err = sock_recvmsg(sock, &msg_sys, total_len, flags & ~MSG_CMSG_COMPAT);


--
USB is for mice, FireWire is for men!

sUse lINUX ag, nÜRNBERG

2004-06-05 21:23:34

by Andreas Schwab

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

"David S. Miller" <[email protected]> writes:

> This means also that Olaf's patch is broken, when CONFIG_COMPAT is not
> set, MSG_CMSG_COMPAT is zero, thus ~MSG_CMSG_COMPAT is the unexpected
> value all 1's thus breaking the tests for unexpected flags completely.

??? Where do you get ~MSG_CMSG_COMPAT from?

Andreas.

--
Andreas Schwab, SuSE Labs, [email protected]
SuSE Linux AG, Maxfeldstra?e 5, 90409 N?rnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."

2004-06-05 21:39:17

by David Miller

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

On Sat, 05 Jun 2004 23:21:53 +0200
Andreas Schwab <[email protected]> wrote:

> "David S. Miller" <[email protected]> writes:
>
> > This means also that Olaf's patch is broken, when CONFIG_COMPAT is not
> > set, MSG_CMSG_COMPAT is zero, thus ~MSG_CMSG_COMPAT is the unexpected
> > value all 1's thus breaking the tests for unexpected flags completely.
>
> ??? Where do you get ~MSG_CMSG_COMPAT from?

Olaf's patch, it said:

- if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
+ if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))

2004-06-05 21:39:41

by David Miller

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

On Sat, 5 Jun 2004 23:17:01 +0200
Olaf Hering <[email protected]> wrote:

> On Sat, Jun 05, David S. Miller wrote:
>
> > I can't see a reason, can anyone else? If there is no reason, the
> > right fix is simply to mask it out at the top level, for both
> > sendmsg and recvmsg.
>
> I did it first this way, but the result was a long delay until the dhcp
> server replied, the patch sent earlier leads to a fast reply.
>
> err = sock_recvmsg(sock, &msg_sys, total_len, flags & ~MSG_CMSG_COMPAT);

See my other email, net/core/scm.c needs this bit set all the
way down into the implementations.

2004-06-05 21:47:26

by Andreas Schwab

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

"David S. Miller" <[email protected]> writes:

> On Sat, 05 Jun 2004 23:21:53 +0200
> Andreas Schwab <[email protected]> wrote:
>
>> "David S. Miller" <[email protected]> writes:
>>
>> > This means also that Olaf's patch is broken, when CONFIG_COMPAT is not
>> > set, MSG_CMSG_COMPAT is zero, thus ~MSG_CMSG_COMPAT is the unexpected
>> > value all 1's thus breaking the tests for unexpected flags completely.
>>
>> ??? Where do you get ~MSG_CMSG_COMPAT from?
>
> Olaf's patch, it said:
>
> - if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
> + if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))

Yes, and where is the problem?

Andreas.

--
Andreas Schwab, SuSE Labs, [email protected]
SuSE Linux AG, Maxfeldstra?e 5, 90409 N?rnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."

2004-06-05 21:56:27

by David Miller

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

On Sat, 05 Jun 2004 23:47:22 +0200
Andreas Schwab <[email protected]> wrote:

> > Olaf's patch, it said:
> >
> > - if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
> > + if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
>
> Yes, and where is the problem?

If MSG_CMSG_COMPAT is "ZERO", which it will be if CONFIG_COMPAT is
not set, then "~0" is all bits, therefore if any bit (even the ones
we want to accept) is set we will return failure. The test ends
up amounting to:

if (flags & ~0)

which is true if any bit is set, that's not what we want.

Anyways, I'm going to fix the bug like so:

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2004/06/05 14:52:04-07:00 [email protected]
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/wanrouter/af_wanpipe.c
# 2004/06/05 14:51:43-07:00 [email protected] +1 -1
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/netrom/af_netrom.c
# 2004/06/05 14:51:43-07:00 [email protected] +1 -1
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/econet/af_econet.c
# 2004/06/05 14:51:43-07:00 [email protected] +1 -1
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/decnet/af_decnet.c
# 2004/06/05 14:51:43-07:00 [email protected] +2 -1
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/x25/af_x25.c
# 2004/06/05 14:51:42-07:00 [email protected] +2 -1
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/rose/af_rose.c
# 2004/06/05 14:51:42-07:00 [email protected] +1 -1
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/packet/af_packet.c
# 2004/06/05 14:51:42-07:00 [email protected] +1 -1
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/key/af_key.c
# 2004/06/05 14:51:42-07:00 [email protected] +1 -1
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/irda/af_irda.c
# 2004/06/05 14:51:42-07:00 [email protected] +3 -3
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/ipx/af_ipx.c
# 2004/06/05 14:51:42-07:00 [email protected] +1 -1
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/ax25/af_ax25.c
# 2004/06/05 14:51:42-07:00 [email protected] +1 -2
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# net/appletalk/ddp.c
# 2004/06/05 14:51:42-07:00 [email protected] +1 -1
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
# include/linux/socket.h
# 2004/06/05 14:51:42-07:00 [email protected] +2 -0
# [NET]: Fix bogus msg_flags checks, need to mask out MSG_CMSG_COMPAT.
#
diff -Nru a/include/linux/socket.h b/include/linux/socket.h
--- a/include/linux/socket.h 2004-06-05 14:53:34 -07:00
+++ b/include/linux/socket.h 2004-06-05 14:53:34 -07:00
@@ -241,8 +241,10 @@

#if defined(CONFIG_COMPAT)
#define MSG_CMSG_COMPAT 0x80000000 /* This message needs 32 bit fixups */
+#define MSG_FLAGS_USER(X) ((X) & ~MSG_CMSG_COMPAT)
#else
#define MSG_CMSG_COMPAT 0 /* We never have 32 bit fixups */
+#define MSG_FLAGS_USER(X) (X)
#endif


diff -Nru a/net/appletalk/ddp.c b/net/appletalk/ddp.c
--- a/net/appletalk/ddp.c 2004-06-05 14:53:35 -07:00
+++ b/net/appletalk/ddp.c 2004-06-05 14:53:35 -07:00
@@ -1567,7 +1567,7 @@
struct atalk_route *rt;
int err;

- if (flags & ~MSG_DONTWAIT)
+ if (MSG_FLAGS_USER(flags) & ~MSG_DONTWAIT)
return -EINVAL;

if (len > DDP_MAXSZ)
diff -Nru a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
--- a/net/ax25/af_ax25.c 2004-06-05 14:53:34 -07:00
+++ b/net/ax25/af_ax25.c 2004-06-05 14:53:34 -07:00
@@ -1413,9 +1413,8 @@
size_t size;
int lv, err, addr_len = msg->msg_namelen;

- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR)) {
+ if (MSG_FLAGS_USER(msg->msg_flags) & ~(MSG_DONTWAIT|MSG_EOR))
return -EINVAL;
- }

lock_sock(sk);
ax25 = ax25_sk(sk);
diff -Nru a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
--- a/net/decnet/af_decnet.c 2004-06-05 14:53:34 -07:00
+++ b/net/decnet/af_decnet.c 2004-06-05 14:53:34 -07:00
@@ -1905,7 +1905,8 @@
unsigned char fctype;
long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);

- if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE))
+ if (MSG_FLAGS_USER(flags) &
+ ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE))
return -EOPNOTSUPP;

if (addr_len && (addr_len != sizeof(struct sockaddr_dn)))
diff -Nru a/net/econet/af_econet.c b/net/econet/af_econet.c
--- a/net/econet/af_econet.c 2004-06-05 14:53:34 -07:00
+++ b/net/econet/af_econet.c 2004-06-05 14:53:34 -07:00
@@ -274,7 +274,7 @@
* Check the flags.
*/

- if (msg->msg_flags&~MSG_DONTWAIT)
+ if (MSG_FLAGS_USER(msg->msg_flags) & ~MSG_DONTWAIT)
return(-EINVAL);

/*
diff -Nru a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
--- a/net/ipx/af_ipx.c 2004-06-05 14:53:34 -07:00
+++ b/net/ipx/af_ipx.c 2004-06-05 14:53:34 -07:00
@@ -1695,7 +1695,7 @@
/* Socket gets bound below anyway */
/* if (sk->sk_zapped)
return -EIO; */ /* Socket not bound */
- if (flags & ~MSG_DONTWAIT)
+ if (MSG_FLAGS_USER(flags) & ~MSG_DONTWAIT)
goto out;

/* Max possible packet size limited by 16 bit pktsize in header */
diff -Nru a/net/irda/af_irda.c b/net/irda/af_irda.c
--- a/net/irda/af_irda.c 2004-06-05 14:53:34 -07:00
+++ b/net/irda/af_irda.c 2004-06-05 14:53:34 -07:00
@@ -1269,7 +1269,7 @@
IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);

/* Note : socket.c set MSG_EOR on SEQPACKET sockets */
- if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR))
+ if (MSG_FLAGS_USER(msg->msg_flags) & ~(MSG_DONTWAIT | MSG_EOR))
return -EINVAL;

if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -1521,7 +1521,7 @@

IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);

- if (msg->msg_flags & ~MSG_DONTWAIT)
+ if (MSG_FLAGS_USER(msg->msg_flags) & ~MSG_DONTWAIT)
return -EINVAL;

if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -1593,7 +1593,7 @@

IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);

- if (msg->msg_flags & ~MSG_DONTWAIT)
+ if (MSG_FLAGS_USER(msg->msg_flags) & ~MSG_DONTWAIT)
return -EINVAL;

if (sk->sk_shutdown & SEND_SHUTDOWN) {
diff -Nru a/net/key/af_key.c b/net/key/af_key.c
--- a/net/key/af_key.c 2004-06-05 14:53:34 -07:00
+++ b/net/key/af_key.c 2004-06-05 14:53:34 -07:00
@@ -2726,7 +2726,7 @@
int copied, err;

err = -EINVAL;
- if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
+ if (MSG_FLAGS_USER(flags) & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
goto out;

msg->msg_namelen = 0;
diff -Nru a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
--- a/net/netrom/af_netrom.c 2004-06-05 14:53:34 -07:00
+++ b/net/netrom/af_netrom.c 2004-06-05 14:53:34 -07:00
@@ -1021,7 +1021,7 @@
unsigned char *asmptr;
int size;

- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR))
+ if (MSG_FLAGS_USER(msg->msg_flags) & ~(MSG_DONTWAIT|MSG_EOR))
return -EINVAL;

lock_sock(sk);
diff -Nru a/net/packet/af_packet.c b/net/packet/af_packet.c
--- a/net/packet/af_packet.c 2004-06-05 14:53:34 -07:00
+++ b/net/packet/af_packet.c 2004-06-05 14:53:34 -07:00
@@ -1037,7 +1037,7 @@
int copied, err;

err = -EINVAL;
- if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
+ if (MSG_FLAGS_USER(flags) & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
goto out;

#if 0
diff -Nru a/net/rose/af_rose.c b/net/rose/af_rose.c
--- a/net/rose/af_rose.c 2004-06-05 14:53:34 -07:00
+++ b/net/rose/af_rose.c 2004-06-05 14:53:34 -07:00
@@ -1021,7 +1021,7 @@
unsigned char *asmptr;
int n, size, qbit = 0;

- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR))
+ if (MSG_FLAGS_USER(msg->msg_flags) & ~(MSG_DONTWAIT|MSG_EOR))
return -EINVAL;

if (sk->sk_zapped)
diff -Nru a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
--- a/net/wanrouter/af_wanpipe.c 2004-06-05 14:53:34 -07:00
+++ b/net/wanrouter/af_wanpipe.c 2004-06-05 14:53:35 -07:00
@@ -552,7 +552,7 @@
if (sk->sk_state != WANSOCK_CONNECTED)
return -ENOTCONN;

- if (msg->msg_flags&~MSG_DONTWAIT)
+ if (MSG_FLAGS_USER(msg->msg_flags) & ~MSG_DONTWAIT)
return(-EINVAL);

/* it was <=, now one can send
diff -Nru a/net/x25/af_x25.c b/net/x25/af_x25.c
--- a/net/x25/af_x25.c 2004-06-05 14:53:34 -07:00
+++ b/net/x25/af_x25.c 2004-06-05 14:53:34 -07:00
@@ -922,7 +922,8 @@
size_t size;
int qbit = 0, rc = -EINVAL;

- if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_OOB | MSG_EOR))
+ if (MSG_FLAGS_USER(msg->msg_flags) &
+ ~(MSG_DONTWAIT | MSG_OOB | MSG_EOR))
goto out;

/* we currently don't support segmented records at the user interface */

2004-06-05 22:06:06

by Andreas Schwab

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

"David S. Miller" <[email protected]> writes:

> On Sat, 05 Jun 2004 23:47:22 +0200
> Andreas Schwab <[email protected]> wrote:
>
>> > Olaf's patch, it said:
>> >
>> > - if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
>> > + if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
>>
>> Yes, and where is the problem?
>
> If MSG_CMSG_COMPAT is "ZERO", which it will be if CONFIG_COMPAT is
> not set, then "~0" is all bits, therefore if any bit (even the ones
> we want to accept) is set we will return failure. The test ends
> up amounting to:
>
> if (flags & ~0)
>
> which is true if any bit is set, that's not what we want.

Can you say DeMorgan?

> diff -Nru a/include/linux/socket.h b/include/linux/socket.h
> --- a/include/linux/socket.h 2004-06-05 14:53:34 -07:00
> +++ b/include/linux/socket.h 2004-06-05 14:53:34 -07:00
> @@ -241,8 +241,10 @@
>
> #if defined(CONFIG_COMPAT)
> #define MSG_CMSG_COMPAT 0x80000000 /* This message needs 32 bit fixups */
> +#define MSG_FLAGS_USER(X) ((X) & ~MSG_CMSG_COMPAT)
> #else
> #define MSG_CMSG_COMPAT 0 /* We never have 32 bit fixups */
> +#define MSG_FLAGS_USER(X) (X)
> #endif
>
>
> diff -Nru a/net/appletalk/ddp.c b/net/appletalk/ddp.c
> --- a/net/appletalk/ddp.c 2004-06-05 14:53:35 -07:00
> +++ b/net/appletalk/ddp.c 2004-06-05 14:53:35 -07:00
> @@ -1567,7 +1567,7 @@
> struct atalk_route *rt;
> int err;
>
> - if (flags & ~MSG_DONTWAIT)
> + if (MSG_FLAGS_USER(flags) & ~MSG_DONTWAIT)
> return -EINVAL;
>
> if (len > DDP_MAXSZ)

This is exactly equivalent to Olaf's version.

Andreas.

--
Andreas Schwab, SuSE Labs, [email protected]
SuSE Linux AG, Maxfeldstra?e 5, 90409 N?rnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."

2004-06-05 22:32:22

by David Miller

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

On Sun, 06 Jun 2004 00:05:58 +0200
Andreas Schwab <[email protected]> wrote:

> Can you say DeMorgan?

Sorry, thought I had put enough caffeine in my system.
Aparently not :)

2004-06-05 22:37:56

by Olaf Hering

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

On Sat, Jun 05, David S. Miller wrote:

> On Sun, 06 Jun 2004 00:05:58 +0200
> Andreas Schwab <[email protected]> wrote:
>
> > Can you say DeMorgan?
>
> Sorry, thought I had put enough caffeine in my system.
> Aparently not :)

Lets agree on this version.


diff -p -purN linux-2.6.7-rc2-bk5.orig/net/appletalk/ddp.c linux-2.6.7-rc2-bk5/net/appletalk/ddp.c
--- linux-2.6.7-rc2-bk5.orig/net/appletalk/ddp.c 2004-06-05 09:34:47.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/appletalk/ddp.c 2004-06-06 00:21:48.000000000 +0200
@@ -1567,7 +1567,7 @@ static int atalk_sendmsg(struct kiocb *i
struct atalk_route *rt;
int err;

- if (flags & ~MSG_DONTWAIT)
+ if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
return -EINVAL;

if (len > DDP_MAXSZ)
diff -p -purN linux-2.6.7-rc2-bk5.orig/net/ax25/af_ax25.c linux-2.6.7-rc2-bk5/net/ax25/af_ax25.c
--- linux-2.6.7-rc2-bk5.orig/net/ax25/af_ax25.c 2004-06-05 09:34:47.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/ax25/af_ax25.c 2004-06-06 00:23:18.000000000 +0200
@@ -1413,9 +1413,8 @@ static int ax25_sendmsg(struct kiocb *io
size_t size;
int lv, err, addr_len = msg->msg_namelen;

- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR)) {
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
return -EINVAL;
- }

lock_sock(sk);
ax25 = ax25_sk(sk);
diff -p -purN linux-2.6.7-rc2-bk5.orig/net/decnet/af_decnet.c linux-2.6.7-rc2-bk5/net/decnet/af_decnet.c
--- linux-2.6.7-rc2-bk5.orig/net/decnet/af_decnet.c 2004-06-05 09:34:47.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/decnet/af_decnet.c 2004-06-06 00:23:01.000000000 +0200
@@ -1905,7 +1905,7 @@ static int dn_sendmsg(struct kiocb *iocb
unsigned char fctype;
long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);

- if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE))
+ if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE|MSG_CMSG_COMPAT))
return -EOPNOTSUPP;

if (addr_len && (addr_len != sizeof(struct sockaddr_dn)))
diff -p -purN linux-2.6.7-rc2-bk5.orig/net/econet/af_econet.c linux-2.6.7-rc2-bk5/net/econet/af_econet.c
--- linux-2.6.7-rc2-bk5.orig/net/econet/af_econet.c 2004-06-05 09:34:47.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/econet/af_econet.c 2004-06-06 00:24:19.000000000 +0200
@@ -274,8 +274,8 @@ static int econet_sendmsg(struct kiocb *
* Check the flags.
*/

- if (msg->msg_flags&~MSG_DONTWAIT)
- return(-EINVAL);
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
+ return -EINVAL;

/*
* Get and verify the address.
diff -p -purN linux-2.6.7-rc2-bk5.orig/net/ipx/af_ipx.c linux-2.6.7-rc2-bk5/net/ipx/af_ipx.c
--- linux-2.6.7-rc2-bk5.orig/net/ipx/af_ipx.c 2004-06-05 09:34:48.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/ipx/af_ipx.c 2004-06-06 00:24:54.000000000 +0200
@@ -1695,7 +1695,7 @@ static int ipx_sendmsg(struct kiocb *ioc
/* Socket gets bound below anyway */
/* if (sk->sk_zapped)
return -EIO; */ /* Socket not bound */
- if (flags & ~MSG_DONTWAIT)
+ if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
goto out;

/* Max possible packet size limited by 16 bit pktsize in header */
diff -p -purN linux-2.6.7-rc2-bk5.orig/net/irda/af_irda.c linux-2.6.7-rc2-bk5/net/irda/af_irda.c
--- linux-2.6.7-rc2-bk5.orig/net/irda/af_irda.c 2004-06-05 09:34:48.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/irda/af_irda.c 2004-06-06 00:27:55.000000000 +0200
@@ -1269,7 +1269,7 @@ static int irda_sendmsg(struct kiocb *io
IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);

/* Note : socket.c set MSG_EOR on SEQPACKET sockets */
- if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR))
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
return -EINVAL;

if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -1521,7 +1521,7 @@ static int irda_sendmsg_dgram(struct kio

IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);

- if (msg->msg_flags & ~MSG_DONTWAIT)
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
return -EINVAL;

if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -1593,7 +1593,7 @@ static int irda_sendmsg_ultra(struct kio

IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);

- if (msg->msg_flags & ~MSG_DONTWAIT)
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
return -EINVAL;

if (sk->sk_shutdown & SEND_SHUTDOWN) {
diff -p -purN linux-2.6.7-rc2-bk5.orig/net/key/af_key.c linux-2.6.7-rc2-bk5/net/key/af_key.c
--- linux-2.6.7-rc2-bk5.orig/net/key/af_key.c 2004-06-05 09:31:46.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/key/af_key.c 2004-06-06 00:28:49.000000000 +0200
@@ -2726,7 +2726,7 @@ static int pfkey_recvmsg(struct kiocb *k
int copied, err;

err = -EINVAL;
- if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
+ if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
goto out;

msg->msg_namelen = 0;
diff -p -purN linux-2.6.7-rc2-bk5.orig/net/netrom/af_netrom.c linux-2.6.7-rc2-bk5/net/netrom/af_netrom.c
--- linux-2.6.7-rc2-bk5.orig/net/netrom/af_netrom.c 2004-06-05 09:34:48.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/netrom/af_netrom.c 2004-06-06 00:29:00.000000000 +0200
@@ -1021,7 +1021,7 @@ static int nr_sendmsg(struct kiocb *iocb
unsigned char *asmptr;
int size;

- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR))
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
return -EINVAL;

lock_sock(sk);
diff -p -purN linux-2.6.7-rc2-bk5.orig/net/packet/af_packet.c linux-2.6.7-rc2-bk5/net/packet/af_packet.c
--- linux-2.6.7-rc2-bk5.orig/net/packet/af_packet.c 2004-06-05 09:34:48.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/packet/af_packet.c 2004-06-05 22:32:16.000000000 +0200
@@ -1037,7 +1037,7 @@ static int packet_recvmsg(struct kiocb *
int copied, err;

err = -EINVAL;
- if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
+ if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
goto out;

#if 0
diff -p -purN linux-2.6.7-rc2-bk5.orig/net/rose/af_rose.c linux-2.6.7-rc2-bk5/net/rose/af_rose.c
--- linux-2.6.7-rc2-bk5.orig/net/rose/af_rose.c 2004-06-05 09:34:48.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/rose/af_rose.c 2004-06-06 00:29:29.000000000 +0200
@@ -1021,7 +1021,7 @@ static int rose_sendmsg(struct kiocb *io
unsigned char *asmptr;
int n, size, qbit = 0;

- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR))
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
return -EINVAL;

if (sk->sk_zapped)
diff -p -purN linux-2.6.7-rc2-bk5.orig/net/wanrouter/af_wanpipe.c linux-2.6.7-rc2-bk5/net/wanrouter/af_wanpipe.c
--- linux-2.6.7-rc2-bk5.orig/net/wanrouter/af_wanpipe.c 2004-06-05 09:34:48.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/wanrouter/af_wanpipe.c 2004-06-06 00:29:51.000000000 +0200
@@ -552,7 +552,7 @@ static int wanpipe_sendmsg(struct kiocb
if (sk->sk_state != WANSOCK_CONNECTED)
return -ENOTCONN;

- if (msg->msg_flags&~MSG_DONTWAIT)
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
return(-EINVAL);

/* it was <=, now one can send
diff -p -purN linux-2.6.7-rc2-bk5.orig/net/x25/af_x25.c linux-2.6.7-rc2-bk5/net/x25/af_x25.c
--- linux-2.6.7-rc2-bk5.orig/net/x25/af_x25.c 2004-06-05 09:34:48.000000000 +0200
+++ linux-2.6.7-rc2-bk5/net/x25/af_x25.c 2004-06-06 00:30:20.000000000 +0200
@@ -922,7 +922,7 @@ static int x25_sendmsg(struct kiocb *ioc
size_t size;
int qbit = 0, rc = -EINVAL;

- if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_OOB | MSG_EOR))
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR|MSG_CMSG_COMPAT))
goto out;

/* we currently don't support segmented records at the user interface */

--
USB is for mice, FireWire is for men!

sUse lINUX ag, nÜRNBERG

2004-06-05 22:57:35

by David Miller

[permalink] [raw]
Subject: Re: [PATCH] compat bug in sys_recvmsg, MSG_CMSG_COMPAT check missing

On Sun, 6 Jun 2004 00:37:23 +0200
Olaf Hering <[email protected]> wrote:

> > Sorry, thought I had put enough caffeine in my system.
> > Aparently not :)
>
> Lets agree on this version.

Yep, patch applied.

Thanks.