From owner-freebsd-bugs Mon Jun 19 13: 0: 8 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id C902C37BD6F for ; Mon, 19 Jun 2000 13:00:00 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id NAA36578; Mon, 19 Jun 2000 13:00:00 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from ady.warpnet.ro (ady.warpnet.ro [194.102.224.1]) by hub.freebsd.org (Postfix) with ESMTP id B46CB37B641 for ; Mon, 19 Jun 2000 12:52:45 -0700 (PDT) (envelope-from ady@ady.warpnet.ro) Received: (from ady@localhost) by ady.warpnet.ro (8.9.3/8.9.3) id XAA83914; Mon, 19 Jun 2000 23:00:17 +0300 (EEST) (envelope-from ady) Message-Id: <200006192000.XAA83914@ady.warpnet.ro> Date: Mon, 19 Jun 2000 23:00:17 +0300 (EEST) From: Adrian Penisoara Reply-To: Adrian Penisoara To: FreeBSD-gnats-submit@freebsd.org Cc: Brian Somers X-Send-Pr-Version: 3.2 Subject: bin/19384: PPP route deletion bug/possible DoS Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 19384 >Category: bin >Synopsis: PPP route deletion bug/possible DoS >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Jun 19 13:00:00 PDT 2000 >Closed-Date: >Last-Modified: >Originator: Adrian Penisoara >Release: FreeBSD 3.4-STABLE i386 >Organization: Warp Net Technologies >Environment: This has been "tested" on 3.4-STABLE, but, as I checked in the CVS repository, it affects _all_ FreeBSD branches. OpenBSD might be affected too ?!? >Description: After more than half an year that I've been stressed by a weird route deletion problem I finally discoverd the bug that affected me. First, let me say that my situation is a bit special in that I use almost 30 PPP processes at the same time on our dial-up / leased line server. The problem I was bitten by was that every now and then, and especially whenever some dial-up user was hanging up, I was loosing routing information on the first tunnel interfaces (including the IP on the interface, I use proxy ARP). The problem: in function iface_Create in ppp/iface.c the index number of the interface is taken from the routing table by comparing the interface names with a strncmp call like this: dl = (struct sockaddr_dl *)(ifm + 1); /* Single _dl at end */ if (!strncmp(name, dl->sdl_data, dl->sdl_nlen)) { iface = (struct iface *)malloc(sizeof *iface); ... This code works as expected when using no more than 9 tunnel interfaces; but when we are using an interface numbered over 9 (eg. tun28) then we will be comparing strings like "tun28" and "tun2" on the length of the second, so we'll have a match when we shouldn't had... This way the PPP process was computing a wrong index number in the routing table. Later, when the process is about to die, in ppp/route.c, it will remove the routes from the shorter named interface tunnel instead of the right one (e.g. it will remove all routing information tied to tun2 instead of tun28). From this moment the link is effectively dead (at least in the proxy ARP case): whatever traffic is sent from one end is discarded on the other end, but the link remains up; the only solution is to force a link renegotiation in order to restore the routing information. >How-To-Repeat: This may be exploited by users allowed to use PPP (e.g. users in group network and with proper allow lines in /etc/ppp.conf), provided that support for over 9 tunnel devices was compiled in the kernel: say an user wants to block tun1, he will initiate a PPP session forcing the use of a tunnel in the 10-19 range, like this: $ ppp -unit 12 link-label then he hangs up and upon termination all tun1's routing information will be removed from the routing tables (this can be checked using "route monitor" or even logging PPP at debug level). >Fix: Suggested patch (tested with success for more than 2 hours): --- usr.sbin/ppp/iface.c.orig Mon Jan 10 20:29:04 2000 +++ usr.sbin/ppp/iface.c Mon Jun 19 21:12:04 2000 @@ -91,6 +91,8 @@ return bits; } +static inline size_t max(size_t a, size_t b) { return (a>b ? a : b); } + struct iface * iface_Create(const char *name) { @@ -146,7 +148,7 @@ if (ifm->ifm_type != RTM_IFINFO) break; dl = (struct sockaddr_dl *)(ifm + 1); /* Single _dl at end */ - if (!strncmp(name, dl->sdl_data, dl->sdl_nlen)) { + if (!strncmp(name, dl->sdl_data, max(strlen(name),dl->sdl_nlen))) { iface = (struct iface *)malloc(sizeof *iface); if (iface == NULL) { fprintf(stderr, "iface_Create: malloc: %s\n", strerror(errno)); You may contact me for further details if you need. Thank you, Adrian Penisoara Ady (@freebsd.ady.ro) Warp Net Technologies >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message