Received: by 10.223.185.116 with SMTP id b49csp4777442wrg; Wed, 7 Mar 2018 00:23:10 -0800 (PST) X-Google-Smtp-Source: AG47ELvLufmrP9cylaf7r4F1khLnHfLibqrb0XbP6FNYUE87Kl6dB19f6O3eC6nKTHnC/0x0gvgi X-Received: by 10.99.172.66 with SMTP id z2mr17022432pgn.273.1520410990481; Wed, 07 Mar 2018 00:23:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520410990; cv=none; d=google.com; s=arc-20160816; b=VLpcWXh6mx0gUUK16aEygWiot5ZqVhtfUVCI+w6vPl4p07Mg8rzSPQ/gIaosO8Tcgs GNEsgjdGk8zQu07PCI6aGLKKbJaFDYv99Fup/el2PapDYJNPha/e5HqkWXGiiMaq/jHj BXlpmERaKxP2FpVrNu64wNAYkUXiWqzD+RtYVA1mGJR9GOPmScdAcYVxR4kFvdPyw77B QYSx8DZF10z45w5VVZ2cHKn5yXbRacVSbv+H8ygCjyXgVKzNQt9Q15vA2Y1V8O1jpWP9 kakB7nRLHixIJak8IaO/6zGEDzIAVvykUV9LGS+z8lhCPLEOCQPC7rtC+5ihAtnaBsSh gyjQ== 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=ttl+sOkqzI25Vv4XYF0entO3z6U3TD8ZiuKrqc14SjY=; b=Ppo+HdTK6tfRnfGJv35ALryyvm0WOEsd0tNtSjZ1YQ/NPEjEiiMXLPpy2J5LeOI222 nfp72n5vqH3g2bE0dhbWvymcH1/jNyqhQCT5JJy7Ub8qPcckiAP1DByzaB9Z3CEv7zL0 DKwPO4Zak0Mb4JNpqp16HKRk8pdxJA+Byp2uwwawk9hitAIeEY81ae2HC/t743vxp5Y3 eef4DKPf2QZnUvD3QPjrRCoKso8lnStNdAzSVV3k+2PZxbtwu83c2yQsFYGBorEZuv5t 9hk09a0wrNVoIOoGm8cN8XrV2kZiekWyW9zJzy0bmvuGyNwvbLcWXV7cafni1qo+OtKQ qLZg== 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 z2-v6si8756408plk.670.2018.03.07.00.22.55; Wed, 07 Mar 2018 00:23:10 -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 S933474AbeCGIVo (ORCPT + 99 others); Wed, 7 Mar 2018 03:21:44 -0500 Received: from mx2.suse.de ([195.135.220.15]:50158 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933278AbeCGIVH (ORCPT ); Wed, 7 Mar 2018 03:21:07 -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 A0468AF93; Wed, 7 Mar 2018 08:21:05 +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 v10 08/10] livepatch: Improve dynamic struct klp_object detection and manipulation Date: Wed, 7 Mar 2018 09:20:37 +0100 Message-Id: <20180307082039.10196-9-pmladek@suse.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180307082039.10196-1-pmladek@suse.com> References: <20180307082039.10196-1-pmladek@suse.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The check for dynamically allocated objects was too optimistic. There might exist livepatches that modify an object only with callbacks. They are statically defined and have "funcs" array empty. A solution would be to check also the callback pointers in klp_is_object_dynamic(). But it still might be error prone. Note that we must avoid calling klp_free_object_dynamic() even for useless structures that were defined statically. Therefore this patch takes a more safe approach. It adds an extra flag into struct klp_object. The type is different from a similar flag on the func level. It is because one object structure might point to func structures of different types. In general, only two states make sense on the object level. This fixed the problem _how_ the structures were freed. But there was also a bug _when_ this happened. For this we added a check to keep statically defined structures until the statically defined function structures are being freed. Signed-off-by: Petr Mladek --- include/linux/livepatch.h | 8 +++++++- kernel/livepatch/core.c | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index ed598d849029..7222b801d63a 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -45,6 +45,11 @@ enum klp_func_type { KLP_FUNC_NOP, /* Dynamically allocated NOP function patch */ }; +enum klp_object_type { + KLP_OBJECT_STATIC = 0, /* Original statically defined structure */ + KLP_OBJECT_DYNAMIC, /* Dynamically allocated structure. */ +}; + /** * struct klp_func - function structure for live patching * @old_name: name of the function to be patched @@ -143,6 +148,7 @@ struct klp_object { struct klp_callbacks callbacks; /* internal */ + enum klp_object_type otype; struct kobject kobj; struct list_head func_list; struct list_head obj_entry; @@ -198,7 +204,7 @@ struct klp_patch { static inline bool klp_is_object_dynamic(struct klp_object *obj) { - return !obj->funcs; + return obj->otype == KLP_OBJECT_DYNAMIC; } static inline bool klp_is_func_dynamic(struct klp_func *func) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 67aa4ec9e087..73ce3f93e0bc 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -743,6 +743,7 @@ static struct klp_object *klp_alloc_object_dynamic(const char *name) return ERR_PTR(-ENOMEM); } } + obj->otype = KLP_OBJECT_DYNAMIC; return obj; } @@ -970,6 +971,15 @@ void klp_free_objects(struct klp_patch *patch, enum klp_func_type ftype) if (!list_empty(&obj->func_list)) continue; + /* + * Keep objects from the original patch initialized until + * the entire patch is being freed. + */ + if (!klp_is_object_dynamic(obj) && + ftype != KLP_FUNC_STATIC && + ftype != KLP_FUNC_ANY) + continue; + /* Avoid freeing the object twice. */ list_del(&obj->obj_entry); -- 2.13.6