Re: mbuf shortage situations (followup)

1999-09-17 Thread Matthew Dillon

I think that what needs to be done is to split the problem in two.  First,
allow the mbuf routines to return a failure even with M_WAIT.  If M_WAIT
is used, it simply means 'try harder, sleeping a bit if necessary'.  This 
requires ensuring that all the networking code deal with the failure
case - a time consuming but straightforward task.  If a failure occurs,
one simply drops the packet, not the connection or anything else drastic.
just the packet.

The second problem that needs to be addressed is resource exhaustion.
For example, allocating thousands of connections and socket-opting their
buffers as large as possible, or programs such as syslog accepting new
connections ad-infinitum.  This is a harder problem to fix properly,
but a lot of the various issues such as those with syslog can be dealt 
with in userland rather then the kernel.

-Matt



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: mbuf shortage situations (followup)

1999-09-17 Thread Matthew Dillon

:In 4.3, the code was able to deal with cluster allocation failing.  We
:have a somewhat different situation now, because many network
:interface devices have less-flexible DMA mechanisms which don't allow
:packet reception into non-contiguous buffers, so we need to have at
:least a certain number of clusters available for this purpose.
:
:-GAWollman
:
:--
:Garrett A. Wollman   | O Siem / We are all family / O Siem / We're all the same

This is an interrupt level mechanism.  The mbuf code is *already* allowed
to (and does) return NULL in this case so I don't think it applies to
the problem under discussion.

The case that is causing the panics is with the non-interrupt mbuf
allocation mechanism.  Specifically, the case where M_WAIT is used.

The second problem under discussion, which really ought to be separated
out from the mbuf panic problem, is the potential for a deadlock or 
denial of service attack when the system is attacked in a manner that
eats all available mbufs.

:[EMAIL PROTECTED]  | O Siem / The fires of freedom 
:Opinions not those of| Dance in the burning flame

-Matt
Matthew Dillon 
[EMAIL PROTECTED]



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: mbuf shortage situations (followup)

1999-09-17 Thread Brian F. Feldman

On Mon, 13 Sep 1999, Matthew Dillon wrote:

 The case that is causing the panics is with the non-interrupt mbuf
 allocation mechanism.  Specifically, the case where M_WAIT is used.
 
 The second problem under discussion, which really ought to be separated
 out from the mbuf panic problem, is the potential for a deadlock or 
 denial of service attack when the system is attacked in a manner that
 eats all available mbufs.
 

The traditional way to prevent resource-starvation DoSes from the user
populus has been to add administrative limits.  Using RLIMIT_SBSIZE does
this nicely.  Yes, this isn't actually fixing the panics, but it is
good preventative medicine.

   -Matt
   Matthew Dillon 
   [EMAIL PROTECTED]
 

