From owner-freebsd-bugs@FreeBSD.ORG Sat Nov 13 13:20:05 2010 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1E99F106564A for ; Sat, 13 Nov 2010 13:20:05 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id D50588FC15 for ; Sat, 13 Nov 2010 13:20:04 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id oADDK4cg044596 for ; Sat, 13 Nov 2010 13:20:04 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id oADDK4Gk044595; Sat, 13 Nov 2010 13:20:04 GMT (envelope-from gnats) Resent-Date: Sat, 13 Nov 2010 13:20:04 GMT Resent-Message-Id: <201011131320.oADDK4Gk044595@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Andrey Zonov Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9C4B7106566B for ; Sat, 13 Nov 2010 13:19:52 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 6FF128FC0A for ; Sat, 13 Nov 2010 13:19:52 +0000 (UTC) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id oADDJqEq020133 for ; Sat, 13 Nov 2010 13:19:52 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id oADDJqjg020132; Sat, 13 Nov 2010 13:19:52 GMT (envelope-from nobody) Message-Id: <201011131319.oADDJqjg020132@www.freebsd.org> Date: Sat, 13 Nov 2010 13:19:52 GMT From: Andrey Zonov To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/152200: Overflow in vmspace_swap_count() X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Nov 2010 13:20:05 -0000 >Number: 152200 >Category: kern >Synopsis: Overflow in vmspace_swap_count() >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Nov 13 13:20:04 UTC 2010 >Closed-Date: >Last-Modified: >Originator: Andrey Zonov >Release: 8.1-RELEASE >Organization: >Environment: FreeBSD xxx.xxx.ru 8.1-RELEASE FreeBSD 8.1-RELEASE #0 r212732M: Tue Mar 30 03:14:51 MSD 2010 root@xxx.xxx.ru:/usr/obj/usr/src/sys/GENERIC amd64 >Description: When memory exhasted, [pagedaemon] calls src/sys/vm/vm_pageout.c:vm_pageout_oom(), this function calls src/sys/vm/swap_pager.c:vmspace_swap_count() for swap usage calculation of process. vmspace_swap_count() uses type `int' for address defference and it often leads to `n' variable overflow and system may kill random swapped processes, not only with big memory usage. >How-To-Repeat: # swapon /dev/something # fetch http://zonov.pp.ru/tests/swapped_test.tbz # tar xyf swapped_test.tbz # cd swapped_test # make test Be carefully, that may hang up your system! >Fix: Patch attached with submission follows: Index: /usr/src/sys/vm/vm_map.h =================================================================== --- /usr/src/sys/vm/vm_map.h (revision 212732) +++ /usr/src/sys/vm/vm_map.h (working copy) @@ -373,6 +373,6 @@ int flags); int vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end, int flags); -int vmspace_swap_count (struct vmspace *vmspace); +long vmspace_swap_count (struct vmspace *vmspace); #endif /* _KERNEL */ #endif /* _VM_MAP_ */ Index: /usr/src/sys/vm/swap_pager.c =================================================================== --- /usr/src/sys/vm/swap_pager.c (revision 212732) +++ /usr/src/sys/vm/swap_pager.c (working copy) @@ -2412,12 +2412,12 @@ * if the VM object has any swap use at all the associated map entries * count for at least 1 swap page. */ -int +long vmspace_swap_count(struct vmspace *vmspace) { vm_map_t map = &vmspace->vm_map; vm_map_entry_t cur; - int count = 0; + long count = 0; for (cur = map->header.next; cur != &map->header; cur = cur->next) { vm_object_t object; @@ -2427,7 +2427,7 @@ VM_OBJECT_LOCK(object); if (object->type == OBJT_SWAP && object->un_pager.swp.swp_bcount != 0) { - int n = (cur->end - cur->start) / PAGE_SIZE; + vm_offset_t n = (cur->end - cur->start) / PAGE_SIZE; count += object->un_pager.swp.swp_bcount * SWAP_META_PAGES * n / object->size + 1; >Release-Note: >Audit-Trail: >Unformatted: