Received: by 2002:a05:6358:9144:b0:117:f937:c515 with SMTP id r4csp5734181rwr; Mon, 1 May 2023 09:59:27 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5FbJZZxrp/nD0/RZMjBoUfwlAKx/knvHh4WP6K8rNdmTmF7UCF1g+soq8OXTnoZqQH4pkN X-Received: by 2002:a05:6a00:1d23:b0:63b:8cdc:b38f with SMTP id a35-20020a056a001d2300b0063b8cdcb38fmr20036254pfx.5.1682960367447; Mon, 01 May 2023 09:59:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1682960367; cv=none; d=google.com; s=arc-20160816; b=IJPEJ2sbIR19unF9cPj0jPj8rIdfuIm5g2ZoTeXH0/YhSpW2tTTlvEy/EtkkaimlEV CfEXlk9J8wYLJAIAw2B/JJGNJe2sy01kKMLI/+P1rad3XrTFgqZ2SfTARA71Aqe6kF1N bI7SBl04kcj1haRwYIYoN3kU7fKPGvVKZNFbIOGSEmSNbP50TqClPs2IAXiULEiAn7SP JkgWQ9HMQBq6ixVmy4vfMl3kaEA6DGd/0wF2JehBLr6xOaGErA+QLBeOtMUvt9soobFk 3h17fM5Tp46SDiXFkHWRuor61gsMtEgJyTRRr/DvBmrQ4VSH5MsAtu2rfSrvnKWXplpg Qbgw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:dkim-signature; bh=KlR34XlXux9ljlJXPX99aK4k/cmOetFB9Q46atx2T7Y=; b=gHT54jEo7o98FVo68nYFqGTOQuvK7N4nKmGeJBDPDyi+pRVKcCKGT1Muw3uHp1qHPG gpAefN85uaV/mCsn4nSqhwtoJHqxmufapv5ZiGDuMM20FezhxLwPdr1vy5/E0MGssvFJ 0mcXu6Nbn4fiLd41m64qrjDBfaodyoYRi1nXHNi2k4gjvdawuZEH1x4kdugzBNdC6edI J3J5SXS3RFqpF87XzOCE7eklSiod4pqcE/4Z310ZRUZIbjCCjdIeP0qoBqpOAsnKKoU7 nl2KIxwqhax51ozi9a2ihxdRItOmX2b3jj5gwNkMY9RFNLygrWoszxwk2PgCkS3ItuCH ODbQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20221208 header.b=QWt5E67j; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y24-20020aa79438000000b0062bbe792ab7si28364447pfo.191.2023.05.01.09.59.14; Mon, 01 May 2023 09:59:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20221208 header.b=QWt5E67j; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233008AbjEAQ6j (ORCPT + 99 others); Mon, 1 May 2023 12:58:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232447AbjEAQ50 (ORCPT ); Mon, 1 May 2023 12:57:26 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A09B2711 for ; Mon, 1 May 2023 09:55:53 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-54bfd2c7ad6so53027837b3.2 for ; Mon, 01 May 2023 09:55:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1682960143; x=1685552143; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=KlR34XlXux9ljlJXPX99aK4k/cmOetFB9Q46atx2T7Y=; b=QWt5E67jzX3Q9n5FFMEQTPcgcYXDs3S4iywG6hR5j3a3JlBUkYCc4DtOpxxkkjLFnu 4D+SF9vM2W+aSyyk8kJjTG69VNYflbotzNlQqwEogeuQynY5M8r1b7VoJRcfxutnecbL LuU9GuJRo0TkDfrLBSlYcY4SPMYXeI4QMPcJoAM+FNu7Tta0lyhA6wvriGeN5RlC9+S0 iffTz/pkSCC3kF9yyYctejaCym7L71sJ6nP1Y94qsXlQPHEO6LhbQR95ce2BCueglN+Q qfFo6LHwZ424yz+z+s5ncB2VWclW4myqX2EcpXj3e8kJr6XkScT1PFtCKYGoTWUopffl ivjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682960143; x=1685552143; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=KlR34XlXux9ljlJXPX99aK4k/cmOetFB9Q46atx2T7Y=; b=QE6TYRdvbtuuoH+6RNFX05SkGBbqBxhOJa9dF7WAw+/O2bIN/55Y+zqZaLGeCcRwj2 xi6X8zh4FlNVx2V/kP6/kXxzeZf7EEIWlaEg3dLCG6KBj1IjUmgIajSFL7Yj2oL4/NEN 7m1ckDtPAna7D5jjortMYowlJbbTIIreMQiqnLw1lfy+SDhE3goMVD1LnNqtVbBVgKOL WAjGYyLh/rxWZeBSnYoQJrX0Vy6bkbvUSUYnxUy6Dx2gorqz23f6f+z/6odKu8+7QYuc dW5uAo33XPcMhDJcKJ9FFv91rAk6EzIal/McTwZt9u2vAzHnUQ0PwsAyL6B5eZeoyYA9 jBmg== X-Gm-Message-State: AC+VfDwpykJQAyazgGaWwwGD2d7pxvdsB9qMhL3PuH/lOeT6Hi2cHVqV F9LtteLJtzlK6nfNfmTmb8BWMjPLvUQ= X-Received: from surenb-desktop.mtv.corp.google.com ([2620:15c:211:201:6d24:3efd:facc:7ac4]) (user=surenb job=sendgmr) by 2002:a81:b3c8:0:b0:559:e792:4e87 with SMTP id r191-20020a81b3c8000000b00559e7924e87mr4661945ywh.7.1682960142770; Mon, 01 May 2023 09:55:42 -0700 (PDT) Date: Mon, 1 May 2023 09:54:25 -0700 In-Reply-To: <20230501165450.15352-1-surenb@google.com> Mime-Version: 1.0 References: <20230501165450.15352-1-surenb@google.com> X-Mailer: git-send-email 2.40.1.495.gc816e09b53d-goog Message-ID: <20230501165450.15352-16-surenb@google.com> Subject: [PATCH 15/40] lib: prevent module unloading if memory is not freed From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: kent.overstreet@linux.dev, mhocko@suse.com, vbabka@suse.cz, hannes@cmpxchg.org, roman.gushchin@linux.dev, mgorman@suse.de, dave@stgolabs.net, willy@infradead.org, liam.howlett@oracle.com, corbet@lwn.net, void@manifault.com, peterz@infradead.org, juri.lelli@redhat.com, ldufour@linux.ibm.com, catalin.marinas@arm.com, will@kernel.org, arnd@arndb.de, tglx@linutronix.de, mingo@redhat.com, dave.hansen@linux.intel.com, x86@kernel.org, peterx@redhat.com, david@redhat.com, axboe@kernel.dk, mcgrof@kernel.org, masahiroy@kernel.org, nathan@kernel.org, dennis@kernel.org, tj@kernel.org, muchun.song@linux.dev, rppt@kernel.org, paulmck@kernel.org, pasha.tatashin@soleen.com, yosryahmed@google.com, yuzhao@google.com, dhowells@redhat.com, hughd@google.com, andreyknvl@gmail.com, keescook@chromium.org, ndesaulniers@google.com, gregkh@linuxfoundation.org, ebiggers@google.com, ytcoode@gmail.com, vincent.guittot@linaro.org, dietmar.eggemann@arm.com, rostedt@goodmis.org, bsegall@google.com, bristot@redhat.com, vschneid@redhat.com, cl@linux.com, penberg@kernel.org, iamjoonsoo.kim@lge.com, 42.hyeyoo@gmail.com, glider@google.com, elver@google.com, dvyukov@google.com, shakeelb@google.com, songmuchun@bytedance.com, jbaron@akamai.com, rientjes@google.com, minchan@google.com, kaleshsingh@google.com, surenb@google.com, kernel-team@android.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, iommu@lists.linux.dev, linux-arch@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-modules@vger.kernel.org, kasan-dev@googlegroups.com, cgroups@vger.kernel.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Skip freeing module's data section if there are non-zero allocation tags because otherwise, once these allocations are freed, the access to their code tag would cause UAF. Signed-off-by: Suren Baghdasaryan --- include/linux/codetag.h | 6 +++--- kernel/module/main.c | 23 +++++++++++++++-------- lib/codetag.c | 11 ++++++++--- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/include/linux/codetag.h b/include/linux/codetag.h index 386733e89b31..d98e4c8e86f0 100644 --- a/include/linux/codetag.h +++ b/include/linux/codetag.h @@ -44,7 +44,7 @@ struct codetag_type_desc { size_t tag_size; void (*module_load)(struct codetag_type *cttype, struct codetag_module *cmod); - void (*module_unload)(struct codetag_type *cttype, + bool (*module_unload)(struct codetag_type *cttype, struct codetag_module *cmod); }; @@ -74,10 +74,10 @@ codetag_register_type(const struct codetag_type_desc *desc); #ifdef CONFIG_CODE_TAGGING void codetag_load_module(struct module *mod); -void codetag_unload_module(struct module *mod); +bool codetag_unload_module(struct module *mod); #else static inline void codetag_load_module(struct module *mod) {} -static inline void codetag_unload_module(struct module *mod) {} +static inline bool codetag_unload_module(struct module *mod) { return true; } #endif #endif /* _LINUX_CODETAG_H */ diff --git a/kernel/module/main.c b/kernel/module/main.c index 4232e7bff549..9ff56f2bb09d 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -1218,15 +1218,19 @@ static void *module_memory_alloc(unsigned int size, enum mod_mem_type type) return module_alloc(size); } -static void module_memory_free(void *ptr, enum mod_mem_type type) +static void module_memory_free(void *ptr, enum mod_mem_type type, + bool unload_codetags) { + if (!unload_codetags && mod_mem_type_is_core_data(type)) + return; + if (mod_mem_use_vmalloc(type)) vfree(ptr); else module_memfree(ptr); } -static void free_mod_mem(struct module *mod) +static void free_mod_mem(struct module *mod, bool unload_codetags) { for_each_mod_mem_type(type) { struct module_memory *mod_mem = &mod->mem[type]; @@ -1237,20 +1241,23 @@ static void free_mod_mem(struct module *mod) /* Free lock-classes; relies on the preceding sync_rcu(). */ lockdep_free_key_range(mod_mem->base, mod_mem->size); if (mod_mem->size) - module_memory_free(mod_mem->base, type); + module_memory_free(mod_mem->base, type, + unload_codetags); } /* MOD_DATA hosts mod, so free it at last */ lockdep_free_key_range(mod->mem[MOD_DATA].base, mod->mem[MOD_DATA].size); - module_memory_free(mod->mem[MOD_DATA].base, MOD_DATA); + module_memory_free(mod->mem[MOD_DATA].base, MOD_DATA, unload_codetags); } /* Free a module, remove from lists, etc. */ static void free_module(struct module *mod) { + bool unload_codetags; + trace_module_free(mod); - codetag_unload_module(mod); + unload_codetags = codetag_unload_module(mod); mod_sysfs_teardown(mod); /* @@ -1292,7 +1299,7 @@ static void free_module(struct module *mod) kfree(mod->args); percpu_modfree(mod); - free_mod_mem(mod); + free_mod_mem(mod, unload_codetags); } void *__symbol_get(const char *symbol) @@ -2294,7 +2301,7 @@ static int move_module(struct module *mod, struct load_info *info) return 0; out_enomem: for (t--; t >= 0; t--) - module_memory_free(mod->mem[t].base, t); + module_memory_free(mod->mem[t].base, t, true); return ret; } @@ -2424,7 +2431,7 @@ static void module_deallocate(struct module *mod, struct load_info *info) percpu_modfree(mod); module_arch_freeing_init(mod); - free_mod_mem(mod); + free_mod_mem(mod, true); } int __weak module_finalize(const Elf_Ehdr *hdr, diff --git a/lib/codetag.c b/lib/codetag.c index 4ea57fb37346..0ad4ea66c769 100644 --- a/lib/codetag.c +++ b/lib/codetag.c @@ -5,6 +5,7 @@ #include #include #include +#include struct codetag_type { struct list_head link; @@ -219,12 +220,13 @@ void codetag_load_module(struct module *mod) mutex_unlock(&codetag_lock); } -void codetag_unload_module(struct module *mod) +bool codetag_unload_module(struct module *mod) { struct codetag_type *cttype; + bool unload_ok = true; if (!mod) - return; + return true; mutex_lock(&codetag_lock); list_for_each_entry(cttype, &codetag_types, link) { @@ -241,7 +243,8 @@ void codetag_unload_module(struct module *mod) } if (found) { if (cttype->desc.module_unload) - cttype->desc.module_unload(cttype, cmod); + if (!cttype->desc.module_unload(cttype, cmod)) + unload_ok = false; cttype->count -= range_size(cttype, &cmod->range); idr_remove(&cttype->mod_idr, mod_id); @@ -250,4 +253,6 @@ void codetag_unload_module(struct module *mod) up_write(&cttype->mod_lock); } mutex_unlock(&codetag_lock); + + return unload_ok; } -- 2.40.1.495.gc816e09b53d-goog