-- 
 Brian Fundakowski Feldman   \  FreeBSD: The Power to Serve!  /
 [EMAIL PROTECTED]`--'



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: mbuf shortage situations (followup)

1999-09-17 Thread Matthew Dillon
:In 4.3, the code was able to deal with cluster allocation failing.  We
:have a somewhat different situation now, because many network
:interface devices have less-flexible DMA mechanisms which don't allow
:packet reception into non-contiguous buffers, so we need to have at
:least a certain number of clusters available for this purpose.
:
:-GAWollman
:
:--
:Garrett A. Wollman   | O Siem / We are all family / O Siem / We're all the same

This is an interrupt level mechanism.  The mbuf code is *already* allowed
to (and does) return NULL in this case so I don't think it applies to
the problem under discussion.

The case that is causing the panics is with the non-interrupt mbuf
allocation mechanism.  Specifically, the case where M_WAIT is used.

The second problem under discussion, which really ought to be separated
out from the mbuf panic problem, is the potential for a deadlock or 
denial of service attack when the system is attacked in a manner that
eats all available mbufs.

:woll...@lcs.mit.edu  | O Siem / The fires of freedom 
:Opinions not those of| Dance in the burning flame

-Matt
Matthew Dillon 
dil...@backplane.com



To Unsubscribe: send mail to majord...@freebsd.org
with unsubscribe freebsd-hackers in the body of the message



Re: mbuf shortage situations (followup)

1999-09-17 Thread Matthew Dillon
I think that what needs to be done is to split the problem in two.  First,
allow the mbuf routines to return a failure even with M_WAIT.  If M_WAIT
is used, it simply means 'try harder, sleeping a bit if necessary'.  This 
requires ensuring that all the networking code deal with the failure
case - a time consuming but straightforward task.  If a failure occurs,
one simply drops the packet, not the connection or anything else drastic.
just the packet.

The second problem that needs to be addressed is resource exhaustion.
For example, allocating thousands of connections and socket-opting their
buffers as large as possible, or programs such as syslog accepting new
connections ad-infinitum.  This is a harder problem to fix properly,
but a lot of the various issues such as those with syslog can be dealt 
with in userland rather then the kernel.

-Matt



To Unsubscribe: send mail to majord...@freebsd.org
with unsubscribe freebsd-hackers in the body of the message



Re: mbuf shortage situations (followup)

1999-09-17 Thread Brian F. Feldman
On Mon, 13 Sep 1999, Matthew Dillon wrote:

 The case that is causing the panics is with the non-interrupt mbuf
 allocation mechanism.  Specifically, the case where M_WAIT is used.
 
 The second problem under discussion, which really ought to be separated
 out from the mbuf panic problem, is the potential for a deadlock or 
 denial of service attack when the system is attacked in a manner that
 eats all available mbufs.
 

The traditional way to prevent resource-starvation DoSes from the user
populus has been to add administrative limits.  Using RLIMIT_SBSIZE does
this nicely.  Yes, this isn't actually fixing the panics, but it is
good preventative medicine.

   -Matt
   Matthew Dillon 
   dil...@backplane.com
 

-- 
 Brian Fundakowski Feldman   \  FreeBSD: The Power to Serve!  /
 gr...@freebsd.org`--'



To Unsubscribe: send mail to majord...@freebsd.org
with unsubscribe freebsd-hackers in the body of the message



Re: mbuf shortage situations (followup)

1999-09-14 Thread Stas Kisel
 From woll...@khavrinen.lcs.mit.edu Mon Sep 13 22:39:37 1999
  I'm also aware of the possiblity of some people not liking the
  fact that we tsleep() forever (e.g. tsleep(x,x,x,0)). 

 I don't have any problem with sleeping forever -- but I am concerned
 about the possibility of deadlock, especially when client-NFS is
 involved.  If the problem just moves around and has harder-to-recover
 symptoms, the change isn't helping.

IMHO merely sleeping can't help if we deal with a DoS. Instead of
sleeping, kernel should find out where all kernel memory is wasted
and free some memory (and, probably, remove/log reason). And, partially,
this mechanism is already implemented in ip_drain() and tp_drain().

--
Stas Kisel. UNIX, security, C, TCP/IP, Web. UNIX - the best adventure game
http://www.tekmetrics.com/transcript.shtml?pid=20053 http://www.crimea.edu
+380(652)510222,230238 ; s...@crimea.edu s...@sonet.crimea.ua ; 2:460/54.4



To Unsubscribe: send mail to majord...@freebsd.org
with unsubscribe freebsd-hackers in the body of the message



Re: mbuf shortage situations (followup)

1999-09-13 Thread Bosko Milekic



!I think that what needs to be done is to split the problem in two.  First,
!allow the mbuf routines to return a failure even with M_WAIT.  If M_WAIT
!is used, it simply means 'try harder, sleeping a bit if necessary'.  This 
!requires ensuring that all the networking code deal with the failure
!case - a time consuming but straightforward task.  If a failure occurs,
!one simply drops the packet, not the connection or anything else drastic.
!just the packet.

