[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2] livepatch: account for patch offset when applying NOP patch


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Wed, 30 Mar 2022 13:05:31 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=23PpZPsq+frtG4bi3DwFGXPe3nlscKwcNzLG0s1a+aE=; b=Js3uM6e6UeQq1jbxHcFKwDMUkL7Zdf5ceM7svXLt5VgAKwC3FqAsQWC96m8cJIyZ5X/rJ1HCRbZvTANJ54Pf5CzJOGXrvXGgilO6oWpHbrF96hmanY8LnrnawiSHC1FApHlB1qC2Lp6/BGgm9ePaS3Z5hgEkY9lhDvEaSIlNWAgbov9XYZ83RNUSgEcVpCA01i1JvhAJFEdJgnJQwHqUEd7yS+obEsBF3NxocwcmDmyTKUAR0KdGwzZvSRnFMfamvY1+Up1aO+MoMSMouBL9i9caqmojFHTAwAIChjMVIfKibH0hzf3uSlPCJ0iRHe3eDfwyCDvZwAHMFjGxJmcubw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eg9buBnh0JVcfyGk8SbV17CWf3+NlaZrZc5jjzlzMkglu93W68magmkl38vH0xWgH6D4fYK5X/+DpE/+4+nX5xrMd47aCOk0dAzGDPEi0AVOLpBy1FmIkSf+1dk5rkyor04G/j9hrpvnggH1Ywjs95xnI6pfPXEBTbAiJHi0ehDlE7uGIJLOxKwfWOmZSKhpUoFISgxFg6iRlXoaOijNHF31i3uJrE7p/i2UZ2li3WZZnYHc85LyvVJY17m4EwY2gErMnRjpJL3hp6YH5sMGQvhBHrdZy/fF260UwbIoaK5mJPlUZi7rqfBTirhiBCoHpDKKep7iDHrg0vfxbsXQVg==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>, Konrad Wilk <konrad.wilk@xxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Bjoern Doebel <doebel@xxxxxxxxx>
  • Delivery-date: Wed, 30 Mar 2022 11:05:40 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

While not triggered by the trivial xen_nop in-tree patch on
staging/master, that patch exposes a problem on the stable trees, where
all functions have ENDBR inserted. When NOP-ing out a range, we need to
account for this. Handle this right in livepatch_insn_len().

This requires livepatch_insn_len() to be called _after_ ->patch_offset
was set. Note however that the earlier call cannot be deleted. In fact
its result should have been used to guard the is_endbr64() /
is_endbr64_poison() invocations - add the missing check now. While
making that adjustment, also use the local variable "old_ptr"
consistently.

Fixes: 6974c75180f1 ("xen/x86: Livepatch: support patching CET-enhanced 
functions")
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
v2: Re-issue livepatch_insn_len(). Fix buffer overrun.
---
Only build tested, as I don't have a live patching environment available.

For Arm this assumes that the patch_offset field starts out as zero; I
think we can make such an assumption, yet otoh on x86 explicit
initialization was added by the cited commit.

Note that the other use of is_endbr64() / is_endbr64_poison() in
arch_livepatch_verify_func() would need the extra check only for
cosmetic reasons, because ARCH_PATCH_INSN_SIZE > ENDBR64_LEN (5 > 4).
Hence I'm not altering the code there.

--- a/xen/arch/x86/livepatch.c
+++ b/xen/arch/x86/livepatch.c
@@ -157,9 +157,15 @@ void noinline arch_livepatch_apply(struc
      * loaded hotpatch (to avoid racing against other fixups adding/removing
      * ENDBR64 or similar instructions).
      */
-    if ( is_endbr64(old_ptr) || is_endbr64_poison(func->old_addr) )
+    if ( len >= ENDBR64_LEN &&
+         (is_endbr64(old_ptr) || is_endbr64_poison(old_ptr)) )
         func->patch_offset += ENDBR64_LEN;
 
+    /* This call must be re-issued once ->patch_offset has its final value. */
+    len = livepatch_insn_len(func);
+    if ( !len )
+        return;
+
     memcpy(func->opaque, old_ptr + func->patch_offset, len);
     if ( func->new_addr )
     {
--- a/xen/include/xen/livepatch.h
+++ b/xen/include/xen/livepatch.h
@@ -90,7 +90,7 @@ static inline
 unsigned int livepatch_insn_len(const struct livepatch_func *func)
 {
     if ( !func->new_addr )
-        return func->new_size;
+        return func->new_size - func->patch_offset;
 
     return ARCH_PATCH_INSN_SIZE;
 }




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.