From owner-svn-src-head@freebsd.org Tue Apr 24 15:59:40 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1D7FEFAA530; Tue, 24 Apr 2018 15:59:40 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id C3E86686E7; Tue, 24 Apr 2018 15:59:39 +0000 (UTC) (envelope-from kib@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 BEE7E153C2; Tue, 24 Apr 2018 15:59:39 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w3OFxdIS092311; Tue, 24 Apr 2018 15:59:39 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w3OFxd2N092310; Tue, 24 Apr 2018 15:59:39 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201804241559.w3OFxd2N092310@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Tue, 24 Apr 2018 15:59:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r332940 - head/lib/libc/secure X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: head/lib/libc/secure X-SVN-Commit-Revision: 332940 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.25 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: Tue, 24 Apr 2018 15:59:40 -0000 Author: kib Date: Tue Apr 24 15:59:39 2018 New Revision: 332940 URL: https://svnweb.freebsd.org/changeset/base/332940 Log: Carefully update stack guard bytes inside __guard_setup(). This is necessary to make sure that functions that can have stack protection are not used to update the stack guard. If not, the stack guard check would fail when it shouldn't. guard_setup() calls elf_aux_info(), which, in turn, calls memcpy() to update stack_chk_guard. If either elf_aux_info() or memcpy() have stack protection enabled, __stack_chk_guard will be modified before returning from them, causing the stack protection check to fail. This change uses a temporary buffer to delay changing __stack_chk_guard until elf_aux_info() returns. Submitted by: Luis Pires MFC after: 1 week Differential revision: https://reviews.freebsd.org/D15173 Modified: head/lib/libc/secure/stack_protector.c Modified: head/lib/libc/secure/stack_protector.c ============================================================================== --- head/lib/libc/secure/stack_protector.c Tue Apr 24 15:04:07 2018 (r332939) +++ head/lib/libc/secure/stack_protector.c Tue Apr 24 15:59:39 2018 (r332940) @@ -54,15 +54,27 @@ static void __guard_setup(void) { static const int mib[2] = { CTL_KERN, KERN_ARND }; + volatile long tmp_stack_chk_guard[nitems(__stack_chk_guard)]; size_t len; - int error; + int error, idx; if (__stack_chk_guard[0] != 0) return; - error = _elf_aux_info(AT_CANARY, __stack_chk_guard, - sizeof(__stack_chk_guard)); - if (error == 0 && __stack_chk_guard[0] != 0) + /* + * Avoid using functions which might have stack protection + * enabled, to update the __stack_chk_guard. First fetch the + * data into a temporal array, then do manual volatile copy to + * not allow optimizer to call memcpy() behind us. + */ + error = _elf_aux_info(AT_CANARY, (void *)tmp_stack_chk_guard, + sizeof(tmp_stack_chk_guard)); + if (error == 0 && tmp_stack_chk_guard[0] != 0) { + for (idx = 0; idx < nitems(__stack_chk_guard); idx++) { + __stack_chk_guard[idx] = tmp_stack_chk_guard[idx]; + tmp_stack_chk_guard[idx] = 0; + } return; + } len = sizeof(__stack_chk_guard); if (__sysctl(mib, nitems(mib), __stack_chk_guard, &len, NULL, 0) ==