Yes, these is mainly the part I've been working on recently. The
sleeping and what not (as I'm sure you've seen from the patches if you
looked at them) has already been completed. Adding a counter that will
expire and return a pre-defined error is trivial, in this case.

The only real issue here (if we can call it that) is get _all_ the
networking code to recognize this. Anyone want to help? :-)


!
!The second problem that needs to be addressed is resource exhaustion.
!For example, allocating thousands of connections and socket-opting their
!buffers as large as possible, or programs such as syslog accepting new
!connections ad-infinitum.  This is a harder problem to fix properly,
!but a lot of the various issues such as those with syslog can be dealt 
!with in userland rather then the kernel.
!
!  -Matt
!

I agree. The issue here is somewhat related (if I understand your
explanation correctly) to [local] processes attempting to grab a lot of
socket buffer space. I was a little less concerned with this issue since,
as I previously mentionned, Brian Feldman is working on limiting socket
buffer space. Nonetheless, if we do not consider limiting, here's what I
believe will need to be done:

As explained above, when we run out of mbufs and/or mbuf
clusters (and some are needed), if we are M_WAIT (when processes socket
opt their buffers as large as possible, the call is usually with M_WAIT),
we will end up tsleep()ing for certain periods of time, until our counter
expires and we return our pre-defined error (as mentionned above). When we
do return this error, however, the caller (for instance, we can consider
sosend() the caller -- which, if I remember correctly, is one of the
callers to MGET() when we setsockopt a large buffer and consequently
write() to this socket), will also have to know how to properly deal with
this error (e.g.: kill the process?).

Killing the process may seem somewhat sadistic to some ( :-) ),
but remember that if we do get to the point where 'normal' local processes
eat up so much buffer space that we run out, we should probably be
increasing NMBCLUSTERS and/or maxusers anyway.

As for script weenies, I hope that Brian (and whomever else may be
working on it) gets that sockbuf limiting code done, because, to be quite
honest, I don't think that script kids having to comprimise more than one
account just so they can DoS a box will be much of an issue (if worse
comes to worse, we can limit per gid -as opposed to per uid). With
exhaustion attacks such as these, we're better off just limiting.

Regards,
Bosko Milekic.




To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: mbuf shortage situations (followup)

1999-09-13 Thread Bosko Milekic



On Mon, 13 Sep 1999, Garrett Wollman wrote:

!On Sun, 12 Sep 1999 23:19:13 -0400 (EDT), Bosko Milekic [EMAIL PROTECTED] said:
!
!   This message is in MIME format.  The first part should be readable text,
!   while the remaining parts are likely unreadable without MIME-aware tools.
!   Send mail to [EMAIL PROTECTED] for more info.
!
!It would be preferable if text were sent as text, since MIME-encoded
!patches require more effort to read.
!

I deffinately agree. This is obviously my mistake, and I was
somewhat in a rush, very lagged (modem, eurgh), using pine, and made
several [dumb] typos in the 'Attatchement' field.


! I'm also aware of the possiblity of some people not liking the
! fact that we tsleep() forever (e.g. tsleep(x,x,x,0)). 
!
!
!I don't have any problem with sleeping forever -- but I am concerned
!about the possibility of deadlock, especially when client-NFS is
!involved.  If the problem just moves around and has harder-to-recover
!symptoms, the change isn't helping.

Well, the main purpose of the code is to basically sleep until
something is freed after we've already exhausted the mb_map arena (as I'm
sure you've seen if you were able to grab the attachements). This is
really a-la-limite stuff. In other words, if 'normal' local programs are
having trouble because of mb_map exhaustion, then maxusers  nmbclusters
would have to be augmented.

!
!The 4.3BSD code had two different behaviors:
!
!  - For clusters, if M_WAIT was specified and there was no space
!left in mb_map, it panicked.  However, m_clalloc was never called with
!M_WAIT, so that panic was effectively dead code.

