From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754279AbdGXKNb (ORCPT ); Mon, 24 Jul 2017 06:13:31 -0400 Received: from mail.skyhub.de ([5.9.137.197]:46668 "EHLO mail.skyhub.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751599AbdGXKNZ (ORCPT ); Mon, 24 Jul 2017 06:13:25 -0400 From: Borislav Petkov To: X86 ML Cc: LKML Subject: [PATCH 1/3] x86/microcode/AMD: Free unneeded patch before exit from update_cache() Date: Mon, 24 Jul 2017 12:12:26 +0200 Message-Id: <20170724101228.17326-2-bp@alien8.de> X-Mailer: git-send-email 2.14.0.rc0 In-Reply-To: <20170724101228.17326-1-bp@alien8.de> References: <20170724101228.17326-1-bp@alien8.de> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Shu Wang verify_and_add_patch() allocates memory for a microcode patch and hands it down to be added to the cache of patches. However, if the cache already has the latest patch, the newly allocated one needs to be freed before returning. Do that. This issue has been found by kmemleak: unreferenced object 0xffff88010e780b40 (size 32): comm "bash", pid 860, jiffies 4294690939 (age 29.297s) backtrace: kmemleak_alloc kmem_cache_alloc_trace load_microcode_amd.isra.0 request_microcode_amd reload_store dev_attr_store sysfs_kf_write kernfs_fop_write __vfs_write vfs_write SyS_write do_syscall_64 return_from_SYSCALL_64 0xffffffffffffffff (gdb) list *0xffffffff81050d60 0xffffffff81050d60 is in load_microcode_amd (arch/x86/kernel/cpu/microcode/amd.c:616). which is this: patch = kzalloc(sizeof(*patch), GFP_KERNEL); --> if (!patch) { pr_err("Patch allocation failure.\n"); return -EINVAL; } Signed-off-by: Shu Wang Cc: chuhu@redhat.com Cc: liwang@redhat.com Cc: x86-ml Link: http://lkml.kernel.org/r/1500438083-15996-1-git-send-email-shuwang@redhat.com [ Rewrite commit message. ] Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/microcode/amd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 21b185793c80..c6daec4bdba5 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -400,9 +400,12 @@ static void update_cache(struct ucode_patch *new_patch) list_for_each_entry(p, µcode_cache, plist) { if (p->equiv_cpu == new_patch->equiv_cpu) { - if (p->patch_id >= new_patch->patch_id) + if (p->patch_id >= new_patch->patch_id) { /* we already have the latest patch */ + kfree(new_patch->data); + kfree(new_patch); return; + } list_replace(&p->plist, &new_patch->plist); kfree(p->data); -- 2.14.0.rc0