Re: Fw: Local Denial-of-Service attack against Linux

From: Alexey Kuznetosv (kuznet@ms2.inr.ac.ru)
Date: Sun Mar 26 2000 - 10:41:58 EST


Hello!

The patch for 2.3 is appended. I apologize, I compiled it,
but did not test, I will not have a machine to boot for several days.

The idea is clear: sock_wmalloc() is wrong function, it cannot be
used in the places, where we have choice: to sleep or not to sleep.
Luckily, there are only two such places: sock_alloc_send_skb()
and its analogue in tcp_sendmsg().

Alexey

Index: net/core/sock.c
===================================================================
RCS file: /vger/u4/cvs/linux/net/core/sock.c,v
retrieving revision 1.91
diff -u -r1.91 sock.c
--- net/core/sock.c 2000/03/25 01:55:03 1.91
+++ net/core/sock.c 2000/03/26 15:04:31
@@ -786,18 +786,22 @@
                 if (sk->shutdown&SEND_SHUTDOWN)
                         goto failure;

- if (fallback) {
- /* The buffer get won't block, or use the atomic queue.
- * It does produce annoying no free page messages still.
- */
- skb = sock_wmalloc(sk, size, 0, GFP_BUFFER);
+ if (atomic_read(&sk->wmem_alloc) < sk->sndbuf) {
+ if (fallback) {
+ /* The buffer get won't block, or use the atomic queue.
+ * It does produce annoying no free page messages still.
+ */
+ skb = alloc_skb(size, GFP_BUFFER);
+ if (skb)
+ break;
+ try_size = fallback;
+ }
+ skb = alloc_skb(try_size, sk->allocation);
                         if (skb)
                                 break;
- try_size = fallback;
+ err = -ENOBUFS;
+ goto failure;
                 }
- skb = sock_wmalloc(sk, try_size, 0, sk->allocation);
- if (skb)
- break;

                 /*
                  * This means we have too many buffers for this socket already.
@@ -813,6 +817,7 @@
                 timeo = sock_wait_for_wmem(sk, timeo);
         }

+ skb_set_owner_w(skb, sk);
         return skb;

 interrupted:
Index: net/ipv4/tcp.c
===================================================================
RCS file: /vger/u4/cvs/linux/net/ipv4/tcp.c,v
retrieving revision 1.166
diff -u -r1.166 tcp.c
--- net/ipv4/tcp.c 2000/03/25 01:55:11 1.166
+++ net/ipv4/tcp.c 2000/03/26 15:04:31
@@ -951,10 +951,14 @@
                                 tmp += copy;
                                 queue_it = 0;
                         }
- skb = sock_wmalloc(sk, tmp, 0, GFP_KERNEL);

- /* If we didn't get any memory, we need to sleep. */
- if (skb == NULL) {
+ if (tcp_memory_free(sk)) {
+ skb = alloc_skb(tmp, GFP_KERNEL);
+ if (skb == NULL)
+ goto do_oom;
+ skb_set_owner_w(skb, sk);
+ } else {
+ /* If we didn't get any memory, we need to sleep. */
                                 set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
                                 set_bit(SOCK_NOSPACE, &sk->socket->flags);

@@ -1028,6 +1032,9 @@
                         send_sig(SIGPIPE, current, 0);
                 err = -EPIPE;
         }
+ goto out;
+do_oom:
+ err = copied ? : -ENOBUFS;
         goto out;
 do_interrupted:
         if(copied)
Index: net/unix/af_unix.c
===================================================================
RCS file: /vger/u4/cvs/linux/net/unix/af_unix.c,v
retrieving revision 1.91
diff -u -r1.91 af_unix.c
--- net/unix/af_unix.c 2000/03/25 01:55:34 1.91
+++ net/unix/af_unix.c 2000/03/26 15:04:32
@@ -1087,6 +1087,10 @@
                         goto out;
         }

+ err = -EMSGSIZE;
+ if (len > sk->sndbuf)
+ goto out;
+
         if (sock->passcred && !sk->protinfo.af_unix.addr &&
             (err = unix_autobind(sock)) != 0)
                 goto out;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Mar 31 2000 - 21:00:17 EST