Hmmm. If m_clalloc was never called with M_WAIT, then all the code
calling m_clalloc deffinately checked its return value. It probably had
specific ways to deal with m_clalloc returning failures, too?

!
!  - For mbufs, if M_WAIT was specified and there were no mbufs
!available, it would sleep at PZERO - 1 (which was interruptible).
!
!In 4.3, the code was able to deal with cluster allocation failing.  We
!have a somewhat different situation now, because many network
!interface devices have less-flexible DMA mechanisms which don't allow
!packet reception into non-contiguous buffers, so we need to have at
!least a certain number of clusters available for this purpose.

Exactly. This is the next challenge. As for things being
interruptable, as I mentionned to a reply to Matt Dillon just a few
seconds ago, getting the tsleep to occasionally expire is trivial. As you
say above, it's dealing with the failure that is the issue.

!
!-GAWollman
!
!--
!Garrett A. Wollman   | O Siem / We are all family / O Siem / We're all the same
![EMAIL PROTECTED]  | O Siem / The fires of freedom 
!Opinions not those of| Dance in the burning flame
!MIT, LCS, CRS, or NSA| - Susan Aglukark and Chad Irschick
!

Cheers,
Bosko Milekic.




To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: mbuf shortage situations (followup)

1999-09-13 Thread Garrett Wollman
On Sun, 12 Sep 1999 23:19:13 -0400 (EDT), Bosko Milekic bmile...@dsuper.net 
said:

   This message is in MIME format.  The first part should be readable text,
   while the remaining parts are likely unreadable without MIME-aware tools.
   Send mail to m...@docserver.cac.washington.edu for more info.

It would be preferable if text were sent as text, since MIME-encoded
patches require more effort to read.

   I'm also aware of the possiblity of some people not liking the
 fact that we tsleep() forever (e.g. tsleep(x,x,x,0)). 


I don't have any problem with sleeping forever -- but I am concerned
about the possibility of deadlock, especially when client-NFS is
involved.  If the problem just moves around and has harder-to-recover
symptoms, the change isn't helping.

The 4.3BSD code had two different behaviors:

- For clusters, if M_WAIT was specified and there was no space
left in mb_map, it panicked.  However, m_clalloc was never called with
M_WAIT, so that panic was effectively dead code.

- For mbufs, if M_WAIT was specified and there were no mbufs
available, it would sleep at PZERO - 1 (which was interruptible).

In 4.3, the code was able to deal with cluster allocation failing.  We
have a somewhat different situation now, because many network
interface devices have less-flexible DMA mechanisms which don't allow
packet reception into non-contiguous buffers, so we need to have at
least a certain number of clusters available for this purpose.

-GAWollman

--
Garrett A. Wollman   | O Siem / We are all family / O Siem / We're all the same
woll...@lcs.mit.edu  | O Siem / The fires of freedom 
Opinions not those of| Dance in the burning flame
MIT, LCS, CRS, or NSA| - Susan Aglukark and Chad Irschick


To Unsubscribe: send mail to majord...@freebsd.org
with unsubscribe freebsd-hackers in the body of the message



Re: mbuf shortage situations (followup)

1999-09-13 Thread Bosko Milekic


!I think that what needs to be done is to split the problem in two.  First,
!allow the mbuf routines to return a failure even with M_WAIT.  If M_WAIT
!is used, it simply means 'try harder, sleeping a bit if necessary'.  This 
!requires ensuring that all the networking code deal with the failure
!case - a time consuming but straightforward task.  If a failure occurs,
!one simply drops the packet, not the connection or anything else drastic.
!just the packet.

Yes, these is mainly the part I've been working on recently. The
sleeping and what not (as I'm sure you've seen from the patches if you
looked at them) has already been completed. Adding a counter that will
expire and return a pre-defined error is trivial, in this case.

The only real issue here (if we can call it that) is get _all_ the
networking code to recognize this. Anyone want to help? :-)


