From owner-svn-src-all@freebsd.org Tue Dec 1 17:04:48 2020 Return-Path: Delivered-To: svn-src-all@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 B2EEB4AE959; Tue, 1 Dec 2020 17:04:48 +0000 (UTC) (envelope-from jhb@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 4ClpPD4dbpz4Xnr; Tue, 1 Dec 2020 17:04:48 +0000 (UTC) (envelope-from jhb@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 8DB67191FD; Tue, 1 Dec 2020 17:04:48 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0B1H4m4e007177; Tue, 1 Dec 2020 17:04:48 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0B1H4lNN007171; Tue, 1 Dec 2020 17:04:47 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <202012011704.0B1H4lNN007171@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Tue, 1 Dec 2020 17:04:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r368240 - in head/sys: cddl/dev/dtrace/amd64 cddl/dev/dtrace/i386 ddb riscv/riscv sys x86/x86 X-SVN-Group: head X-SVN-Commit-Author: jhb X-SVN-Commit-Paths: in head/sys: cddl/dev/dtrace/amd64 cddl/dev/dtrace/i386 ddb riscv/riscv sys x86/x86 X-SVN-Commit-Revision: 368240 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Dec 2020 17:04:48 -0000 Author: jhb Date: Tue Dec 1 17:04:46 2020 New Revision: 368240 URL: https://svnweb.freebsd.org/changeset/base/368240 Log: Add a kstack_contains() helper function. This is useful for stack unwinders which need to avoid out-of-bounds reads of a kernel stack which can trigger kernel faults. Reviewed by: kib, markj Obtained from: CheriBSD Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D27356 Modified: head/sys/cddl/dev/dtrace/amd64/dtrace_isa.c head/sys/cddl/dev/dtrace/i386/dtrace_isa.c head/sys/ddb/db_ps.c head/sys/riscv/riscv/stack_machdep.c head/sys/sys/proc.h head/sys/x86/x86/stack_machdep.c Modified: head/sys/cddl/dev/dtrace/amd64/dtrace_isa.c ============================================================================== --- head/sys/cddl/dev/dtrace/amd64/dtrace_isa.c Tue Dec 1 16:44:36 2020 (r368239) +++ head/sys/cddl/dev/dtrace/amd64/dtrace_isa.c Tue Dec 1 17:04:46 2020 (r368240) @@ -73,14 +73,10 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, in frame = (struct amd64_frame *)rbp; td = curthread; while (depth < pcstack_limit) { - if (!INKERNEL((long) frame)) + if (!kstack_contains(curthread, (vm_offset_t)frame, + sizeof(*frame)) break; - if ((vm_offset_t)frame >= - td->td_kstack + ptoa(td->td_kstack_pages) || - (vm_offset_t)frame < td->td_kstack) - break; - callpc = frame->f_retaddr; if (!INKERNEL(callpc)) @@ -466,14 +462,11 @@ dtrace_getstackdepth(int aframes) frame = (struct amd64_frame *)rbp; depth++; for(;;) { - if (!INKERNEL((long) frame)) + if (!kstack_contains(curthread, (vm_offset_t)frame, + sizeof(*frame)) break; - if (!INKERNEL((long) frame->f_frame)) - break; depth++; - if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= curthread->td_kstack + - curthread->td_kstack_pages * PAGE_SIZE) + if (frame->f_frame <= frame) break; frame = frame->f_frame; } Modified: head/sys/cddl/dev/dtrace/i386/dtrace_isa.c ============================================================================== --- head/sys/cddl/dev/dtrace/i386/dtrace_isa.c Tue Dec 1 16:44:36 2020 (r368239) +++ head/sys/cddl/dev/dtrace/i386/dtrace_isa.c Tue Dec 1 17:04:46 2020 (r368240) @@ -73,7 +73,8 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, in frame = (struct i386_frame *)ebp; while (depth < pcstack_limit) { - if (!INKERNEL(frame)) + if (!kstack_contains(curthread, (vm_offset_t)frame, + sizeof(*frame)) break; callpc = frame->f_retaddr; @@ -91,9 +92,7 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, in pcstack[depth++] = callpc; } - if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= curthread->td_kstack + - curthread->td_kstack_pages * PAGE_SIZE) + if (frame->f_frame <= frame) break; frame = frame->f_frame; } @@ -484,14 +483,10 @@ dtrace_getstackdepth(int aframes) frame = (struct i386_frame *)ebp; depth++; for(;;) { - if (!INKERNEL((long) frame)) + if (!kstack_contains((vm_offset_t)frame, sizeof(*frame)) break; - if (!INKERNEL((long) frame->f_frame)) - break; depth++; - if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= curthread->td_kstack + - curthread->td_kstack_pages * PAGE_SIZE) + if (frame->f_frame <= frame) break; frame = frame->f_frame; } Modified: head/sys/ddb/db_ps.c ============================================================================== --- head/sys/ddb/db_ps.c Tue Dec 1 16:44:36 2020 (r368239) +++ head/sys/ddb/db_ps.c Tue Dec 1 17:04:46 2020 (r368240) @@ -527,8 +527,7 @@ db_findstack_cmd(db_expr_t addr, bool have_addr, db_ex FOREACH_PROC_IN_SYSTEM(p) { FOREACH_THREAD_IN_PROC(p, td) { - if (td->td_kstack <= saddr && saddr < td->td_kstack + - PAGE_SIZE * td->td_kstack_pages) { + if (kstack_contains(td, saddr, 1)) { db_printf("Thread %p\n", td); return; } Modified: head/sys/riscv/riscv/stack_machdep.c ============================================================================== --- head/sys/riscv/riscv/stack_machdep.c Tue Dec 1 16:44:36 2020 (r368239) +++ head/sys/riscv/riscv/stack_machdep.c Tue Dec 1 17:04:46 2020 (r368240) @@ -53,9 +53,8 @@ stack_capture(struct thread *td, struct stack *st, str stack_zero(st); while (1) { - if ((vm_offset_t)frame->fp < td->td_kstack || - (vm_offset_t)frame->fp >= td->td_kstack + - td->td_kstack_pages * PAGE_SIZE) + if (!kstack_contains(td, (vm_offset_t)frame->fp - + (sizeof(uintptr_t) * 2), sizeof(uintptr_t) * 2)) break; unwind_frame(frame); if (!INKERNEL((vm_offset_t)frame->pc)) Modified: head/sys/sys/proc.h ============================================================================== --- head/sys/sys/proc.h Tue Dec 1 16:44:36 2020 (r368239) +++ head/sys/sys/proc.h Tue Dec 1 17:04:46 2020 (r368240) @@ -1198,6 +1198,13 @@ curthread_pflags2_restore(int save) curthread->td_pflags2 &= save; } +static __inline bool +kstack_contains(struct thread *td, vm_offset_t va, size_t len) +{ + return (va >= td->td_kstack && va + len >= va && + va + len <= td->td_kstack + td->td_kstack_pages * PAGE_SIZE); +} + static __inline __pure2 struct td_sched * td_get_sched(struct thread *td) { Modified: head/sys/x86/x86/stack_machdep.c ============================================================================== --- head/sys/x86/x86/stack_machdep.c Tue Dec 1 16:44:36 2020 (r368239) +++ head/sys/x86/x86/stack_machdep.c Tue Dec 1 17:04:46 2020 (r368240) @@ -79,9 +79,7 @@ stack_capture(struct thread *td, struct stack *st, reg stack_zero(st); frame = (x86_frame_t)fp; while (1) { - if ((vm_offset_t)frame < td->td_kstack || - (vm_offset_t)frame >= td->td_kstack + - td->td_kstack_pages * PAGE_SIZE) + if (!kstack_contains(td, (vm_offset_t)frame, sizeof(*frame))) break; callpc = frame->f_retaddr; if (!INKERNEL(callpc))