From owner-freebsd-security Thu Sep 9 2: 2:52 1999 Delivered-To: freebsd-security@freebsd.org Received: from sonet.crimea.ua (OTC-sl3-FLY.CRIS.NET [212.110.136.71]) by hub.freebsd.org (Postfix) with ESMTP id 0AC6C15024 for ; Thu, 9 Sep 1999 02:01:47 -0700 (PDT) (envelope-from stas@sonet.crimea.ua) Received: (from stas@localhost) by sonet.crimea.ua (8.8.8/8.8.8) id MAA16555 for freebsd-security@freebsd.org; Thu, 9 Sep 1999 12:02:45 +0400 (MSD) (envelope-from stas) Date: Thu, 9 Sep 1999 12:02:45 +0400 (MSD) From: Stas Kisel Message-Id: <199909090802.MAA16555@sonet.crimea.ua> To: freebsd-security@freebsd.org Subject: mbuf shortage situations Sender: owner-freebsd-security@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org > From: bmilekic@dsuper.net (Bosko Milekic) > Having MGET store that null (e.g. fail as opposed to panic) on a > M_WAIT seems fairly easy to fix, and would probably require some patching > that would ensure that the packet loss is handeled relatively 'cleanly' > (probably some debugging), but I wouldn't mind doing this. However, I'd > like to know if there are objections to doing this or, in fact, if there > are any suggestions on how to handle mbuf shortage situations (aside from > just limiting -- although limiting is in itself a good solution and I'm > glad that Brian F. is working on that). I really don't like limiting as an anti-DoS method. In user-based limiting limits have to be divided by "maximum number of users which can cooperate to make DoS" - quite inevident number. Especially if you have many easy-compromisable accounts - eg. shell server for a university classrooms. In process-based limiting limits also have to be divided by max proc per user. This results in very low, inconvenient limits. Probably there are another methods (kernel swapping comes to mind, but probably it is too hard to implement). IMHO it is a good idea to develop tcp_drain() from /sys/netinet/tcp_subr.c It should be quite intellectual to select a target - a process or a uid, which does not read properly from it's sockets, and has many data in mbufs. IMHO it is bad idea to drop packets, because this can be used for SPOOFING ARBITRARY DATA into TCP stream, which is very INSECURE[1]. Same goes for ALREADY implemented ip_drain() wich now seems to drop all fragments. Killing a process is not a good idea too, because it allows to DoS incorrectly developed applications. Attacker just have to feed so much network data, that application can not process it (I have no example, but it is easy to imagine an appplication, which spends more time to process requiest than network to transmit - a sort of database search or remote computing or so...). IMHO the best solution is to drop offending connection, though is can allow DoS too, if application can be made busy enough to not read from sockets. But this sort of applications can be DoS-ed anyways. Good applications have to read all their data from sockets. All other *_drain() functions should be implemented with the same care to determine offender and not allow DoS (/sys/netinet/in_proto.c). There are programs which use Unix Domain sockets and ICMP for causing DoS by mbuf starvation, if I recall correctly. This is a flaw in a _drain() method of eliminating this DoS - we have to find _all_ places where incorrect or hostile application can cause kernel to allocate mbufs. And remember about DoS when adding a new protocol or probably another code. m_reclaim() in /sys/kern/uipc_mbuf.c should be modified to (probably with all _drain interface) to determine correctly offending domain and protocol. It woild be very bad thing if in reply to frag flooding we will drop a, say, ssh connection. Or, probably, _drain functions each have to decide - "to drain or not to drain". IMHO 1-st way is better. -------------------------------- [1] Theoretical algorythm to spoof arbitrary data, based on possible flaw in ip_drain(). Requirements: 1. Ability to sniff traffic (eg, attacker is on the same Ethernet segment as victim) 2. quite slow connections of client to a target. - Sniff a network to find out a sequence number and a fragmented connection. - Wait for a moment when only one fragment (containing sensitive information) of a packed has arrived. - Cause mbuf starvaition by not reading from sockets (there are a lot of programs for it). - kernel drops all fragments, including one from target connection. - kill DoS-ing program - Assemble and spoof bogus fragment instead of dropped one. Note: The same algorythm can be used if you'll decide to drop TCP packets instead of ACK-ing them. Note: This algorytm is theoretical only - so probably I'm wrong. -------------------------------- \bye Stas PS. Would some of you, folks, be so kind to forward this message to an appropriate place, or just tell me about this place if I have mistaken by sending it only to -hackers and to -security. The trouble is in that I'm not familiar with unformal "what who does here" and "where which talks go". To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message