!
!The second problem that needs to be addressed is resource exhaustion.
!For example, allocating thousands of connections and socket-opting their
!buffers as large as possible, or programs such as syslog accepting new
!connections ad-infinitum.  This is a harder problem to fix properly,
!but a lot of the various issues such as those with syslog can be dealt 
!with in userland rather then the kernel.
!
!  -Matt
!

I agree. The issue here is somewhat related (if I understand your
explanation correctly) to [local] processes attempting to grab a lot of
socket buffer space. I was a little less concerned with this issue since,
as I previously mentionned, Brian Feldman is working on limiting socket
buffer space. Nonetheless, if we do not consider limiting, here's what I
believe will need to be done:

As explained above, when we run out of mbufs and/or mbuf
clusters (and some are needed), if we are M_WAIT (when processes socket
opt their buffers as large as possible, the call is usually with M_WAIT),
we will end up tsleep()ing for certain periods of time, until our counter
expires and we return our pre-defined error (as mentionned above). When we
do return this error, however, the caller (for instance, we can consider
sosend() the caller -- which, if I remember correctly, is one of the
callers to MGET() when we setsockopt a large buffer and consequently
write() to this socket), will also have to know how to properly deal with
this error (e.g.: kill the process?).

Killing the process may seem somewhat sadistic to some ( :-) ),
but remember that if we do get to the point where 'normal' local processes
eat up so much buffer space that we run out, we should probably be
increasing NMBCLUSTERS and/or maxusers anyway.

As for script weenies, I hope that Brian (and whomever else may be
working on it) gets that sockbuf limiting code done, because, to be quite
honest, I don't think that script kids having to comprimise more than one
account just so they can DoS a box will be much of an issue (if worse
comes to worse, we can limit per gid -as opposed to per uid). With
exhaustion attacks such as these, we're better off just limiting.

Regards,
Bosko Milekic.




To Unsubscribe: send mail to majord...@freebsd.org
with unsubscribe freebsd-hackers in the body of the message



Re: mbuf shortage situations (followup)

1999-09-13 Thread Bosko Milekic


On Mon, 13 Sep 1999, Garrett Wollman wrote:

!On Sun, 12 Sep 1999 23:19:13 -0400 (EDT), Bosko Milekic 
bmile...@dsuper.net said:
!
!   This message is in MIME format.  The first part should be readable text,
!   while the remaining parts are likely unreadable without MIME-aware tools.
!   Send mail to m...@docserver.cac.washington.edu for more info.
!
!It would be preferable if text were sent as text, since MIME-encoded
!patches require more effort to read.
!

I deffinately agree. This is obviously my mistake, and I was
somewhat in a rush, very lagged (modem, eurgh), using pine, and made
several [dumb] typos in the 'Attatchement' field.


! I'm also aware of the possiblity of some people not liking the
! fact that we tsleep() forever (e.g. tsleep(x,x,x,0)). 
!
!
!I don't have any problem with sleeping forever -- but I am concerned
!about the possibility of deadlock, especially when client-NFS is
!involved.  If the problem just moves around and has harder-to-recover
!symptoms, the change isn't helping.

Well, the main purpose of the code is to basically sleep until
something is freed after we've already exhausted the mb_map arena (as I'm
sure you've seen if you were able to grab the attachements). This is
really a-la-limite stuff. In other words, if 'normal' local programs are
having trouble because of mb_map exhaustion, then maxusers  nmbclusters
would have to be augmented.

!
!The 4.3BSD code had two different behaviors:
!
!  - For clusters, if M_WAIT was specified and there was no space
!left in mb_map, it panicked.  However, m_clalloc was never called with
!M_WAIT, so that panic was effectively dead code.

Hmmm. If m_clalloc was never called with M_WAIT, then all the code
calling m_clalloc deffinately checked its return value. It probably had
specific ways to deal with m_clalloc returning failures, too?

