From owner-svn-src-head@freebsd.org Fri Jul 17 14:39:08 2020 Return-Path: Delivered-To: svn-src-head@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 3C0C7366A1F; Fri, 17 Jul 2020 14:39:08 +0000 (UTC) (envelope-from andrew@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 4B7YfN0s0kz483P; Fri, 17 Jul 2020 14:39:08 +0000 (UTC) (envelope-from andrew@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 00C501A66D; Fri, 17 Jul 2020 14:39:08 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 06HEd7ES050697; Fri, 17 Jul 2020 14:39:07 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 06HEd742050696; Fri, 17 Jul 2020 14:39:07 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <202007171439.06HEd742050696@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Fri, 17 Jul 2020 14:39:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r363272 - head/sys/cddl/dev/dtrace/aarch64 X-SVN-Group: head X-SVN-Commit-Author: andrew X-SVN-Commit-Paths: head/sys/cddl/dev/dtrace/aarch64 X-SVN-Commit-Revision: 363272 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Jul 2020 14:39:08 -0000 Author: andrew Date: Fri Jul 17 14:39:07 2020 New Revision: 363272 URL: https://svnweb.freebsd.org/changeset/base/363272 Log: Don't overflow the trap frame when accessing lr or xzr. When emulating a load pair or store pair in dtrace on arm64 we need to copy the data between the stack and trap frame. When the registers are either the link register or the zero register we will access memory past the end of the trap frame as these are encoded as registers 30 and 31 respectively while the array they access only has 30 entries. Fix this by creating 2 helper functions to perform the operation with special cases for these registers. Sponsored by: Innovate UK Modified: head/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c Modified: head/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c ============================================================================== --- head/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c Fri Jul 17 14:17:13 2020 (r363271) +++ head/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c Fri Jul 17 14:39:07 2020 (r363272) @@ -231,6 +231,31 @@ dtrace_probe_error(dtrace_state_t *state, dtrace_epid_ (uintptr_t)which, (uintptr_t)fault, (uintptr_t)fltoffs); } +static void +dtrace_load64(uint64_t *addr, struct trapframe *frame, u_int reg) +{ + + KASSERT(reg <= 31, ("dtrace_load64: Invalid register %u", reg)); + if (reg < nitems(frame->tf_x)) + frame->tf_x[reg] = *addr; + else if (reg == 30) /* lr */ + frame->tf_lr = *addr; + /* Nothing to do for load to xzr */ +} + +static void +dtrace_store64(uint64_t *addr, struct trapframe *frame, u_int reg) +{ + + KASSERT(reg <= 31, ("dtrace_store64: Invalid register %u", reg)); + if (reg < nitems(frame->tf_x)) + *addr = frame->tf_x[reg]; + else if (reg == 30) /* lr */ + *addr = frame->tf_lr; + else if (reg == 31) /* xzr */ + *addr = 0; +} + static int dtrace_invop_start(struct trapframe *frame) { @@ -258,12 +283,12 @@ dtrace_invop_start(struct trapframe *frame) sp -= (~offs & OFFSET_MASK) + 1; else sp += (offs); - *(sp + 0) = frame->tf_x[arg1]; - *(sp + 1) = frame->tf_x[arg2]; + dtrace_store64(sp + 0, frame, arg1); + dtrace_store64(sp + 1, frame, arg2); break; case LDP_64: - frame->tf_x[arg1] = *(sp + 0); - frame->tf_x[arg2] = *(sp + 1); + dtrace_load64(sp + 0, frame, arg1); + dtrace_load64(sp + 1, frame, arg2); if (offs >> (OFFSET_SIZE - 1)) sp -= (~offs & OFFSET_MASK) + 1; else