Date: Tue, 24 Jul 2007 16:37:19 GMT From: Craig Boston <craig@xfoil.gank.org> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/114870: tmpfs max file size overflow Message-ID: <200707241637.l6OGbJZI067086@www.freebsd.org> Resent-Message-ID: <200707241640.l6OGe1od013250@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 114870 >Category: kern >Synopsis: tmpfs max file size overflow >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Jul 24 16:40:01 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Craig Boston >Release: 7.0-CURRENT >Organization: >Environment: FreeBSD test 7.0-CURRENT FreeBSD 7.0-CURRENT #0: Wed Jul 18 13:40:41 CDT 2007 me@test:/compile/obj/compile/src/sys/TEST i386 >Description: tmpfs calculates tm_maxfilesize by first finding the number of usable swap pages in get_swpgtotal(), then multiplying by PAGE_SIZE. While tm_maxfilesize is a u_int64_t, get_swpgtotal() returns a u_int, and multiplying by a constant may result in an overflow on i386. In my case with 12GB of swap, get_swpgtotal() returned 3145944, but tm_maxfilesize ended up as 884736, making it impossible to create files in /tmp larger than 864k without getting "File too large" (EFBIG). The problem exists on any 32-bit system with > 4GB of swap, though the resulting limit may or may not be noticeable depending on what the final value is. >How-To-Repeat: Set up more than 4GB of swap on an i386 system, mount a tmpfs filesystem somewhere, and examine the incorrect value of tm_maxfilesize >Fix: Casting the return of get_swpgtotal() to u_int64_t causes the calculation to be made correctly. === sys/fs/tmpfs/tmpfs_vfsops.c ================================================================== --- sys/fs/tmpfs/tmpfs_vfsops.c (revision 777) +++ sys/fs/tmpfs/tmpfs_vfsops.c (local) @@ -268,7 +268,7 @@ mtx_init(&tmp->allnode_lock, "tmpfs allnode lock", NULL, MTX_DEF); tmp->tm_nodes_max = nodes; tmp->tm_nodes_inuse = 0; - tmp->tm_maxfilesize = get_swpgtotal() * PAGE_SIZE; + tmp->tm_maxfilesize = (u_int64_t)get_swpgtotal() * PAGE_SIZE; LIST_INIT(&tmp->tm_nodes_used); tmp->tm_pages_max = pages; >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707241637.l6OGbJZI067086>