Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp1303611imu; Tue, 20 Nov 2018 15:23:55 -0800 (PST) X-Google-Smtp-Source: AFSGD/VCAnrZTg6JP3DB0zmr0sH6RlAuhoeNbQBNQlBOMvxElLpy2+MViuS8/XtYAW7maCHtzhS3 X-Received: by 2002:a17:902:bd92:: with SMTP id q18mr4304752pls.167.1542756235017; Tue, 20 Nov 2018 15:23:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542756234; cv=none; d=google.com; s=arc-20160816; b=MhhK1RzhRdiEM265wNMtL+pYykX8A3i7le0lWfkExubR0TmfIQ+Il+EsmImDMMDDr/ h/DjOP2QCFdHYwG5hC2dlccupFNgVpJGTuXgog82pIB54XVH71Wiaq7z+8qDqPWythks qdCOrYn57PT3wLNMs7zvtgDbGZv+3KQcQFvp8bOAG+8CG8gWNXFxQIBQyg7Abx1USUVg ZzvOZHyN9cXzKZC2gN426paxcy3ewMlX0Tw+/CG8AEO/bErh/6Eog2jtMi1cYVh2oovk 02mLR4mHplOMZN+pPq+/VxcaY3I+i+JCL8vVJpnIlr4Nqdm/hk2AodPeaiROpNfWe10E rCZQ== 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; bh=+mSO61ChHconaFDfZPZTkzvJ9XsnfWKihWo8ZoXaF20=; b=YgggRl94MpT7j3kFhQQYTF6tR2jmYJQh3GsCYGtX5f/PIfWo1EEB45zCDiWmaGDSD0 8RtPCJHG5jj35GqgZf4B6Dl9rMqzE6By60t9VL69zWlYRztCsEUf1yeFeBGrWzum9DT6 S/anUa70YSCbCVHDCB7CczgU/vJ3pWlMk0qMO1sRIyK3omo6uZX6JXXQcg6I9i3oRgc8 ye6EzLlxeIYef9NINJlqwroIBb7kHaFJ+F/KAllxaOj3xZz5qSG3n/0DOtEh7yKqEie2 4Fq/NNMQj51AiCqRya+7Pwzdguczeu/PJGw09r1Y91CSGxsQEyc1i1GfvKLQus3xZ5Ej qdjg== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d18si43769872pgm.212.2018.11.20.15.23.40; Tue, 20 Nov 2018 15:23:54 -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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726632AbeKUJyG (ORCPT + 99 others); Wed, 21 Nov 2018 04:54:06 -0500 Received: from mga11.intel.com ([192.55.52.93]:6936 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725900AbeKUJxt (ORCPT ); Wed, 21 Nov 2018 04:53:49 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Nov 2018 15:22:05 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,258,1539673200"; d="scan'208";a="251330796" Received: from rpedgeco-desk5.jf.intel.com ([10.54.75.128]) by orsmga004.jf.intel.com with ESMTP; 20 Nov 2018 15:22:05 -0800 From: Rick Edgecombe To: jeyu@kernel.org, akpm@linux-foundation.org, willy@infradead.org, tglx@linutronix.de, mingo@redhat.com, hpa@zytor.com, x86@kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, kernel-hardening@lists.openwall.com, daniel@iogearbox.net, jannh@google.com, keescook@chromium.org Cc: kristen@linux.intel.com, dave.hansen@intel.com, arjan@linux.intel.com, Rick Edgecombe Subject: [PATCH v9 RESEND 3/4] vmalloc: Add debugfs modfraginfo Date: Tue, 20 Nov 2018 15:23:11 -0800 Message-Id: <20181120232312.30037-4-rick.p.edgecombe@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181120232312.30037-1-rick.p.edgecombe@intel.com> References: <20181120232312.30037-1-rick.p.edgecombe@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add debugfs file "modfraginfo" for providing info on module space fragmentation. This can be used for determining if loadable module randomization is causing any problems for extreme module loading situations, like huge numbers of modules or extremely large modules. Sample output when KASLR is enabled and X86_64 is configured: Largest free space: 897912 kB Total free space: 1025424 kB Allocations in backup area: 0 Sample output when just X86_64: Largest free space: 897912 kB Total free space: 1025424 kB Signed-off-by: Rick Edgecombe Reviewed-by: Kees Cook --- mm/vmalloc.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index b8b34d319c85..63894cb50873 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,12 @@ #include #include +#ifdef CONFIG_X86 +#include +#include +#include +#endif + #include "internal.h" struct vfree_deferred { @@ -2415,7 +2422,6 @@ void free_vm_area(struct vm_struct *area) } EXPORT_SYMBOL_GPL(free_vm_area); -#ifdef CONFIG_SMP static struct vmap_area *node_to_va(struct rb_node *n) { return rb_entry_safe(n, struct vmap_area, rb_node); @@ -2463,6 +2469,7 @@ static bool pvm_find_next_prev(unsigned long end, return true; } +#ifdef CONFIG_SMP /** * pvm_determine_end - find the highest aligned address between two vmap_areas * @pnext: in/out arg for the next vmap_area @@ -2804,7 +2811,96 @@ static int __init proc_vmalloc_init(void) proc_create_seq("vmallocinfo", 0400, NULL, &vmalloc_op); return 0; } -module_init(proc_vmalloc_init); +#elif defined(CONFIG_DEBUG_FS) +static int __init proc_vmalloc_init(void) +{ + return 0; +} +#endif + +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_RANDOMIZE_FINE_MODULE) +static inline unsigned long is_in_backup(unsigned long addr) +{ + return addr >= MODULES_VADDR + get_modules_rand_len(); +} + +static int modulefraginfo_debug_show(struct seq_file *m, void *v) +{ + unsigned long last_end = MODULES_VADDR; + unsigned long total_free = 0; + unsigned long largest_free = 0; + unsigned long backup_cnt = 0; + unsigned long gap; + struct vmap_area *prev, *cur = NULL; + + spin_lock(&vmap_area_lock); + + if (!pvm_find_next_prev(MODULES_VADDR, &cur, &prev) || !cur) + goto done; + + for (; cur->va_end <= MODULES_END; cur = list_next_entry(cur, list)) { + /* Don't count areas that are marked to be lazily freed */ + if (!(cur->flags & VM_LAZY_FREE)) { + if (kaslr_mod_randomize_each_module()) + backup_cnt += is_in_backup(cur->va_start); + gap = cur->va_start - last_end; + if (gap > largest_free) + largest_free = gap; + total_free += gap; + last_end = cur->va_end; + } + + if (list_is_last(&cur->list, &vmap_area_list)) + break; + } + +done: + gap = (MODULES_END - last_end); + if (gap > largest_free) + largest_free = gap; + total_free += gap; + spin_unlock(&vmap_area_lock); + + seq_printf(m, "\tLargest free space:\t%lu kB\n", largest_free / 1024); + seq_printf(m, "\t Total free space:\t%lu kB\n", total_free / 1024); + + if (kaslr_mod_randomize_each_module()) + seq_printf(m, "Allocations in backup area:\t%lu\n", backup_cnt); + + return 0; +} + +static int proc_module_frag_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, modulefraginfo_debug_show, NULL); +} + +static const struct file_operations debug_module_frag_operations = { + .open = proc_module_frag_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void __init debug_modfrag_init(void) +{ + debugfs_create_file("modfraginfo", 0400, NULL, NULL, + &debug_module_frag_operations); +} +#elif defined(CONFIG_DEBUG_FS) || defined(CONFIG_PROC_FS) +static void __init debug_modfrag_init(void) +{ +} #endif +#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_PROC_FS) +static int __init info_vmalloc_init(void) +{ + proc_vmalloc_init(); + debug_modfrag_init(); + return 0; +} + +module_init(info_vmalloc_init); +#endif -- 2.17.1