!
!  - For mbufs, if M_WAIT was specified and there were no mbufs
!available, it would sleep at PZERO - 1 (which was interruptible).
!
!In 4.3, the code was able to deal with cluster allocation failing.  We
!have a somewhat different situation now, because many network
!interface devices have less-flexible DMA mechanisms which don't allow
!packet reception into non-contiguous buffers, so we need to have at
!least a certain number of clusters available for this purpose.

Exactly. This is the next challenge. As for things being
interruptable, as I mentionned to a reply to Matt Dillon just a few
seconds ago, getting the tsleep to occasionally expire is trivial. As you
say above, it's dealing with the failure that is the issue.

!
!-GAWollman
!
!--
!Garrett A. Wollman   | O Siem / We are all family / O Siem / We're all the 
same
!woll...@lcs.mit.edu  | O Siem / The fires of freedom 
!Opinions not those of| Dance in the burning flame
!MIT, LCS, CRS, or NSA| - Susan Aglukark and Chad Irschick
!

Cheers,
Bosko Milekic.




To Unsubscribe: send mail to majord...@freebsd.org
with unsubscribe freebsd-hackers in the body of the message



Re: mbuf shortage situations (followup)

1999-09-12 Thread Bosko Milekic


Hello (again),

On Thu, 9 Sep 1999, Stas Kisel wrote:

! From [EMAIL PROTECTED] Thu Sep  9 16:17:27 1999
!
!  Probably it is not self-evident why we HAVE to drop this connection.
!
! So what if someone manages to crash a program due to a DOS attack ?
! An easy one that comes to mind is syslogd.  It's often stuck in disk-wait
! and can easily be targetted with a large number of packets.
!
!1. If ever syslog used (or will use) TCP, it should drop the connection
!which is logging data too quickly.
!OS shouldn't kill process, only drop connection. So no crash.
!More examples?
!
!2. udp_drain() may either drop all packets or intellectually select
!"offending" socket and try to avoid deletion of "right" packets and
!simplifying spoofing. RFC allows 1st way, but 2-nd can improve OS.
!
!3. Another idea. Apart from the *_drain() method. Probably I ever will
!try to implement it somedays (quite low probability, though).
!Set TCP window in a packets according to really available kernel
!memory. Available memory should be distributed non-uniformly
!between maximum number of sockets. So 1-st socket has window=
!=64k-still_not_read_data, and 1024-th has window=MIN_WINDOW-
!-still_not_read_data. 
!MIN_WINDOW should be determined for max efficiency. About 2k.
!Distribution can not be linear - it isapproximately like min(NORM*1/x,64k).
!Exactly it can be determined via functional equation. Something like
!\integral_0^maxsockets{dist(x)dx}=kernel_memory and several
!conditions. (sorry for my poor TeX).
!
!In a case of attack new sockets will be created with a very small
!window - about 2k.
!
!Please blame me as much as possible - probably I have missed some significant
!detail.
!Probably all this math suxx and the best is a "stair" function -
!somebody already works on lowering TCP window, if I didn't mistaken.
!
!
!--
!Stas Kisel. UNIX, security, C, TCP/IP, Web. UNIX - the best adventure game
!http://www.tekmetrics.com/transcript.shtml?pid=20053 http://www.crimea.edu
!+380(652)510222,230238 ; [EMAIL PROTECTED] [EMAIL PROTECTED] ; 2:460/54.4
!

These are all interesting ideas.

