From owner-svn-src-releng@FreeBSD.ORG Mon Apr 1 09:56:21 2013 Return-Path: Delivered-To: svn-src-releng@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 00D514FB; Mon, 1 Apr 2013 09:56:20 +0000 (UTC) (envelope-from tijl@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id D912FFAC; Mon, 1 Apr 2013 09:56:20 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r319uK0M015216; Mon, 1 Apr 2013 09:56:20 GMT (envelope-from tijl@svn.freebsd.org) Received: (from tijl@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r319uKtB015215; Mon, 1 Apr 2013 09:56:20 GMT (envelope-from tijl@svn.freebsd.org) Message-Id: <201304010956.r319uKtB015215@svn.freebsd.org> From: Tijl Coosemans Date: Mon, 1 Apr 2013 09:56:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r248966 - releng/8.4/sys/kern X-SVN-Group: releng MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-releng@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the release engineering / security commits to the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Apr 2013 09:56:21 -0000 Author: tijl Date: Mon Apr 1 09:56:20 2013 New Revision: 248966 URL: http://svnweb.freebsd.org/changeset/base/248966 Log: MFS r248880: - Fix two possible overflows when testing if ELF program headers are on the first page: 1. Cast uint16_t operands in a multiplication to unsigned int because otherwise the implicit promotion to int results in a signed multiplication that can overflow and the behaviour on integer overflow is undefined. 2. Replace (offset + size > PAGE_SIZE) with (size > PAGE_SIZE - offset) because the sum may overflow. - Use the same tests to see if the path to the interpreter is on the first page. There's no overflow here because size is already limited by MAXPATHLEN, but the compiler optimises the new tests better. Also fix an off-by-one error. - Simplify tests to see if an ELF note program header is on the first page. This also fixes an off-by-one error. Reviewed by: kib Approved by: re (glebius) Modified: releng/8.4/sys/kern/imgact_elf.c Directory Properties: releng/8.4/sys/ (props changed) releng/8.4/sys/kern/ (props changed) Modified: releng/8.4/sys/kern/imgact_elf.c ============================================================================== --- releng/8.4/sys/kern/imgact_elf.c Mon Apr 1 00:44:20 2013 (r248965) +++ releng/8.4/sys/kern/imgact_elf.c Mon Apr 1 09:56:20 2013 (r248966) @@ -629,9 +629,8 @@ __elfN(load_file)(struct proc *p, const } /* Only support headers that fit within first page for now */ - /* (multiplication of two Elf_Half fields will not overflow) */ if ((hdr->e_phoff > PAGE_SIZE) || - (hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE - hdr->e_phoff) { + (u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) { error = ENOEXEC; goto fail; } @@ -713,7 +712,7 @@ __CONCAT(exec_, __elfN(imgact))(struct i */ if ((hdr->e_phoff > PAGE_SIZE) || - (hdr->e_phoff + hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE) { + (u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) { /* Only support headers in first page for now */ return (ENOEXEC); } @@ -732,8 +731,8 @@ __CONCAT(exec_, __elfN(imgact))(struct i if (phdr[i].p_type == PT_INTERP) { /* Path to interpreter */ if (phdr[i].p_filesz > MAXPATHLEN || - phdr[i].p_offset >= PAGE_SIZE || - phdr[i].p_offset + phdr[i].p_filesz >= PAGE_SIZE) + phdr[i].p_offset > PAGE_SIZE || + phdr[i].p_filesz > PAGE_SIZE - phdr[i].p_offset) return (ENOEXEC); interp = imgp->image_header + phdr[i].p_offset; interp_name_len = phdr[i].p_filesz; @@ -1417,9 +1416,8 @@ __elfN(parse_notes)(struct image_params const char *note_name; int i; - if (pnote == NULL || pnote->p_offset >= PAGE_SIZE || - pnote->p_filesz > PAGE_SIZE || - pnote->p_offset + pnote->p_filesz >= PAGE_SIZE) + if (pnote == NULL || pnote->p_offset > PAGE_SIZE || + pnote->p_filesz > PAGE_SIZE - pnote->p_offset) return (FALSE); note = note0 = (const Elf_Note *)(imgp->image_header + pnote->p_offset);