From patchwork Fri Sep 20 09:36:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 13808424 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CBDDECF58FF for ; Fri, 20 Sep 2024 09:37:27 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.801078.1211110 (Exim 4.92) (envelope-from ) id 1sra4Y-0000cf-U6; Fri, 20 Sep 2024 09:37:06 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 801078.1211110; Fri, 20 Sep 2024 09:37:06 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1sra4Y-0000cY-RC; Fri, 20 Sep 2024 09:37:06 +0000 Received: by outflank-mailman (input) for mailman id 801078; Fri, 20 Sep 2024 09:37:06 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1sra4Y-0000Rx-6u for xen-devel@lists.xenproject.org; Fri, 20 Sep 2024 09:37:06 +0000 Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [2a00:1450:4864:20::52d]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id e4ed46d4-7733-11ef-99a2-01e77a169b0f; Fri, 20 Sep 2024 11:37:04 +0200 (CEST) Received: by mail-ed1-x52d.google.com with SMTP id 4fb4d7f45d1cf-5c275491c61so2407178a12.0 for ; Fri, 20 Sep 2024 02:37:04 -0700 (PDT) Received: from localhost ([213.195.124.163]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a90612e5731sm825313766b.183.2024.09.20.02.37.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Sep 2024 02:37:02 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: e4ed46d4-7733-11ef-99a2-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1726825023; x=1727429823; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CKm4w8wQOjLh/yBHbsoJsPm7JcAdsfYSU5MaYWb8sVM=; b=YSb87MXLT/kpkbxdwkVMkSQJX1YM+mJSxmQljfqr/5uGn8yW4EWfRkdeNGAQg0HhfX qAKUtMVGkklKFnEmQYH0d/Jw81Zi97YHqzb7PdM4ZVuaPPxxrS3NlvVHuX+T+QUkF/mx q3XwtHTEvbvuH6OG/7DvjG0hXlCKQH+NQjoFE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726825023; x=1727429823; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CKm4w8wQOjLh/yBHbsoJsPm7JcAdsfYSU5MaYWb8sVM=; b=NvjV2zAifnOJf7FIdupFCdhndJQF6PPMIm86FyRIaBPFWVihKty8QZFVCmTvQkVWva meNt5NrHmiYGZOjKIjVb1nzRaU4KimK91G88UVZlDoVF6fuVtV15TJVtpfdFp0Vj65yV lJcv20ZPlGnb6F/1CCU7mthbHua+1fp2VsTunkP7UQ2UalcGRIbQJx2XHUHTuEOHs7T8 ezTqnb0dFDKOfyZknyj4FrEP//osOIvJnCCCne7ZBEZ0lj+Ls5GAyZqcERAzwTVfebsF XfIQ4QyqphrOp35E+rx+ShEP7KeGHnWBdwjs2HU2RObO7wC3Mmd+zCywfqAUzsNATbNj 0xyA== X-Gm-Message-State: AOJu0Yy5cC4T21JSS7i4OfsB0lIVn/Ac172vFoC8yOa4gPIXwlexxPbu 3rF2GwIHalF+Tj/NrYzpvGPhYMoePN1pfhPwKtCJ8CIQfHTaabfT4zdy9qA7fnlaFUVlz4m4Hyk Y X-Google-Smtp-Source: AGHT+IGZN72h0QdBaY0y+Q/o4Q0N3nipJ5FdhNCHKIhHckf6YNhq2OqlAfJrtSkiZmtscsKAecLkdQ== X-Received: by 2002:a17:907:f184:b0:a8d:1284:6de5 with SMTP id a640c23a62f3a-a90d560e199mr175568166b.14.1726825022585; Fri, 20 Sep 2024 02:37:02 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Ross Lagerwall Subject: [PATCH 1/3] xen/livepatch: simplify and unify logic in prepare_payload() Date: Fri, 20 Sep 2024 11:36:53 +0200 Message-ID: <20240920093656.48879-2-roger.pau@citrix.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240920093656.48879-1-roger.pau@citrix.com> References: <20240920093656.48879-1-roger.pau@citrix.com> MIME-Version: 1.0 The following sections: .note.gnu.build-id, .livepatch.xen_depends and .livepatch.depends are mandatory and ensured to be present by check_special_sections() before prepare_payload() is called. Simplify the logic in prepare_payload() by introducing a generic function to parse the sections that contain a buildid. Note the function assumes the buildid related section to always be present. No functional change intended. Signed-off-by: Roger Pau Monné --- xen/common/livepatch.c | 106 ++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 60 deletions(-) diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c index d93a556bcda2..cea47ffe4c84 100644 --- a/xen/common/livepatch.c +++ b/xen/common/livepatch.c @@ -647,15 +647,37 @@ static inline int livepatch_check_expectations(const struct payload *payload) nhooks = __sec->sec->sh_size / sizeof(*hook); \ } while (0) +static int fetch_buildid(const struct livepatch_elf_sec *sec, + struct livepatch_build_id *id) +{ + const Elf_Note *n = sec->load_addr; + int rc; + + ASSERT(sec); + + if ( sec->sec->sh_size <= sizeof(*n) ) + return -EINVAL; + + rc = xen_build_id_check(n, sec->sec->sh_size, &id->p, &id->len); + if ( rc ) + return rc; + + if ( !id->len || !id->p ) + return -EINVAL; + + return 0; +} + static int prepare_payload(struct payload *payload, struct livepatch_elf *elf) { const struct livepatch_elf_sec *sec; + const struct payload *data; unsigned int i; struct livepatch_func *funcs; struct livepatch_func *f; struct virtual_region *region; - const Elf_Note *n; + int rc; sec = livepatch_elf_sec_by_name(elf, ELF_LIVEPATCH_FUNC); if ( sec ) @@ -673,8 +695,6 @@ static int prepare_payload(struct payload *payload, for ( i = 0; i < payload->nfuncs; i++ ) { - int rc; - f = &(funcs[i]); if ( f->version != LIVEPATCH_PAYLOAD_VERSION ) @@ -717,69 +737,35 @@ static int prepare_payload(struct payload *payload, LIVEPATCH_ASSIGN_SINGLE_HOOK(elf, payload->hooks.revert.action, ELF_LIVEPATCH_REVERT_HOOK); LIVEPATCH_ASSIGN_SINGLE_HOOK(elf, payload->hooks.revert.post, ELF_LIVEPATCH_POSTREVERT_HOOK); - sec = livepatch_elf_sec_by_name(elf, ELF_BUILD_ID_NOTE); - if ( sec ) - { - const struct payload *data; - - n = sec->load_addr; - - if ( sec->sec->sh_size <= sizeof(*n) ) - return -EINVAL; - - if ( xen_build_id_check(n, sec->sec->sh_size, - &payload->id.p, &payload->id.len) ) - return -EINVAL; - - if ( !payload->id.len || !payload->id.p ) - return -EINVAL; + rc = fetch_buildid(livepatch_elf_sec_by_name(elf, ELF_BUILD_ID_NOTE), + &payload->id); + if ( rc ) + return rc; - /* Make sure it is not a duplicate. */ - list_for_each_entry ( data, &payload_list, list ) + /* Make sure it is not a duplicate. */ + list_for_each_entry ( data, &payload_list, list ) + { + /* No way _this_ payload is on the list. */ + ASSERT(data != payload); + if ( data->id.len == payload->id.len && + !memcmp(data->id.p, payload->id.p, data->id.len) ) { - /* No way _this_ payload is on the list. */ - ASSERT(data != payload); - if ( data->id.len == payload->id.len && - !memcmp(data->id.p, payload->id.p, data->id.len) ) - { - dprintk(XENLOG_DEBUG, LIVEPATCH "%s: Already loaded as %s!\n", - elf->name, data->name); - return -EEXIST; - } + dprintk(XENLOG_DEBUG, LIVEPATCH "%s: Already loaded as %s!\n", + elf->name, data->name); + return -EEXIST; } } - sec = livepatch_elf_sec_by_name(elf, ELF_LIVEPATCH_DEPENDS); - if ( sec ) - { - n = sec->load_addr; - - if ( sec->sec->sh_size <= sizeof(*n) ) - return -EINVAL; - - if ( xen_build_id_check(n, sec->sec->sh_size, - &payload->dep.p, &payload->dep.len) ) - return -EINVAL; - - if ( !payload->dep.len || !payload->dep.p ) - return -EINVAL; - } - - sec = livepatch_elf_sec_by_name(elf, ELF_LIVEPATCH_XEN_DEPENDS); - if ( sec ) - { - n = sec->load_addr; - - if ( sec->sec->sh_size <= sizeof(*n) ) - return -EINVAL; - - if ( xen_build_id_check(n, sec->sec->sh_size, - &payload->xen_dep.p, &payload->xen_dep.len) ) - return -EINVAL; + rc = fetch_buildid(livepatch_elf_sec_by_name(elf, ELF_LIVEPATCH_DEPENDS), + &payload->dep); + if ( rc ) + return rc; - if ( !payload->xen_dep.len || !payload->xen_dep.p ) - return -EINVAL; - } + rc = fetch_buildid(livepatch_elf_sec_by_name(elf, + ELF_LIVEPATCH_XEN_DEPENDS), + &payload->xen_dep); + if ( rc ) + return rc; /* Setup the virtual region with proper data. */ region = &payload->region; From patchwork Fri Sep 20 09:36:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 13808422 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 91DC3CF58FA for ; Fri, 20 Sep 2024 09:37:26 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.801080.1211129 (Exim 4.92) (envelope-from ) id 1sra4b-00016A-FY; Fri, 20 Sep 2024 09:37:09 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 801080.1211129; Fri, 20 Sep 2024 09:37:09 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1sra4b-000161-Co; Fri, 20 Sep 2024 09:37:09 +0000 Received: by outflank-mailman (input) for mailman id 801080; Fri, 20 Sep 2024 09:37:07 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1sra4Z-0000OC-LW for xen-devel@lists.xenproject.org; Fri, 20 Sep 2024 09:37:07 +0000 Received: from mail-lf1-x129.google.com (mail-lf1-x129.google.com [2a00:1450:4864:20::129]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id e6d5e6e2-7733-11ef-a0b8-8be0dac302b0; Fri, 20 Sep 2024 11:37:07 +0200 (CEST) Received: by mail-lf1-x129.google.com with SMTP id 2adb3069b0e04-5365aa568ceso2249042e87.0 for ; Fri, 20 Sep 2024 02:37:07 -0700 (PDT) Received: from localhost ([213.195.124.163]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a90612b38c8sm818163366b.103.2024.09.20.02.37.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Sep 2024 02:37:05 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: e6d5e6e2-7733-11ef-a0b8-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1726825026; x=1727429826; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1N4dCytGEzetjbXwIG17gkrBm9HHnJ0smkpdbjRf43Q=; b=apagAd7c7Wg+RAKFdXbBLHh4Zb2iNPASR2DAs/sfvFUQZYzi2K96LJygLj4KGvbON1 /3kj9vHnZtr8auqUQN4DEMiWxv7bw/S7kljT45kfb/gAjZUw3jY7DSIPrLdiCZAltwMz MvAf3+eiR/8/hcGEn6nfViPnas0m7hDKfbBx4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726825026; x=1727429826; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1N4dCytGEzetjbXwIG17gkrBm9HHnJ0smkpdbjRf43Q=; b=ma9IV+AvXHLy9rel65YIarkx+tsk85IjHJw8CCppIFV9l3fOCPxdsKTRD1lSqWY0B1 1ym8RX/XADj+qmK5shCc7WDJmxjNYiizUPkAHWpeo2cxp6jxEsH1IxI9XhBifmH1EKql mI1xqxcGwCBlEmA1cJsZYzvTV6DkNfAsk9Fvf3+7e+XuFDrLOjF1eE3Gl/49dy0wKeZL 1blDlGK1WDp3q4NLnb431qLOvmSHmTQw+39gD6OVaGFk5C59eOqtDqJdZUcuvQ+AEBkW couOzR56AdwZ2pLk2Q+pCBD2WLnnJjhsaDnzn060NCzJXXKaKHR0YjuSHpJSPKDbfjoT 6d7w== X-Gm-Message-State: AOJu0YxeYtYXRK3LXm5sn6WpsNzB0bTTVwu1J/32pAS5F9kFcJKiyfwV BWiwIqTWsz4/8fVGKpTaZ9MZxxanmLFvoChoBiAkAYC81VGuNewF+cSzjQYBVOzVeQs8C91zjA+ E X-Google-Smtp-Source: AGHT+IHhvvIt+KgvTO9l5R4mcB4EbpcBhhw6Mx5U5GtLiA1CWcOQ0GlWTILJbgfX9YNYLOncwU8dNQ== X-Received: by 2002:a05:6512:39c4:b0:536:a4f1:d214 with SMTP id 2adb3069b0e04-536ac2e705bmr1758118e87.19.1726825025701; Fri, 20 Sep 2024 02:37:05 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Ross Lagerwall Subject: [PATCH 2/3] xen/livepatch: do build-id check earlier Date: Fri, 20 Sep 2024 11:36:55 +0200 Message-ID: <20240920093656.48879-4-roger.pau@citrix.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240920093656.48879-1-roger.pau@citrix.com> References: <20240920093656.48879-1-roger.pau@citrix.com> MIME-Version: 1.0 The check against the expected Xen build ID should be done ahead of attempting to apply the alternatives contained in the livepatch. If the CPUID in the alternatives patching data is out of the scope of the running Xen featureset the BUG() in _apply_alternatives() will trigger thus bringing the system down. Note the layout of struct alt_instr could also change between versions. It's also possible for struct exception_table_entry to have changed format, hence possibly leading to other errors. Move the Xen build ID check to be done ahead of any processing of the livepatch payload sections. Signed-off-by: Roger Pau Monné --- xen/common/livepatch.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c index 8043954ad0fc..a20f9fb2294d 100644 --- a/xen/common/livepatch.c +++ b/xen/common/livepatch.c @@ -765,6 +765,11 @@ static int prepare_payload(struct payload *payload, if ( rc ) return rc; + /* Perform the Xen build-id check ahead of doing any more processing. */ + rc = xen_build_id_dep(payload); + if ( rc ) + return rc; + /* Setup the virtual region with proper data. */ region = &payload->region; @@ -1097,10 +1102,6 @@ static int load_payload_data(struct payload *payload, void *raw, size_t len) if ( rc ) goto out; - rc = xen_build_id_dep(payload); - if ( rc ) - goto out; - rc = build_symbol_table(payload, &elf); if ( rc ) goto out; From patchwork Fri Sep 20 09:36:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 13808423 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 38F4ECF58F9 for ; Fri, 20 Sep 2024 09:37:27 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.801081.1211140 (Exim 4.92) (envelope-from ) id 1sra4c-0001Ll-NH; Fri, 20 Sep 2024 09:37:10 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 801081.1211140; Fri, 20 Sep 2024 09:37:10 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1sra4c-0001La-JN; Fri, 20 Sep 2024 09:37:10 +0000 Received: by outflank-mailman (input) for mailman id 801081; Fri, 20 Sep 2024 09:37:09 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1sra4b-0000OC-F2 for xen-devel@lists.xenproject.org; Fri, 20 Sep 2024 09:37:09 +0000 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [2a00:1450:4864:20::635]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id e7a76c00-7733-11ef-a0b8-8be0dac302b0; Fri, 20 Sep 2024 11:37:08 +0200 (CEST) Received: by mail-ej1-x635.google.com with SMTP id a640c23a62f3a-a8d29b7edc2so225329366b.1 for ; Fri, 20 Sep 2024 02:37:08 -0700 (PDT) Received: from localhost ([213.195.124.163]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a90611164d0sm821123566b.91.2024.09.20.02.37.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Sep 2024 02:37:06 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: e7a76c00-7733-11ef-a0b8-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1726825027; x=1727429827; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=X9pg/kWT3bx52nQ7VZiYhabzSdBQ5rhnkc3RGrpKCwI=; b=XWNnCq2DsvrsQTVnIoEzBF0SKgSVyCF4/XkSzDhU1/EI1WDMqZ6ho2Q5FP0df5O3RG QPl50R9LM4ex1UHiHbC+jK/xMrfojZHqr9z1lN6TmIGQg/Uq3AOTDy17mjnad059WYNj fdytylOv/LtyEpfo7lbM6TGLZ8FFhQK82CNsg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726825027; x=1727429827; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=X9pg/kWT3bx52nQ7VZiYhabzSdBQ5rhnkc3RGrpKCwI=; b=L06zppi+aF9+GqvF+xtxNu+cQ9cAfA+IQ8tDGS9+oO5n83wrbL/6jaO9NeHZxUoFJZ BfRy9ajxpOf4OpmnxbeRaPrCNeZJb0cKY7qjqtS3A5XLtgDumTvfoKrLooRQL4z+RqL4 C8hHpxfdlyImvFBdjJkPc9LE4XusDYSlZUF+sg1Mja9qcgpp7xdxAQ9x86AnRdqH4atO xvwwm/Eo2LTsS8XhhwazZH/k2h++3f4ex0RHNhWPFFtqRQkxS0hzSv4HiVm1KO/8J1ls ZKDfP+E7LuZMk1hlW6W7ZemgsQVZjR+/k+qGfcMx5UWLnjnwF8+PGZFlcogi0+/vNHTD Onmg== X-Gm-Message-State: AOJu0Ywt3oElqer+ofiyEqh8pn7iS5ao0VT2VP3GLFOWBNmDwNV7SNNy A5qE9nefKoxTPwul6fx34xaXOUaGR7gxzAI+ZQKdZfaztZZD//Cg1Qv5FA+B+QHsF5V3MT316C0 u X-Google-Smtp-Source: AGHT+IG1bK95YeuNqzX+GZWxQqWHomjbSmSdaMNmK7x/G+C1kfv489w4B5E+dP+diNs0DECA4daBVg== X-Received: by 2002:a17:907:7da1:b0:a86:9ba1:639e with SMTP id a640c23a62f3a-a90d5614d1bmr153475866b.26.1726825027291; Fri, 20 Sep 2024 02:37:07 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Jan Beulich , Andrew Cooper , Ross Lagerwall , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [PATCH 3/3] x86/alternatives: relax apply BUGs during runtime Date: Fri, 20 Sep 2024 11:36:56 +0200 Message-ID: <20240920093656.48879-5-roger.pau@citrix.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240920093656.48879-1-roger.pau@citrix.com> References: <20240920093656.48879-1-roger.pau@citrix.com> MIME-Version: 1.0 alternatives is used both at boot time, and when loading livepatch payloads. While for the former it makes sense to panic, it's not useful for the later, as for livepatches it's possible to fail to load the livepatch if alternatives cannot be resolved and continue operating normally. Relax the BUGs in _apply_alternatives() to instead return an error code if alternatives are applied after boot. Add a dummy livepatch test so the new logic can be assessed, with the change applied the loading now fails with: alt table ffff82d040602024 -> ffff82d040602032 livepatch: xen_alternatives_fail applying alternatives failed: -22 Signed-off-by: Roger Pau Monné --- xen/arch/x86/alternative.c | 29 ++++++++++++++++------ xen/arch/x86/include/asm/alternative.h | 3 ++- xen/common/livepatch.c | 10 +++++++- xen/test/livepatch/Makefile | 5 ++++ xen/test/livepatch/xen_alternatives_fail.c | 29 ++++++++++++++++++++++ 5 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 xen/test/livepatch/xen_alternatives_fail.c diff --git a/xen/arch/x86/alternative.c b/xen/arch/x86/alternative.c index 7824053c9d33..c0912cb12ea5 100644 --- a/xen/arch/x86/alternative.c +++ b/xen/arch/x86/alternative.c @@ -174,10 +174,13 @@ extern void *const __initdata_cf_clobber_end[]; * The caller will set the "force" argument to true for the final * invocation, such that no CALLs/JMPs to NULL pointers will be left * around. See also the further comment below. + * + * Note the function cannot fail if system_state < SYS_STATE_active, it would + * panic instead. The return value is only meaningful for runtime usage. */ -static void init_or_livepatch _apply_alternatives(struct alt_instr *start, - struct alt_instr *end, - bool force) +static int init_or_livepatch _apply_alternatives(struct alt_instr *start, + struct alt_instr *end, + bool force) { struct alt_instr *a, *base; @@ -198,9 +201,17 @@ static void init_or_livepatch _apply_alternatives(struct alt_instr *start, uint8_t buf[MAX_PATCH_LEN]; unsigned int total_len = a->orig_len + a->pad_len; - BUG_ON(a->repl_len > total_len); - BUG_ON(total_len > sizeof(buf)); - BUG_ON(a->cpuid >= NCAPINTS * 32); +#define BUG_ON_BOOT(cond) \ + if ( system_state < SYS_STATE_active ) \ + BUG_ON(cond); \ + else if ( cond ) \ + return -EINVAL; + + BUG_ON_BOOT(a->repl_len > total_len); + BUG_ON_BOOT(total_len > sizeof(buf)); + BUG_ON_BOOT(a->cpuid >= NCAPINTS * 32); + +#undef BUG_ON_BOOT /* * Detect sequences of alt_instr's patching the same origin site, and @@ -356,12 +367,14 @@ static void init_or_livepatch _apply_alternatives(struct alt_instr *start, printk("altcall: Optimised away %u endbr64 instructions\n", clobbered); } + + return 0; } #ifdef CONFIG_LIVEPATCH -void apply_alternatives(struct alt_instr *start, struct alt_instr *end) +int apply_alternatives(struct alt_instr *start, struct alt_instr *end) { - _apply_alternatives(start, end, true); + return _apply_alternatives(start, end, true); } #endif diff --git a/xen/arch/x86/include/asm/alternative.h b/xen/arch/x86/include/asm/alternative.h index a86eadfaecbd..83940e1849c6 100644 --- a/xen/arch/x86/include/asm/alternative.h +++ b/xen/arch/x86/include/asm/alternative.h @@ -24,7 +24,8 @@ struct __packed alt_instr { extern void add_nops(void *insns, unsigned int len); /* Similar to alternative_instructions except it can be run with IRQs enabled. */ -extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end); +extern int __must_check apply_alternatives(struct alt_instr *start, + struct alt_instr *end); extern void alternative_instructions(void); extern void alternative_branches(void); diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c index 3e4fce036a1c..1b3a9dda52a7 100644 --- a/xen/common/livepatch.c +++ b/xen/common/livepatch.c @@ -882,7 +882,15 @@ static int prepare_payload(struct payload *payload, return -EINVAL; } } - apply_alternatives(start, end); + + rc = apply_alternatives(start, end); + if ( rc ) + { + printk(XENLOG_ERR LIVEPATCH "%s applying alternatives failed: %d\n", + elf->name, rc); + return rc; + } + alt_done:; #else printk(XENLOG_ERR LIVEPATCH "%s: We don't support alternative patching\n", diff --git a/xen/test/livepatch/Makefile b/xen/test/livepatch/Makefile index 4caa9e24324e..c29529b50338 100644 --- a/xen/test/livepatch/Makefile +++ b/xen/test/livepatch/Makefile @@ -125,6 +125,11 @@ $(obj)/xen_action_hooks_norevert.o: $(obj)/config.h extra-y += xen_action_hooks_norevert.livepatch xen_action_hooks_norevert-objs := xen_action_hooks_norevert.o xen_hello_world_func.o note.o xen_note.o +$(obj)/xen_alternatives_fail.o: $(obj)/config.h + +extra-y += xen_alternatives_fail.livepatch +xen_alternatives_fail-objs := xen_alternatives_fail.o note.o xen_note.o + EXPECT_BYTES_COUNT := 8 CODE_GET_EXPECT=$(shell $(OBJDUMP) -d --insn-width=1 $(1) | sed -n -e '/<'$(2)'>:$$/,/^$$/ p' | tail -n +2 | head -n $(EXPECT_BYTES_COUNT) | awk '{$$0=$$2; printf "%s", substr($$0,length-1)}' | sed 's/.\{2\}/0x&,/g' | sed 's/^/{/;s/,$$/}/g') $(obj)/expect_config.h: $(objtree)/xen-syms diff --git a/xen/test/livepatch/xen_alternatives_fail.c b/xen/test/livepatch/xen_alternatives_fail.c new file mode 100644 index 000000000000..01d289095a31 --- /dev/null +++ b/xen/test/livepatch/xen_alternatives_fail.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Cloud Software Group. + * + */ + +#include "config.h" +#include +#include + +#include +#include + +void test_alternatives(void) +{ + alternative("", "", NCAPINTS * 32); +} + +/* Set a hook so the loading logic in Xen don't consider the payload empty. */ +LIVEPATCH_LOAD_HOOK(test_alternatives); + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */