Received: by 10.223.176.5 with SMTP id f5csp500517wra; Tue, 6 Feb 2018 02:38:17 -0800 (PST) X-Google-Smtp-Source: AH8x227k+sFW8A7Gg83vEFb439KHM5m/7b2Uzkk4iiS2S3mOd0OPaaA2zGCuqD6MOZX/bsOk/juj X-Received: by 2002:a17:902:20e8:: with SMTP id v37-v6mr1967226plg.66.1517913497619; Tue, 06 Feb 2018 02:38:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517913497; cv=none; d=google.com; s=arc-20160816; b=MUkzCqNuJAuztQr8cPicq05+7r6rRLCsuTd+Ik+cTr+CRQ2lZqmSRo5PL8jLf2AcOT oFJy81vbn8UfM2wDWcwg+l56ZdZzS79bAmNZb2LxijUfSH6j0dfQk8jPcx3YFiGi/4wl ecjG5ihQNPW6pFmHu6tFNnCow4NJet7rNCiVcosPKMW/8qUZYAoBQdIdCAFDkRBvVWzo AsR96R4tuW0glfyptwzWZoOqg62XTrGBs3rzvWHjGdJAKmyhiXhT7ZAUkuiIoVBlpTWW 6lnmrbivP9dckMQ0/rjSfPSY6N2ioKaCsu+OzDXDK4StrU22T29eTf44e3mr11NNjtUs mJVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=6/u1G20aczLWoDjmzLzlcb3H9uqTiGr+PMvnCvnpmJQ=; b=IMQq4YNcB1XG3BaUaPyIfRfa9IyEifFijdn1XHUNsBUjvKyMQYwaM8kYAMxAwB9zLE dqH2HOnR0gs3ifZp0nxj9qw+scHIJye8OdlHVr5o0ffpsxa/M3S0JUWFF2rf8Uv/hXcw 5riQA6EnTeijGXN7eRTZkEsRvFaL2OPino4rIXhy0hEkJjPN0NTjZbwPrhPTqAgtZuO3 zhRN5QYG3G7R7zPJR0CeKGO9cN7V76Ft7ng2sWqu4ISkGRq/SNhhFrIa2+ZaREgLgSsw /YHWrlexaGwT6Y6A2UCP+lvcbbw3BRfSYPLYYAMA7BVmieRzVoIpy2xwHyyiwx+II1gI s6gQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1-v6si1440530pld.492.2018.02.06.02.38.03; Tue, 06 Feb 2018 02:38:17 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752932AbeBFKf4 (ORCPT + 99 others); Tue, 6 Feb 2018 05:35:56 -0500 Received: from mx2.suse.de ([195.135.220.15]:59984 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752810AbeBFKew (ORCPT ); Tue, 6 Feb 2018 05:34:52 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id D21E1AD2D; Tue, 6 Feb 2018 10:34:50 +0000 (UTC) From: Petr Mladek To: Jiri Kosina , Josh Poimboeuf , Miroslav Benes Cc: Jason Baron , Joe Lawrence , Jessica Yu , Evgenii Shatokhin , live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, Petr Mladek Subject: [PATCH v7 5/7] livepatch: Support separate list for replaced patches. Date: Tue, 6 Feb 2018 11:34:22 +0100 Message-Id: <20180206103424.10829-6-pmladek@suse.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180206103424.10829-1-pmladek@suse.com> References: <20180206103424.10829-1-pmladek@suse.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jason Baron We are going to add a feature called atomic replace. It will allow to create a patch that would replace all already registered patches. The replaced patches will stay registered because they are typically unregistered by some package uninstall scripts. But we will remove these patches from @klp_patches list to keep the enabled patch on the bottom of the stack. Otherwise, we would need to implement rather complex logic for moving the patches on the stack. Also it would complicate implementation of the atomic replace feature. It is not worth it. As a result, we will have patches that are registered but that are not longer usable. Let's get prepared for this and use a better descriptive name for klp_is_patch_registered() function. Also create separate list for the replaced patches and allow to unregister them. Alternative solution would be to add a flag into struct klp_patch. Note that patch->kobj.state_initialized is not safe because it can be cleared outside klp_mutex. This patch does not change the existing behavior. Signed-off-by: Jason Baron [pmladek@suse.com: Split and renamed klp_is_patch_usable()] Signed-off-by: Petr Mladek Cc: Josh Poimboeuf Cc: Jessica Yu Cc: Jiri Kosina Cc: Miroslav Benes --- kernel/livepatch/core.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index fccb603942f1..11632fe8716a 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -47,6 +47,13 @@ DEFINE_MUTEX(klp_mutex); static LIST_HEAD(klp_patches); +/* + * List of 'replaced' patches that have been replaced by a patch that has the + * 'replace' bit set. When they are added to this list, they are disabled and + * can not be re-enabled, but they can be unregistered(). + */ +LIST_HEAD(klp_replaced_patches); + static struct kobject *klp_root_kobj; static void klp_init_func_list(struct klp_object *obj, struct klp_func *func) @@ -108,17 +115,28 @@ static void klp_find_object_module(struct klp_object *obj) mutex_unlock(&module_mutex); } -static bool klp_is_patch_registered(struct klp_patch *patch) +static bool klp_is_patch_in_list(struct klp_patch *patch, + struct list_head *head) { struct klp_patch *mypatch; - list_for_each_entry(mypatch, &klp_patches, list) + list_for_each_entry(mypatch, head, list) if (mypatch == patch) return true; return false; } +static bool klp_is_patch_usable(struct klp_patch *patch) +{ + return klp_is_patch_in_list(patch, &klp_patches); +} + +static bool klp_is_patch_replaced(struct klp_patch *patch) +{ + return klp_is_patch_in_list(patch, &klp_replaced_patches); +} + static bool klp_initialized(void) { return !!klp_root_kobj; @@ -375,7 +393,7 @@ int klp_disable_patch(struct klp_patch *patch) mutex_lock(&klp_mutex); - if (!klp_is_patch_registered(patch)) { + if (!klp_is_patch_usable(patch)) { ret = -EINVAL; goto err; } @@ -475,7 +493,7 @@ int klp_enable_patch(struct klp_patch *patch) mutex_lock(&klp_mutex); - if (!klp_is_patch_registered(patch)) { + if (!klp_is_patch_usable(patch)) { ret = -EINVAL; goto err; } @@ -516,7 +534,7 @@ static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr, mutex_lock(&klp_mutex); - if (!klp_is_patch_registered(patch)) { + if (!klp_is_patch_usable(patch)) { /* * Module with the patch could either disappear meanwhile or is * not properly initialized yet. @@ -971,7 +989,7 @@ int klp_unregister_patch(struct klp_patch *patch) mutex_lock(&klp_mutex); - if (!klp_is_patch_registered(patch)) { + if (!klp_is_patch_usable(patch) && !klp_is_patch_replaced(patch)) { ret = -EINVAL; goto err; } -- 2.13.6