However, when I initially posted regarding this, I was
disappointed in seeing that we simply handle MGET()s, MGETHDR()s, and
MCLALLOC()s by storing a null _even_ if we are M_WAIT. What basically
ended up happening (and, the last time I checked, it's like this even in
--CURRENT), is m_retry() -- or m_retryhdr() (this is in the case of no
mbufs beings available) would simply panic().
I have produced patches (see attached -- they are seperated into
two different patches, mbuf.patch which patches kern/uipc_mbuf.c and
mbuf2.patch which patches sys/mbuf.h) that will basically tsleep() in the
case of an M_WAIT and mbuf or mbuf cluster shortage. I wanted something
that would make sure that we will get a non-NULL result when we called
with M_WAIT. Obviously, this isn't the definite solution to the DoS
problem that seemed to have become the main idea of discussion in this
thread.
However, I've kept that in mind, and I am now starting work (when
time permits) on some code which will enable us to warn the network
protocol module code that we're out of mbufs (or mbuf clusters) when the
situation occurs. This way, if we can't get anything even with m_reclaim
(which would be called from m_retry if we are M_WAIT), we could have the
protocols figure out what to drop.
I'm also aware of the possiblity of some people not liking the
fact that we tsleep() forever (e.g. tsleep(x,x,x,0)). Thus, I am open to
modifying the diffs to add a counter and have the tsleep expire every once
in a while so that finally, when the counter would expire, we would return
a deffinate null _even_ if we are M_WAIT, but this can only be implemented
if we make sure that ALL the MGET and company callers check for this
(which would be annoying to do).


Cheers,
Bosko Milekic.



--- /usr/src/sys/kern.old/uipc_mbuf.c   Wed Sep  8 20:45:50 1999
+++ /usr/src/sys/kern/uipc_mbuf.c   Sun Sep 12 22:44:23 1999
@@ -60,6 +60,8 @@
 intmax_hdr;
 intmax_datalen;
 
+static int m_mballoc_wid = 0, m_clalloc_wid = 0;
+
 SYSCTL_INT(_kern_ipc, KIPC_MAX_LINKHDR, max_linkhdr, CTLFLAG_RW,
   max_linkhdr, 0, "");
 SYSCTL_INT(_kern_ipc, KIPC_MAX_PROTOHDR, max_protohdr, CTLFLAG_RW,
@@ -153,6 +155,57 @@
return (1);
 }
 
