From patchwork Mon Jan 1 14:03:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 83073 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 46E303858422 for ; Mon, 1 Jan 2024 14:04:15 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pg1-x52e.google.com (mail-pg1-x52e.google.com [IPv6:2607:f8b0:4864:20::52e]) by sourceware.org (Postfix) with ESMTPS id 089B33858D1E for ; Mon, 1 Jan 2024 14:03:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 089B33858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 089B33858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::52e ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704117830; cv=none; b=NTms1xk62rhtW0XgLO4sN1KHGWMq0CMQZl0nSYzJM5TZqt9VPeg+J8zUD/EaPtybWNFZehzgaSaYKZdFpHi9re6PJQ47xL2we87EeT4riHuZdXtFL85dcB1BjtOu1P+JCDTpBywKhmHLsEMwt+AbQ4TWXj8Y3MFCJIRc2iRoDg8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704117830; c=relaxed/simple; bh=J4Fuh2O4RlYqecmAc5LkE1KSEMLDh9TZLaYnPlR6igQ=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=voSQcZ3TaY7wbYg88KomIslm9y6BRVTT1MPg82WelyOeWUv3vOe1ijIEmjyplHGR5ypVupvTFkFAcLDuxfMb44oMAuLxsI8NetrAu8lfk9vslCOhrbKO3yAIsODc+hGchhQ9EDMNKlY5zKR+m4Dhm+ixFUuTl8eMX4SO1LMVB2w= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pg1-x52e.google.com with SMTP id 41be03b00d2f7-5ce07cf1e5dso1599385a12.2 for ; Mon, 01 Jan 2024 06:03:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1704117827; x=1704722627; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=jEFG+tglXGMfHMLide+4Kv6+sXyqMZEpYnSHpJKVgJI=; b=LqRjp1fWpeuhDxeIQ0uxfbLnFJowBtBqQMzfaw3YVEm9M1JXnCHtvDPekz+E2lQ54l UqLeOR2pKElffnb+XGQQ6fNeiwBliaBVJuhTKvKomRF/nep/B1xzO9FJqJ87JqtZu7yE H0hGs5eFE/L7evlD6rbd4mhq24MgQyxN55IYhPYYxLs/7ZOfD5O75GxpL/Z7l3idst0A DQ5I6pjaGEAgAxy+5ycyZvvUarM+7ncizmKmc7pdDBnHEPbhiCt6EoAjj3Xgy8N497vd 1Oh1ZDuRyuq2XEmvbtgfk6cBT+rRoPxn5vmDVNaD0sza8Ag7Ia7m5Oz5WC85H/0LtryO y8lQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704117827; x=1704722627; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=jEFG+tglXGMfHMLide+4Kv6+sXyqMZEpYnSHpJKVgJI=; b=J0MOfP7bIUmVX5wE2UN0vTUbdmfbdp/kjq4pqGUsvvF+5f6jxn4zO3bg7vmQyMb3eA vo1g9tVvkwOsVkdxyf3j0m/pFUqdTcZu0w2GWpKirNMGKpDw0hHS1AUBQrePUPKMPwHw zUaJ5kjrSYVoqPiuxbkv95FZCf9Q8jwH+FEqdwn88j2pBkC2JCIaeYFUgOaSaPPiANJg hzjaGkcwFc+WAPQiyUXBpBchHFC/ekfCjT7KSh0GbyrnLY/2ZXW5rDai4/Is5O3qCrNB nO8NhsMd0ByFk/8lU7isaTZhEY0JR8KSt0trGk4TbU+pYk7yi+o5Bvmzf9fjtAtxF6Kg m/jA== X-Gm-Message-State: AOJu0YypJbwOSnn/Tnatp3vsmkyRGFys14QAJlFUXZdmBYP5raFV83zm wW4TGDpG7mrmep119lxRHh0= X-Google-Smtp-Source: AGHT+IH6COIEVTcxc2BlP4c9izQsazLgWkorxaVjw7LIMvvfPHdzKJTnEWpImIVJFcsQEvlB02K/Rg== X-Received: by 2002:a05:6a00:17a9:b0:6d9:b557:fa05 with SMTP id s41-20020a056a0017a900b006d9b557fa05mr6399221pfg.40.1704117826617; Mon, 01 Jan 2024 06:03:46 -0800 (PST) Received: from gnu-cfl-3.localdomain ([172.56.169.119]) by smtp.gmail.com with ESMTPSA id g5-20020aa78745000000b006d9af8c25easm14507532pfo.84.2024.01.01.06.03.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jan 2024 06:03:45 -0800 (PST) Received: from gnu-cfl-3.. (localhost [IPv6:::1]) by gnu-cfl-3.localdomain (Postfix) with ESMTP id 9BABB740376; Mon, 1 Jan 2024 06:03:44 -0800 (PST) From: "H.J. Lu" To: libc-alpha@sourceware.org Cc: rick.p.edgecombe@intel.com Subject: [PATCH] x86-64/cet: Check the restore token in longjmp Date: Mon, 1 Jan 2024 06:03:44 -0800 Message-ID: <20240101140344.1962815-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Spam-Status: No, score=-3024.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org setcontext and swapcontext put a restore token on the old shadow stack which is used to restore the target shadow stack when switching user contexts. When longjmp from a user context, the target shadow stack can be different from the current shadow stack and INCSSP can't be used to restore the shadow stack pointer to the target shadow stack. Update longjmp to search for a restore token. If found, use the token to restore the shadow stack pointer before using INCSSP to pop the shadow stack. Stop the token search and use INCSSP if the shadow stack entry value is the same as the current shadow stack pointer. It is a user error if there is a shadow stack switch without leaving a restore token on the old shadow stack. --- .../unix/sysv/linux/x86_64/____longjmp_chk.S | 30 ++++++++++++++++++- sysdeps/x86_64/__longjmp.S | 30 ++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S index 1b735bbbb2..855c934218 100644 --- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S @@ -121,9 +121,37 @@ ENTRY(____longjmp_chk) # endif /* Check and adjust the Shadow-Stack-Pointer. */ rdsspq %rax + /* Save the current ssp. */ + movq %rax, %r10 + movq SHADOW_STACK_POINTER_OFFSET(%rdi), %rcx /* And compare it with the saved ssp value. */ - subq SHADOW_STACK_POINTER_OFFSET(%rdi), %rax + subq %rcx, %rax je L(skip_ssp) + +L(find_restore_token_loop): + /* Look for a restore token. */ + movq -8(%rcx), %rbx + andq $-8, %rbx + cmpq %rcx, %rbx + /* Find the restore token. */ + je L(restore_shadow_stack) + + /* Try the next slot. */ + subq $8, %rcx + /* Stop if the current ssp is found. */ + cmpq %rcx, %r10 + je L(no_shadow_stack_token) + jmp L(find_restore_token_loop) + +L(restore_shadow_stack): + /* Restore the target shadow stack. */ + rstorssp -8(%rcx) + /* Save the restore token on the old shadow stack. */ + saveprevssp + rdsspq %rax + subq SHADOW_STACK_POINTER_OFFSET(%rdi), %rax + +L(no_shadow_stack_token): /* Count the number of frames to adjust and adjust it with incssp instruction. The instruction can adjust the ssp by [0..255] value only thus use a loop if diff --git a/sysdeps/x86_64/__longjmp.S b/sysdeps/x86_64/__longjmp.S index 9ac075e0a8..4f449115e6 100644 --- a/sysdeps/x86_64/__longjmp.S +++ b/sysdeps/x86_64/__longjmp.S @@ -63,9 +63,37 @@ ENTRY(__longjmp) /* Check and adjust the Shadow-Stack-Pointer. */ /* Get the current ssp. */ rdsspq %rax + /* Save the current ssp. */ + movq %rax, %r10 /* And compare it with the saved ssp value. */ - subq SHADOW_STACK_POINTER_OFFSET(%rdi), %rax + movq SHADOW_STACK_POINTER_OFFSET(%rdi), %rcx + subq %rcx, %rax je L(skip_ssp) + +L(find_restore_token_loop): + /* Look for a restore token. */ + movq -8(%rcx), %rbx + andq $-8, %rbx + cmpq %rcx, %rbx + /* Find the restore token. */ + je L(restore_shadow_stack) + + /* Try the next slot. */ + subq $8, %rcx + /* Stop if the current ssp is found. */ + cmpq %rcx, %r10 + je L(no_shadow_stack_token) + jmp L(find_restore_token_loop) + +L(restore_shadow_stack): + /* Restore the target shadow stack. */ + rstorssp -8(%rcx) + /* Save the restore token on the old shadow stack. */ + saveprevssp + rdsspq %rax + subq SHADOW_STACK_POINTER_OFFSET(%rdi), %rax + +L(no_shadow_stack_token): /* Count the number of frames to adjust and adjust it with incssp instruction. The instruction can adjust the ssp by [0..255] value only thus use a loop if