From owner-svn-src-stable-12@freebsd.org Fri Jun 26 16:16:27 2020 Return-Path: Delivered-To: svn-src-stable-12@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 4B98435B5EB; Fri, 26 Jun 2020 16:16:27 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49thpM1JmHz4pCY; Fri, 26 Jun 2020 16:16:27 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 27FB916C18; Fri, 26 Jun 2020 16:16:27 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 05QGGRZI050182; Fri, 26 Jun 2020 16:16:27 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05QGGQUt050177; Fri, 26 Jun 2020 16:16:26 GMT (envelope-from markj@FreeBSD.org) Message-Id: <202006261616.05QGGQUt050177@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Fri, 26 Jun 2020 16:16:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r362653 - in stable/12/sys: compat/linuxkpi/common/src vm X-SVN-Group: stable-12 X-SVN-Commit-Author: markj X-SVN-Commit-Paths: in stable/12/sys: compat/linuxkpi/common/src vm X-SVN-Commit-Revision: 362653 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-12@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for only the 12-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Jun 2020 16:16:27 -0000 Author: markj Date: Fri Jun 26 16:16:25 2020 New Revision: 362653 URL: https://svnweb.freebsd.org/changeset/base/362653 Log: MFC r362361, r362363: Add a helper function for validating VA ranges. Modified: stable/12/sys/compat/linuxkpi/common/src/linux_page.c stable/12/sys/vm/vm_fault.c stable/12/sys/vm/vm_map.c stable/12/sys/vm/vm_map.h stable/12/sys/vm/vm_mmap.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/compat/linuxkpi/common/src/linux_page.c ============================================================================== --- stable/12/sys/compat/linuxkpi/common/src/linux_page.c Fri Jun 26 15:14:03 2020 (r362652) +++ stable/12/sys/compat/linuxkpi/common/src/linux_page.c Fri Jun 26 16:16:25 2020 (r362653) @@ -235,7 +235,7 @@ __get_user_pages_fast(unsigned long start, int nr_page va = start; map = &curthread->td_proc->p_vmspace->vm_map; end = start + (((size_t)nr_pages) << PAGE_SHIFT); - if (start < vm_map_min(map) || end > vm_map_max(map)) + if (!vm_map_range_valid(map, start, end)) return (-EINVAL); prot = write ? (VM_PROT_READ | VM_PROT_WRITE) : VM_PROT_READ; for (count = 0, mp = pages, va = start; va < end; Modified: stable/12/sys/vm/vm_fault.c ============================================================================== --- stable/12/sys/vm/vm_fault.c Fri Jun 26 15:14:03 2020 (r362652) +++ stable/12/sys/vm/vm_fault.c Fri Jun 26 16:16:25 2020 (r362653) @@ -1643,10 +1643,7 @@ vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t ad end = round_page(addr + len); addr = trunc_page(addr); - /* - * Check for illegal addresses. - */ - if (addr < vm_map_min(map) || addr > end || end > vm_map_max(map)) + if (!vm_map_range_valid(map, addr, end)) return (-1); if (atop(end - addr) > max_count) Modified: stable/12/sys/vm/vm_map.c ============================================================================== --- stable/12/sys/vm/vm_map.c Fri Jun 26 15:14:03 2020 (r362652) +++ stable/12/sys/vm/vm_map.c Fri Jun 26 16:16:25 2020 (r362653) @@ -1450,8 +1450,7 @@ vm_map_insert(vm_map_t map, vm_object_t object, vm_oof /* * Check that the start and end points are not bogus. */ - if (start < vm_map_min(map) || end > vm_map_max(map) || - start >= end) + if (start == end || !vm_map_range_valid(map, start, end)) return (KERN_INVALID_ADDRESS); /* @@ -1986,9 +1985,7 @@ again: goto done; } } else if ((cow & MAP_REMAP) != 0) { - if (*addr < vm_map_min(map) || - *addr + length > vm_map_max(map) || - *addr + length <= length) { + if (!vm_map_range_valid(map, *addr, *addr + length)) { rv = KERN_INVALID_ADDRESS; goto done; } @@ -4163,9 +4160,8 @@ vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos, KASSERT(orient != (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP), ("bi-dir stack")); - if (addrbos < vm_map_min(map) || - addrbos + max_ssize > vm_map_max(map) || - addrbos + max_ssize <= addrbos) + if (max_ssize == 0 || + !vm_map_range_valid(map, addrbos, addrbos + max_ssize)) return (KERN_INVALID_ADDRESS); sgp = ((curproc->p_flag2 & P2_STKGAP_DISABLE) != 0 || (curproc->p_fctl0 & NT_FREEBSD_FCTL_STKGAP_DISABLE) != 0) ? 0 : Modified: stable/12/sys/vm/vm_map.h ============================================================================== --- stable/12/sys/vm/vm_map.h Fri Jun 26 15:14:03 2020 (r362652) +++ stable/12/sys/vm/vm_map.h Fri Jun 26 16:16:25 2020 (r362653) @@ -250,6 +250,17 @@ vm_map_modflags(vm_map_t map, vm_flags_t set, vm_flags { map->flags = (map->flags | set) & ~clear; } + +static inline bool +vm_map_range_valid(vm_map_t map, vm_offset_t start, vm_offset_t end) +{ + if (end < start) + return (false); + if (start < vm_map_min(map) || end > vm_map_max(map)) + return (false); + return (true); +} + #endif /* KLD_MODULE */ #endif /* _KERNEL */ Modified: stable/12/sys/vm/vm_mmap.c ============================================================================== --- stable/12/sys/vm/vm_mmap.c Fri Jun 26 15:14:03 2020 (r362652) +++ stable/12/sys/vm/vm_mmap.c Fri Jun 26 16:16:25 2020 (r362653) @@ -298,11 +298,8 @@ kern_mmap_fpcheck(struct thread *td, uintptr_t addr0, return (EINVAL); /* Address range must be all in user VM space. */ - if (addr < vm_map_min(&vms->vm_map) || - addr + size > vm_map_max(&vms->vm_map)) + if (!vm_map_range_valid(&vms->vm_map, addr, addr + size)) return (EINVAL); - if (addr + size < addr) - return (EINVAL); #ifdef MAP_32BIT if (flags & MAP_32BIT && addr + size > MAP_32BIT_MAX_ADDR) return (EINVAL); @@ -534,7 +531,7 @@ kern_munmap(struct thread *td, uintptr_t addr0, size_t vm_map_entry_t entry; bool pmc_handled; #endif - vm_offset_t addr; + vm_offset_t addr, end; vm_size_t pageoff; vm_map_t map; @@ -546,15 +543,11 @@ kern_munmap(struct thread *td, uintptr_t addr0, size_t addr -= pageoff; size += pageoff; size = (vm_size_t) round_page(size); - if (addr + size < addr) - return (EINVAL); - - /* - * Check for illegal addresses. Watch out for address wrap... - */ + end = addr + size; map = &td->td_proc->p_vmspace->vm_map; - if (addr < vm_map_min(map) || addr + size > vm_map_max(map)) + if (!vm_map_range_valid(map, addr, end)) return (EINVAL); + vm_map_lock(map); #ifdef HWPMC_HOOKS pmc_handled = false; @@ -566,7 +559,7 @@ kern_munmap(struct thread *td, uintptr_t addr0, size_t */ pkm.pm_address = (uintptr_t) NULL; if (vm_map_lookup_entry(map, addr, &entry)) { - for (; entry->start < addr + size; + for (; entry->start < end; entry = entry->next) { if (vm_map_check_protection(map, entry->start, entry->end, VM_PROT_EXECUTE) == TRUE) { @@ -578,7 +571,7 @@ kern_munmap(struct thread *td, uintptr_t addr0, size_t } } #endif - vm_map_delete(map, addr, addr + size); + vm_map_delete(map, addr, end); #ifdef HWPMC_HOOKS if (__predict_false(pmc_handled)) { @@ -715,9 +708,7 @@ kern_madvise(struct thread *td, uintptr_t addr0, size_ */ map = &td->td_proc->p_vmspace->vm_map; addr = addr0; - if (addr < vm_map_min(map) || addr + len > vm_map_max(map)) - return (EINVAL); - if ((addr + len) < addr) + if (!vm_map_range_valid(map, addr, addr + len)) return (EINVAL); /*