+/*
+ * Function used for waiting on some mbuf to be freed and, upon wakeup,
+ * to go get that mbuf and use it.
+ */
+struct mbuf *
+m_mballoc_wait(caller, type)
+   int caller;
+   int type;
+{
+   struct mbuf *p;
+
+RetryFetch:
+   /* Sleep here until something's available. */
+   m_mballoc_wid++;
+   tsleep(m_mballoc_wid, PVM, "mballc", 0);
+   
+   /*
+* Now that we (think) that we've got something, we will redo an
+* MGET, but avoid getting into another instance of m_mballoc_wait()
+* We do this by defining this function as null.
+*/

Re: mbuf shortage situations (followup)

1999-09-12 Thread Bosko Milekic

Hello (again),

On Thu, 9 Sep 1999, Stas Kisel wrote:

! From ava...@cheops.anu.edu.au Thu Sep  9 16:17:27 1999
!
!  Probably it is not self-evident why we HAVE to drop this connection.
!
! So what if someone manages to crash a program due to a DOS attack ?
! An easy one that comes to mind is syslogd.  It's often stuck in disk-wait
! and can easily be targetted with a large number of packets.
!
!1. If ever syslog used (or will use) TCP, it should drop the connection
!which is logging data too quickly.
!OS shouldn't kill process, only drop connection. So no crash.
!More examples?
!
!2. udp_drain() may either drop all packets or intellectually select
!offending socket and try to avoid deletion of right packets and
!simplifying spoofing. RFC allows 1st way, but 2-nd can improve OS.
!
!3. Another idea. Apart from the *_drain() method. Probably I ever will
!try to implement it somedays (quite low probability, though).
!Set TCP window in a packets according to really available kernel
!memory. Available memory should be distributed non-uniformly
!between maximum number of sockets. So 1-st socket has window=
!=64k-still_not_read_data, and 1024-th has window=MIN_WINDOW-
!-still_not_read_data. 
!MIN_WINDOW should be determined for max efficiency. About 2k.
!Distribution can not be linear - it isapproximately like min(NORM*1/x,64k).
!Exactly it can be determined via functional equation. Something like
!\integral_0^maxsockets{dist(x)dx}=kernel_memory and several
!conditions. (sorry for my poor TeX).
!
!In a case of attack new sockets will be created with a very small
!window - about 2k.
!
!Please blame me as much as possible - probably I have missed some significant
!detail.
!Probably all this math suxx and the best is a stair function -
!somebody already works on lowering TCP window, if I didn't mistaken.
!
!
!--
!Stas Kisel. UNIX, security, C, TCP/IP, Web. UNIX - the best adventure game
!http://www.tekmetrics.com/transcript.shtml?pid=20053 http://www.crimea.edu
!+380(652)510222,230238 ; s...@crimea.edu s...@sonet.crimea.ua ; 2:460/54.4
!

These are all interesting ideas.

However, when I initially posted regarding this, I was
disappointed in seeing that we simply handle MGET()s, MGETHDR()s, and
MCLALLOC()s by storing a null _even_ if we are M_WAIT. What basically
ended up happening (and, the last time I checked, it's like this even in
--CURRENT), is m_retry() -- or m_retryhdr() (this is in the case of no
mbufs beings available) would simply panic().
I have produced patches (see attached -- they are seperated into
two different patches, mbuf.patch which patches kern/uipc_mbuf.c and
mbuf2.patch which patches sys/mbuf.h) that will basically tsleep() in the
case of an M_WAIT and mbuf or mbuf cluster shortage. I wanted something
that would make sure that we will get a non-NULL result when we called
with M_WAIT. Obviously, this isn't the definite solution to the DoS
problem that seemed to have become the main idea of discussion in this
thread.
However, I've kept that in mind, and I am now starting work (when
time permits) on some code which will enable us to warn the network
protocol module code that we're out of mbufs (or mbuf clusters) when the
situation occurs. This way, if we can't get anything even with m_reclaim
(which would be called from m_retry if we are M_WAIT), we could have the
protocols figure out what to drop.
I'm also aware of the possiblity of some people not liking the
fact that we tsleep() forever (e.g. tsleep(x,x,x,0)). Thus, I am open to
modifying the diffs to add a counter and have the tsleep expire every once
in a while so that finally, when the counter would expire, we would return
a deffinate null _even_ if we are M_WAIT, but this can only be implemented
if we make sure that ALL the MGET and company callers check for this
(which would be annoying to do).


Cheers,
Bosko Milekic.

--- /usr/src/sys/kern.old/uipc_mbuf.c   Wed Sep  8 20:45:50 1999
+++ /usr/src/sys/kern/uipc_mbuf.c   Sun Sep 12 22:44:23 1999
@@ -60,6 +60,8 @@
 intmax_hdr;
 intmax_datalen;
 
+static int m_mballoc_wid = 0, m_clalloc_wid = 0;
+
 SYSCTL_INT(_kern_ipc, KIPC_MAX_LINKHDR, max_linkhdr, CTLFLAG_RW,
   max_linkhdr, 0, );
 SYSCTL_INT(_kern_ipc, KIPC_MAX_PROTOHDR, max_protohdr, CTLFLAG_RW,
@@ -153,6 +155,57 @@
return (1);
 }
 
+/*
+ * Function used for waiting on some mbuf to be freed and, upon wakeup,
+ * to go get that mbuf and use it.
+ */
+struct mbuf *
+m_mballoc_wait(caller, type)
+   int caller;
+   int type;
+{
+   struct mbuf *p;
+
+RetryFetch:
+   /* Sleep here until something's available. */
+   m_mballoc_wid++;
+   tsleep(m_mballoc_wid, PVM, mballc, 0);
+   
+   /*
+* Now that we (think) that we've got something, we will redo an
+* MGET, but avoid getting into another instance of m_mballoc_wait()
+* We do this by defining this function as null.
+*/
+#define m_mballoc_wait(caller,type)