18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * mm/kmemleak.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2008 ARM Limited 68c2ecf20Sopenharmony_ci * Written by Catalin Marinas <catalin.marinas@arm.com> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * For more information on the algorithm and kmemleak usage, please see 98c2ecf20Sopenharmony_ci * Documentation/dev-tools/kmemleak.rst. 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * Notes on locking 128c2ecf20Sopenharmony_ci * ---------------- 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * The following locks and mutexes are used by kmemleak: 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * - kmemleak_lock (raw_spinlock_t): protects the object_list modifications and 178c2ecf20Sopenharmony_ci * accesses to the object_tree_root. The object_list is the main list 188c2ecf20Sopenharmony_ci * holding the metadata (struct kmemleak_object) for the allocated memory 198c2ecf20Sopenharmony_ci * blocks. The object_tree_root is a red black tree used to look-up 208c2ecf20Sopenharmony_ci * metadata based on a pointer to the corresponding memory block. The 218c2ecf20Sopenharmony_ci * kmemleak_object structures are added to the object_list and 228c2ecf20Sopenharmony_ci * object_tree_root in the create_object() function called from the 238c2ecf20Sopenharmony_ci * kmemleak_alloc() callback and removed in delete_object() called from the 248c2ecf20Sopenharmony_ci * kmemleak_free() callback 258c2ecf20Sopenharmony_ci * - kmemleak_object.lock (raw_spinlock_t): protects a kmemleak_object. 268c2ecf20Sopenharmony_ci * Accesses to the metadata (e.g. count) are protected by this lock. Note 278c2ecf20Sopenharmony_ci * that some members of this structure may be protected by other means 288c2ecf20Sopenharmony_ci * (atomic or kmemleak_lock). This lock is also held when scanning the 298c2ecf20Sopenharmony_ci * corresponding memory block to avoid the kernel freeing it via the 308c2ecf20Sopenharmony_ci * kmemleak_free() callback. This is less heavyweight than holding a global 318c2ecf20Sopenharmony_ci * lock like kmemleak_lock during scanning. 328c2ecf20Sopenharmony_ci * - scan_mutex (mutex): ensures that only one thread may scan the memory for 338c2ecf20Sopenharmony_ci * unreferenced objects at a time. The gray_list contains the objects which 348c2ecf20Sopenharmony_ci * are already referenced or marked as false positives and need to be 358c2ecf20Sopenharmony_ci * scanned. This list is only modified during a scanning episode when the 368c2ecf20Sopenharmony_ci * scan_mutex is held. At the end of a scan, the gray_list is always empty. 378c2ecf20Sopenharmony_ci * Note that the kmemleak_object.use_count is incremented when an object is 388c2ecf20Sopenharmony_ci * added to the gray_list and therefore cannot be freed. This mutex also 398c2ecf20Sopenharmony_ci * prevents multiple users of the "kmemleak" debugfs file together with 408c2ecf20Sopenharmony_ci * modifications to the memory scanning parameters including the scan_thread 418c2ecf20Sopenharmony_ci * pointer 428c2ecf20Sopenharmony_ci * 438c2ecf20Sopenharmony_ci * Locks and mutexes are acquired/nested in the following order: 448c2ecf20Sopenharmony_ci * 458c2ecf20Sopenharmony_ci * scan_mutex [-> object->lock] -> kmemleak_lock -> other_object->lock (SINGLE_DEPTH_NESTING) 468c2ecf20Sopenharmony_ci * 478c2ecf20Sopenharmony_ci * No kmemleak_lock and object->lock nesting is allowed outside scan_mutex 488c2ecf20Sopenharmony_ci * regions. 498c2ecf20Sopenharmony_ci * 508c2ecf20Sopenharmony_ci * The kmemleak_object structures have a use_count incremented or decremented 518c2ecf20Sopenharmony_ci * using the get_object()/put_object() functions. When the use_count becomes 528c2ecf20Sopenharmony_ci * 0, this count can no longer be incremented and put_object() schedules the 538c2ecf20Sopenharmony_ci * kmemleak_object freeing via an RCU callback. All calls to the get_object() 548c2ecf20Sopenharmony_ci * function must be protected by rcu_read_lock() to avoid accessing a freed 558c2ecf20Sopenharmony_ci * structure. 568c2ecf20Sopenharmony_ci */ 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci#include <linux/init.h> 618c2ecf20Sopenharmony_ci#include <linux/kernel.h> 628c2ecf20Sopenharmony_ci#include <linux/list.h> 638c2ecf20Sopenharmony_ci#include <linux/sched/signal.h> 648c2ecf20Sopenharmony_ci#include <linux/sched/task.h> 658c2ecf20Sopenharmony_ci#include <linux/sched/task_stack.h> 668c2ecf20Sopenharmony_ci#include <linux/jiffies.h> 678c2ecf20Sopenharmony_ci#include <linux/delay.h> 688c2ecf20Sopenharmony_ci#include <linux/export.h> 698c2ecf20Sopenharmony_ci#include <linux/kthread.h> 708c2ecf20Sopenharmony_ci#include <linux/rbtree.h> 718c2ecf20Sopenharmony_ci#include <linux/fs.h> 728c2ecf20Sopenharmony_ci#include <linux/debugfs.h> 738c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 748c2ecf20Sopenharmony_ci#include <linux/cpumask.h> 758c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 768c2ecf20Sopenharmony_ci#include <linux/module.h> 778c2ecf20Sopenharmony_ci#include <linux/mutex.h> 788c2ecf20Sopenharmony_ci#include <linux/rcupdate.h> 798c2ecf20Sopenharmony_ci#include <linux/stacktrace.h> 808c2ecf20Sopenharmony_ci#include <linux/cache.h> 818c2ecf20Sopenharmony_ci#include <linux/percpu.h> 828c2ecf20Sopenharmony_ci#include <linux/memblock.h> 838c2ecf20Sopenharmony_ci#include <linux/pfn.h> 848c2ecf20Sopenharmony_ci#include <linux/mmzone.h> 858c2ecf20Sopenharmony_ci#include <linux/slab.h> 868c2ecf20Sopenharmony_ci#include <linux/thread_info.h> 878c2ecf20Sopenharmony_ci#include <linux/err.h> 888c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 898c2ecf20Sopenharmony_ci#include <linux/string.h> 908c2ecf20Sopenharmony_ci#include <linux/nodemask.h> 918c2ecf20Sopenharmony_ci#include <linux/mm.h> 928c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 938c2ecf20Sopenharmony_ci#include <linux/crc32.h> 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci#include <asm/sections.h> 968c2ecf20Sopenharmony_ci#include <asm/processor.h> 978c2ecf20Sopenharmony_ci#include <linux/atomic.h> 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci#include <linux/kasan.h> 1008c2ecf20Sopenharmony_ci#include <linux/kmemleak.h> 1018c2ecf20Sopenharmony_ci#include <linux/memory_hotplug.h> 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci/* 1048c2ecf20Sopenharmony_ci * Kmemleak configuration and common defines. 1058c2ecf20Sopenharmony_ci */ 1068c2ecf20Sopenharmony_ci#define MAX_TRACE 16 /* stack trace length */ 1078c2ecf20Sopenharmony_ci#define MSECS_MIN_AGE 5000 /* minimum object age for reporting */ 1088c2ecf20Sopenharmony_ci#define SECS_FIRST_SCAN 60 /* delay before the first scan */ 1098c2ecf20Sopenharmony_ci#define SECS_SCAN_WAIT 600 /* subsequent auto scanning delay */ 1108c2ecf20Sopenharmony_ci#define MAX_SCAN_SIZE 4096 /* maximum size of a scanned block */ 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci#define BYTES_PER_POINTER sizeof(void *) 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci/* GFP bitmask for kmemleak internal allocations */ 1158c2ecf20Sopenharmony_ci#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC)) | \ 1168c2ecf20Sopenharmony_ci __GFP_NORETRY | __GFP_NOMEMALLOC | \ 1178c2ecf20Sopenharmony_ci __GFP_NOWARN) 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci/* scanning area inside a memory block */ 1208c2ecf20Sopenharmony_cistruct kmemleak_scan_area { 1218c2ecf20Sopenharmony_ci struct hlist_node node; 1228c2ecf20Sopenharmony_ci unsigned long start; 1238c2ecf20Sopenharmony_ci size_t size; 1248c2ecf20Sopenharmony_ci}; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci#define KMEMLEAK_GREY 0 1278c2ecf20Sopenharmony_ci#define KMEMLEAK_BLACK -1 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci/* 1308c2ecf20Sopenharmony_ci * Structure holding the metadata for each allocated memory block. 1318c2ecf20Sopenharmony_ci * Modifications to such objects should be made while holding the 1328c2ecf20Sopenharmony_ci * object->lock. Insertions or deletions from object_list, gray_list or 1338c2ecf20Sopenharmony_ci * rb_node are already protected by the corresponding locks or mutex (see 1348c2ecf20Sopenharmony_ci * the notes on locking above). These objects are reference-counted 1358c2ecf20Sopenharmony_ci * (use_count) and freed using the RCU mechanism. 1368c2ecf20Sopenharmony_ci */ 1378c2ecf20Sopenharmony_cistruct kmemleak_object { 1388c2ecf20Sopenharmony_ci raw_spinlock_t lock; 1398c2ecf20Sopenharmony_ci unsigned int flags; /* object status flags */ 1408c2ecf20Sopenharmony_ci struct list_head object_list; 1418c2ecf20Sopenharmony_ci struct list_head gray_list; 1428c2ecf20Sopenharmony_ci struct rb_node rb_node; 1438c2ecf20Sopenharmony_ci struct rcu_head rcu; /* object_list lockless traversal */ 1448c2ecf20Sopenharmony_ci /* object usage count; object freed when use_count == 0 */ 1458c2ecf20Sopenharmony_ci atomic_t use_count; 1468c2ecf20Sopenharmony_ci unsigned long pointer; 1478c2ecf20Sopenharmony_ci size_t size; 1488c2ecf20Sopenharmony_ci /* pass surplus references to this pointer */ 1498c2ecf20Sopenharmony_ci unsigned long excess_ref; 1508c2ecf20Sopenharmony_ci /* minimum number of a pointers found before it is considered leak */ 1518c2ecf20Sopenharmony_ci int min_count; 1528c2ecf20Sopenharmony_ci /* the total number of pointers found pointing to this object */ 1538c2ecf20Sopenharmony_ci int count; 1548c2ecf20Sopenharmony_ci /* checksum for detecting modified objects */ 1558c2ecf20Sopenharmony_ci u32 checksum; 1568c2ecf20Sopenharmony_ci /* memory ranges to be scanned inside an object (empty for all) */ 1578c2ecf20Sopenharmony_ci struct hlist_head area_list; 1588c2ecf20Sopenharmony_ci unsigned long trace[MAX_TRACE]; 1598c2ecf20Sopenharmony_ci unsigned int trace_len; 1608c2ecf20Sopenharmony_ci unsigned long jiffies; /* creation timestamp */ 1618c2ecf20Sopenharmony_ci pid_t pid; /* pid of the current task */ 1628c2ecf20Sopenharmony_ci char comm[TASK_COMM_LEN]; /* executable name */ 1638c2ecf20Sopenharmony_ci}; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/* flag representing the memory block allocation status */ 1668c2ecf20Sopenharmony_ci#define OBJECT_ALLOCATED (1 << 0) 1678c2ecf20Sopenharmony_ci/* flag set after the first reporting of an unreference object */ 1688c2ecf20Sopenharmony_ci#define OBJECT_REPORTED (1 << 1) 1698c2ecf20Sopenharmony_ci/* flag set to not scan the object */ 1708c2ecf20Sopenharmony_ci#define OBJECT_NO_SCAN (1 << 2) 1718c2ecf20Sopenharmony_ci/* flag set to fully scan the object when scan_area allocation failed */ 1728c2ecf20Sopenharmony_ci#define OBJECT_FULL_SCAN (1 << 3) 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci#define HEX_PREFIX " " 1758c2ecf20Sopenharmony_ci/* number of bytes to print per line; must be 16 or 32 */ 1768c2ecf20Sopenharmony_ci#define HEX_ROW_SIZE 16 1778c2ecf20Sopenharmony_ci/* number of bytes to print at a time (1, 2, 4, 8) */ 1788c2ecf20Sopenharmony_ci#define HEX_GROUP_SIZE 1 1798c2ecf20Sopenharmony_ci/* include ASCII after the hex output */ 1808c2ecf20Sopenharmony_ci#define HEX_ASCII 1 1818c2ecf20Sopenharmony_ci/* max number of lines to be printed */ 1828c2ecf20Sopenharmony_ci#define HEX_MAX_LINES 2 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci/* the list of all allocated objects */ 1858c2ecf20Sopenharmony_cistatic LIST_HEAD(object_list); 1868c2ecf20Sopenharmony_ci/* the list of gray-colored objects (see color_gray comment below) */ 1878c2ecf20Sopenharmony_cistatic LIST_HEAD(gray_list); 1888c2ecf20Sopenharmony_ci/* memory pool allocation */ 1898c2ecf20Sopenharmony_cistatic struct kmemleak_object mem_pool[CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE]; 1908c2ecf20Sopenharmony_cistatic int mem_pool_free_count = ARRAY_SIZE(mem_pool); 1918c2ecf20Sopenharmony_cistatic LIST_HEAD(mem_pool_free_list); 1928c2ecf20Sopenharmony_ci/* search tree for object boundaries */ 1938c2ecf20Sopenharmony_cistatic struct rb_root object_tree_root = RB_ROOT; 1948c2ecf20Sopenharmony_ci/* protecting the access to object_list and object_tree_root */ 1958c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(kmemleak_lock); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci/* allocation caches for kmemleak internal data */ 1988c2ecf20Sopenharmony_cistatic struct kmem_cache *object_cache; 1998c2ecf20Sopenharmony_cistatic struct kmem_cache *scan_area_cache; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci/* set if tracing memory operations is enabled */ 2028c2ecf20Sopenharmony_cistatic int kmemleak_enabled = 1; 2038c2ecf20Sopenharmony_ci/* same as above but only for the kmemleak_free() callback */ 2048c2ecf20Sopenharmony_cistatic int kmemleak_free_enabled = 1; 2058c2ecf20Sopenharmony_ci/* set in the late_initcall if there were no errors */ 2068c2ecf20Sopenharmony_cistatic int kmemleak_initialized; 2078c2ecf20Sopenharmony_ci/* set if a kmemleak warning was issued */ 2088c2ecf20Sopenharmony_cistatic int kmemleak_warning; 2098c2ecf20Sopenharmony_ci/* set if a fatal kmemleak error has occurred */ 2108c2ecf20Sopenharmony_cistatic int kmemleak_error; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci/* minimum and maximum address that may be valid pointers */ 2138c2ecf20Sopenharmony_cistatic unsigned long min_addr = ULONG_MAX; 2148c2ecf20Sopenharmony_cistatic unsigned long max_addr; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_cistatic struct task_struct *scan_thread; 2178c2ecf20Sopenharmony_ci/* used to avoid reporting of recently allocated objects */ 2188c2ecf20Sopenharmony_cistatic unsigned long jiffies_min_age; 2198c2ecf20Sopenharmony_cistatic unsigned long jiffies_last_scan; 2208c2ecf20Sopenharmony_ci/* delay between automatic memory scannings */ 2218c2ecf20Sopenharmony_cistatic signed long jiffies_scan_wait; 2228c2ecf20Sopenharmony_ci/* enables or disables the task stacks scanning */ 2238c2ecf20Sopenharmony_cistatic int kmemleak_stack_scan = 1; 2248c2ecf20Sopenharmony_ci/* protects the memory scanning, parameters and debug/kmemleak file access */ 2258c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(scan_mutex); 2268c2ecf20Sopenharmony_ci/* setting kmemleak=on, will set this var, skipping the disable */ 2278c2ecf20Sopenharmony_cistatic int kmemleak_skip_disable; 2288c2ecf20Sopenharmony_ci/* If there are leaks that can be reported */ 2298c2ecf20Sopenharmony_cistatic bool kmemleak_found_leaks; 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_cistatic bool kmemleak_verbose; 2328c2ecf20Sopenharmony_cimodule_param_named(verbose, kmemleak_verbose, bool, 0600); 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cistatic void kmemleak_disable(void); 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci/* 2378c2ecf20Sopenharmony_ci * Print a warning and dump the stack trace. 2388c2ecf20Sopenharmony_ci */ 2398c2ecf20Sopenharmony_ci#define kmemleak_warn(x...) do { \ 2408c2ecf20Sopenharmony_ci pr_warn(x); \ 2418c2ecf20Sopenharmony_ci dump_stack(); \ 2428c2ecf20Sopenharmony_ci kmemleak_warning = 1; \ 2438c2ecf20Sopenharmony_ci} while (0) 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci/* 2468c2ecf20Sopenharmony_ci * Macro invoked when a serious kmemleak condition occurred and cannot be 2478c2ecf20Sopenharmony_ci * recovered from. Kmemleak will be disabled and further allocation/freeing 2488c2ecf20Sopenharmony_ci * tracing no longer available. 2498c2ecf20Sopenharmony_ci */ 2508c2ecf20Sopenharmony_ci#define kmemleak_stop(x...) do { \ 2518c2ecf20Sopenharmony_ci kmemleak_warn(x); \ 2528c2ecf20Sopenharmony_ci kmemleak_disable(); \ 2538c2ecf20Sopenharmony_ci} while (0) 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci#define warn_or_seq_printf(seq, fmt, ...) do { \ 2568c2ecf20Sopenharmony_ci if (seq) \ 2578c2ecf20Sopenharmony_ci seq_printf(seq, fmt, ##__VA_ARGS__); \ 2588c2ecf20Sopenharmony_ci else \ 2598c2ecf20Sopenharmony_ci pr_warn(fmt, ##__VA_ARGS__); \ 2608c2ecf20Sopenharmony_ci} while (0) 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_cistatic void warn_or_seq_hex_dump(struct seq_file *seq, int prefix_type, 2638c2ecf20Sopenharmony_ci int rowsize, int groupsize, const void *buf, 2648c2ecf20Sopenharmony_ci size_t len, bool ascii) 2658c2ecf20Sopenharmony_ci{ 2668c2ecf20Sopenharmony_ci if (seq) 2678c2ecf20Sopenharmony_ci seq_hex_dump(seq, HEX_PREFIX, prefix_type, rowsize, groupsize, 2688c2ecf20Sopenharmony_ci buf, len, ascii); 2698c2ecf20Sopenharmony_ci else 2708c2ecf20Sopenharmony_ci print_hex_dump(KERN_WARNING, pr_fmt(HEX_PREFIX), prefix_type, 2718c2ecf20Sopenharmony_ci rowsize, groupsize, buf, len, ascii); 2728c2ecf20Sopenharmony_ci} 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci/* 2758c2ecf20Sopenharmony_ci * Printing of the objects hex dump to the seq file. The number of lines to be 2768c2ecf20Sopenharmony_ci * printed is limited to HEX_MAX_LINES to prevent seq file spamming. The 2778c2ecf20Sopenharmony_ci * actual number of printed bytes depends on HEX_ROW_SIZE. It must be called 2788c2ecf20Sopenharmony_ci * with the object->lock held. 2798c2ecf20Sopenharmony_ci */ 2808c2ecf20Sopenharmony_cistatic void hex_dump_object(struct seq_file *seq, 2818c2ecf20Sopenharmony_ci struct kmemleak_object *object) 2828c2ecf20Sopenharmony_ci{ 2838c2ecf20Sopenharmony_ci const u8 *ptr = (const u8 *)object->pointer; 2848c2ecf20Sopenharmony_ci size_t len; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci /* limit the number of lines to HEX_MAX_LINES */ 2878c2ecf20Sopenharmony_ci len = min_t(size_t, object->size, HEX_MAX_LINES * HEX_ROW_SIZE); 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci warn_or_seq_printf(seq, " hex dump (first %zu bytes):\n", len); 2908c2ecf20Sopenharmony_ci kasan_disable_current(); 2918c2ecf20Sopenharmony_ci warn_or_seq_hex_dump(seq, DUMP_PREFIX_NONE, HEX_ROW_SIZE, 2928c2ecf20Sopenharmony_ci HEX_GROUP_SIZE, ptr, len, HEX_ASCII); 2938c2ecf20Sopenharmony_ci kasan_enable_current(); 2948c2ecf20Sopenharmony_ci} 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci/* 2978c2ecf20Sopenharmony_ci * Object colors, encoded with count and min_count: 2988c2ecf20Sopenharmony_ci * - white - orphan object, not enough references to it (count < min_count) 2998c2ecf20Sopenharmony_ci * - gray - not orphan, not marked as false positive (min_count == 0) or 3008c2ecf20Sopenharmony_ci * sufficient references to it (count >= min_count) 3018c2ecf20Sopenharmony_ci * - black - ignore, it doesn't contain references (e.g. text section) 3028c2ecf20Sopenharmony_ci * (min_count == -1). No function defined for this color. 3038c2ecf20Sopenharmony_ci * Newly created objects don't have any color assigned (object->count == -1) 3048c2ecf20Sopenharmony_ci * before the next memory scan when they become white. 3058c2ecf20Sopenharmony_ci */ 3068c2ecf20Sopenharmony_cistatic bool color_white(const struct kmemleak_object *object) 3078c2ecf20Sopenharmony_ci{ 3088c2ecf20Sopenharmony_ci return object->count != KMEMLEAK_BLACK && 3098c2ecf20Sopenharmony_ci object->count < object->min_count; 3108c2ecf20Sopenharmony_ci} 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_cistatic bool color_gray(const struct kmemleak_object *object) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci return object->min_count != KMEMLEAK_BLACK && 3158c2ecf20Sopenharmony_ci object->count >= object->min_count; 3168c2ecf20Sopenharmony_ci} 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci/* 3198c2ecf20Sopenharmony_ci * Objects are considered unreferenced only if their color is white, they have 3208c2ecf20Sopenharmony_ci * not be deleted and have a minimum age to avoid false positives caused by 3218c2ecf20Sopenharmony_ci * pointers temporarily stored in CPU registers. 3228c2ecf20Sopenharmony_ci */ 3238c2ecf20Sopenharmony_cistatic bool unreferenced_object(struct kmemleak_object *object) 3248c2ecf20Sopenharmony_ci{ 3258c2ecf20Sopenharmony_ci return (color_white(object) && object->flags & OBJECT_ALLOCATED) && 3268c2ecf20Sopenharmony_ci time_before_eq(object->jiffies + jiffies_min_age, 3278c2ecf20Sopenharmony_ci jiffies_last_scan); 3288c2ecf20Sopenharmony_ci} 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci/* 3318c2ecf20Sopenharmony_ci * Printing of the unreferenced objects information to the seq file. The 3328c2ecf20Sopenharmony_ci * print_unreferenced function must be called with the object->lock held. 3338c2ecf20Sopenharmony_ci */ 3348c2ecf20Sopenharmony_cistatic void print_unreferenced(struct seq_file *seq, 3358c2ecf20Sopenharmony_ci struct kmemleak_object *object) 3368c2ecf20Sopenharmony_ci{ 3378c2ecf20Sopenharmony_ci int i; 3388c2ecf20Sopenharmony_ci unsigned int msecs_age = jiffies_to_msecs(jiffies - object->jiffies); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci warn_or_seq_printf(seq, "unreferenced object 0x%08lx (size %zu):\n", 3418c2ecf20Sopenharmony_ci object->pointer, object->size); 3428c2ecf20Sopenharmony_ci warn_or_seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu (age %d.%03ds)\n", 3438c2ecf20Sopenharmony_ci object->comm, object->pid, object->jiffies, 3448c2ecf20Sopenharmony_ci msecs_age / 1000, msecs_age % 1000); 3458c2ecf20Sopenharmony_ci hex_dump_object(seq, object); 3468c2ecf20Sopenharmony_ci warn_or_seq_printf(seq, " backtrace:\n"); 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci for (i = 0; i < object->trace_len; i++) { 3498c2ecf20Sopenharmony_ci void *ptr = (void *)object->trace[i]; 3508c2ecf20Sopenharmony_ci warn_or_seq_printf(seq, " [<%p>] %pS\n", ptr, ptr); 3518c2ecf20Sopenharmony_ci } 3528c2ecf20Sopenharmony_ci} 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci/* 3558c2ecf20Sopenharmony_ci * Print the kmemleak_object information. This function is used mainly for 3568c2ecf20Sopenharmony_ci * debugging special cases when kmemleak operations. It must be called with 3578c2ecf20Sopenharmony_ci * the object->lock held. 3588c2ecf20Sopenharmony_ci */ 3598c2ecf20Sopenharmony_cistatic void dump_object_info(struct kmemleak_object *object) 3608c2ecf20Sopenharmony_ci{ 3618c2ecf20Sopenharmony_ci pr_notice("Object 0x%08lx (size %zu):\n", 3628c2ecf20Sopenharmony_ci object->pointer, object->size); 3638c2ecf20Sopenharmony_ci pr_notice(" comm \"%s\", pid %d, jiffies %lu\n", 3648c2ecf20Sopenharmony_ci object->comm, object->pid, object->jiffies); 3658c2ecf20Sopenharmony_ci pr_notice(" min_count = %d\n", object->min_count); 3668c2ecf20Sopenharmony_ci pr_notice(" count = %d\n", object->count); 3678c2ecf20Sopenharmony_ci pr_notice(" flags = 0x%x\n", object->flags); 3688c2ecf20Sopenharmony_ci pr_notice(" checksum = %u\n", object->checksum); 3698c2ecf20Sopenharmony_ci pr_notice(" backtrace:\n"); 3708c2ecf20Sopenharmony_ci stack_trace_print(object->trace, object->trace_len, 4); 3718c2ecf20Sopenharmony_ci} 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci/* 3748c2ecf20Sopenharmony_ci * Look-up a memory block metadata (kmemleak_object) in the object search 3758c2ecf20Sopenharmony_ci * tree based on a pointer value. If alias is 0, only values pointing to the 3768c2ecf20Sopenharmony_ci * beginning of the memory block are allowed. The kmemleak_lock must be held 3778c2ecf20Sopenharmony_ci * when calling this function. 3788c2ecf20Sopenharmony_ci */ 3798c2ecf20Sopenharmony_cistatic struct kmemleak_object *lookup_object(unsigned long ptr, int alias) 3808c2ecf20Sopenharmony_ci{ 3818c2ecf20Sopenharmony_ci struct rb_node *rb = object_tree_root.rb_node; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci while (rb) { 3848c2ecf20Sopenharmony_ci struct kmemleak_object *object = 3858c2ecf20Sopenharmony_ci rb_entry(rb, struct kmemleak_object, rb_node); 3868c2ecf20Sopenharmony_ci if (ptr < object->pointer) 3878c2ecf20Sopenharmony_ci rb = object->rb_node.rb_left; 3888c2ecf20Sopenharmony_ci else if (object->pointer + object->size <= ptr) 3898c2ecf20Sopenharmony_ci rb = object->rb_node.rb_right; 3908c2ecf20Sopenharmony_ci else if (object->pointer == ptr || alias) 3918c2ecf20Sopenharmony_ci return object; 3928c2ecf20Sopenharmony_ci else { 3938c2ecf20Sopenharmony_ci kmemleak_warn("Found object by alias at 0x%08lx\n", 3948c2ecf20Sopenharmony_ci ptr); 3958c2ecf20Sopenharmony_ci dump_object_info(object); 3968c2ecf20Sopenharmony_ci break; 3978c2ecf20Sopenharmony_ci } 3988c2ecf20Sopenharmony_ci } 3998c2ecf20Sopenharmony_ci return NULL; 4008c2ecf20Sopenharmony_ci} 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci/* 4038c2ecf20Sopenharmony_ci * Increment the object use_count. Return 1 if successful or 0 otherwise. Note 4048c2ecf20Sopenharmony_ci * that once an object's use_count reached 0, the RCU freeing was already 4058c2ecf20Sopenharmony_ci * registered and the object should no longer be used. This function must be 4068c2ecf20Sopenharmony_ci * called under the protection of rcu_read_lock(). 4078c2ecf20Sopenharmony_ci */ 4088c2ecf20Sopenharmony_cistatic int get_object(struct kmemleak_object *object) 4098c2ecf20Sopenharmony_ci{ 4108c2ecf20Sopenharmony_ci return atomic_inc_not_zero(&object->use_count); 4118c2ecf20Sopenharmony_ci} 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci/* 4148c2ecf20Sopenharmony_ci * Memory pool allocation and freeing. kmemleak_lock must not be held. 4158c2ecf20Sopenharmony_ci */ 4168c2ecf20Sopenharmony_cistatic struct kmemleak_object *mem_pool_alloc(gfp_t gfp) 4178c2ecf20Sopenharmony_ci{ 4188c2ecf20Sopenharmony_ci unsigned long flags; 4198c2ecf20Sopenharmony_ci struct kmemleak_object *object; 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci /* try the slab allocator first */ 4228c2ecf20Sopenharmony_ci if (object_cache) { 4238c2ecf20Sopenharmony_ci object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp)); 4248c2ecf20Sopenharmony_ci if (object) 4258c2ecf20Sopenharmony_ci return object; 4268c2ecf20Sopenharmony_ci } 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci /* slab allocation failed, try the memory pool */ 4298c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 4308c2ecf20Sopenharmony_ci object = list_first_entry_or_null(&mem_pool_free_list, 4318c2ecf20Sopenharmony_ci typeof(*object), object_list); 4328c2ecf20Sopenharmony_ci if (object) 4338c2ecf20Sopenharmony_ci list_del(&object->object_list); 4348c2ecf20Sopenharmony_ci else if (mem_pool_free_count) 4358c2ecf20Sopenharmony_ci object = &mem_pool[--mem_pool_free_count]; 4368c2ecf20Sopenharmony_ci else 4378c2ecf20Sopenharmony_ci pr_warn_once("Memory pool empty, consider increasing CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE\n"); 4388c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci return object; 4418c2ecf20Sopenharmony_ci} 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci/* 4448c2ecf20Sopenharmony_ci * Return the object to either the slab allocator or the memory pool. 4458c2ecf20Sopenharmony_ci */ 4468c2ecf20Sopenharmony_cistatic void mem_pool_free(struct kmemleak_object *object) 4478c2ecf20Sopenharmony_ci{ 4488c2ecf20Sopenharmony_ci unsigned long flags; 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci if (object < mem_pool || object >= mem_pool + ARRAY_SIZE(mem_pool)) { 4518c2ecf20Sopenharmony_ci kmem_cache_free(object_cache, object); 4528c2ecf20Sopenharmony_ci return; 4538c2ecf20Sopenharmony_ci } 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci /* add the object to the memory pool free list */ 4568c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 4578c2ecf20Sopenharmony_ci list_add(&object->object_list, &mem_pool_free_list); 4588c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 4598c2ecf20Sopenharmony_ci} 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_ci/* 4628c2ecf20Sopenharmony_ci * RCU callback to free a kmemleak_object. 4638c2ecf20Sopenharmony_ci */ 4648c2ecf20Sopenharmony_cistatic void free_object_rcu(struct rcu_head *rcu) 4658c2ecf20Sopenharmony_ci{ 4668c2ecf20Sopenharmony_ci struct hlist_node *tmp; 4678c2ecf20Sopenharmony_ci struct kmemleak_scan_area *area; 4688c2ecf20Sopenharmony_ci struct kmemleak_object *object = 4698c2ecf20Sopenharmony_ci container_of(rcu, struct kmemleak_object, rcu); 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci /* 4728c2ecf20Sopenharmony_ci * Once use_count is 0 (guaranteed by put_object), there is no other 4738c2ecf20Sopenharmony_ci * code accessing this object, hence no need for locking. 4748c2ecf20Sopenharmony_ci */ 4758c2ecf20Sopenharmony_ci hlist_for_each_entry_safe(area, tmp, &object->area_list, node) { 4768c2ecf20Sopenharmony_ci hlist_del(&area->node); 4778c2ecf20Sopenharmony_ci kmem_cache_free(scan_area_cache, area); 4788c2ecf20Sopenharmony_ci } 4798c2ecf20Sopenharmony_ci mem_pool_free(object); 4808c2ecf20Sopenharmony_ci} 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci/* 4838c2ecf20Sopenharmony_ci * Decrement the object use_count. Once the count is 0, free the object using 4848c2ecf20Sopenharmony_ci * an RCU callback. Since put_object() may be called via the kmemleak_free() -> 4858c2ecf20Sopenharmony_ci * delete_object() path, the delayed RCU freeing ensures that there is no 4868c2ecf20Sopenharmony_ci * recursive call to the kernel allocator. Lock-less RCU object_list traversal 4878c2ecf20Sopenharmony_ci * is also possible. 4888c2ecf20Sopenharmony_ci */ 4898c2ecf20Sopenharmony_cistatic void put_object(struct kmemleak_object *object) 4908c2ecf20Sopenharmony_ci{ 4918c2ecf20Sopenharmony_ci if (!atomic_dec_and_test(&object->use_count)) 4928c2ecf20Sopenharmony_ci return; 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_ci /* should only get here after delete_object was called */ 4958c2ecf20Sopenharmony_ci WARN_ON(object->flags & OBJECT_ALLOCATED); 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci /* 4988c2ecf20Sopenharmony_ci * It may be too early for the RCU callbacks, however, there is no 4998c2ecf20Sopenharmony_ci * concurrent object_list traversal when !object_cache and all objects 5008c2ecf20Sopenharmony_ci * came from the memory pool. Free the object directly. 5018c2ecf20Sopenharmony_ci */ 5028c2ecf20Sopenharmony_ci if (object_cache) 5038c2ecf20Sopenharmony_ci call_rcu(&object->rcu, free_object_rcu); 5048c2ecf20Sopenharmony_ci else 5058c2ecf20Sopenharmony_ci free_object_rcu(&object->rcu); 5068c2ecf20Sopenharmony_ci} 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci/* 5098c2ecf20Sopenharmony_ci * Look up an object in the object search tree and increase its use_count. 5108c2ecf20Sopenharmony_ci */ 5118c2ecf20Sopenharmony_cistatic struct kmemleak_object *find_and_get_object(unsigned long ptr, int alias) 5128c2ecf20Sopenharmony_ci{ 5138c2ecf20Sopenharmony_ci unsigned long flags; 5148c2ecf20Sopenharmony_ci struct kmemleak_object *object; 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_ci rcu_read_lock(); 5178c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 5188c2ecf20Sopenharmony_ci object = lookup_object(ptr, alias); 5198c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 5208c2ecf20Sopenharmony_ci 5218c2ecf20Sopenharmony_ci /* check whether the object is still available */ 5228c2ecf20Sopenharmony_ci if (object && !get_object(object)) 5238c2ecf20Sopenharmony_ci object = NULL; 5248c2ecf20Sopenharmony_ci rcu_read_unlock(); 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci return object; 5278c2ecf20Sopenharmony_ci} 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ci/* 5308c2ecf20Sopenharmony_ci * Remove an object from the object_tree_root and object_list. Must be called 5318c2ecf20Sopenharmony_ci * with the kmemleak_lock held _if_ kmemleak is still enabled. 5328c2ecf20Sopenharmony_ci */ 5338c2ecf20Sopenharmony_cistatic void __remove_object(struct kmemleak_object *object) 5348c2ecf20Sopenharmony_ci{ 5358c2ecf20Sopenharmony_ci rb_erase(&object->rb_node, &object_tree_root); 5368c2ecf20Sopenharmony_ci list_del_rcu(&object->object_list); 5378c2ecf20Sopenharmony_ci} 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_ci/* 5408c2ecf20Sopenharmony_ci * Look up an object in the object search tree and remove it from both 5418c2ecf20Sopenharmony_ci * object_tree_root and object_list. The returned object's use_count should be 5428c2ecf20Sopenharmony_ci * at least 1, as initially set by create_object(). 5438c2ecf20Sopenharmony_ci */ 5448c2ecf20Sopenharmony_cistatic struct kmemleak_object *find_and_remove_object(unsigned long ptr, int alias) 5458c2ecf20Sopenharmony_ci{ 5468c2ecf20Sopenharmony_ci unsigned long flags; 5478c2ecf20Sopenharmony_ci struct kmemleak_object *object; 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 5508c2ecf20Sopenharmony_ci object = lookup_object(ptr, alias); 5518c2ecf20Sopenharmony_ci if (object) 5528c2ecf20Sopenharmony_ci __remove_object(object); 5538c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci return object; 5568c2ecf20Sopenharmony_ci} 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci/* 5598c2ecf20Sopenharmony_ci * Save stack trace to the given array of MAX_TRACE size. 5608c2ecf20Sopenharmony_ci */ 5618c2ecf20Sopenharmony_cistatic int __save_stack_trace(unsigned long *trace) 5628c2ecf20Sopenharmony_ci{ 5638c2ecf20Sopenharmony_ci return stack_trace_save(trace, MAX_TRACE, 2); 5648c2ecf20Sopenharmony_ci} 5658c2ecf20Sopenharmony_ci 5668c2ecf20Sopenharmony_ci/* 5678c2ecf20Sopenharmony_ci * Create the metadata (struct kmemleak_object) corresponding to an allocated 5688c2ecf20Sopenharmony_ci * memory block and add it to the object_list and object_tree_root. 5698c2ecf20Sopenharmony_ci */ 5708c2ecf20Sopenharmony_cistatic struct kmemleak_object *create_object(unsigned long ptr, size_t size, 5718c2ecf20Sopenharmony_ci int min_count, gfp_t gfp) 5728c2ecf20Sopenharmony_ci{ 5738c2ecf20Sopenharmony_ci unsigned long flags; 5748c2ecf20Sopenharmony_ci struct kmemleak_object *object, *parent; 5758c2ecf20Sopenharmony_ci struct rb_node **link, *rb_parent; 5768c2ecf20Sopenharmony_ci unsigned long untagged_ptr; 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_ci object = mem_pool_alloc(gfp); 5798c2ecf20Sopenharmony_ci if (!object) { 5808c2ecf20Sopenharmony_ci pr_warn("Cannot allocate a kmemleak_object structure\n"); 5818c2ecf20Sopenharmony_ci kmemleak_disable(); 5828c2ecf20Sopenharmony_ci return NULL; 5838c2ecf20Sopenharmony_ci } 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&object->object_list); 5868c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&object->gray_list); 5878c2ecf20Sopenharmony_ci INIT_HLIST_HEAD(&object->area_list); 5888c2ecf20Sopenharmony_ci raw_spin_lock_init(&object->lock); 5898c2ecf20Sopenharmony_ci atomic_set(&object->use_count, 1); 5908c2ecf20Sopenharmony_ci object->flags = OBJECT_ALLOCATED; 5918c2ecf20Sopenharmony_ci object->pointer = ptr; 5928c2ecf20Sopenharmony_ci object->size = size; 5938c2ecf20Sopenharmony_ci object->excess_ref = 0; 5948c2ecf20Sopenharmony_ci object->min_count = min_count; 5958c2ecf20Sopenharmony_ci object->count = 0; /* white color initially */ 5968c2ecf20Sopenharmony_ci object->jiffies = jiffies; 5978c2ecf20Sopenharmony_ci object->checksum = 0; 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci /* task information */ 6008c2ecf20Sopenharmony_ci if (in_irq()) { 6018c2ecf20Sopenharmony_ci object->pid = 0; 6028c2ecf20Sopenharmony_ci strncpy(object->comm, "hardirq", sizeof(object->comm)); 6038c2ecf20Sopenharmony_ci } else if (in_serving_softirq()) { 6048c2ecf20Sopenharmony_ci object->pid = 0; 6058c2ecf20Sopenharmony_ci strncpy(object->comm, "softirq", sizeof(object->comm)); 6068c2ecf20Sopenharmony_ci } else { 6078c2ecf20Sopenharmony_ci object->pid = current->pid; 6088c2ecf20Sopenharmony_ci /* 6098c2ecf20Sopenharmony_ci * There is a small chance of a race with set_task_comm(), 6108c2ecf20Sopenharmony_ci * however using get_task_comm() here may cause locking 6118c2ecf20Sopenharmony_ci * dependency issues with current->alloc_lock. In the worst 6128c2ecf20Sopenharmony_ci * case, the command line is not correct. 6138c2ecf20Sopenharmony_ci */ 6148c2ecf20Sopenharmony_ci strncpy(object->comm, current->comm, sizeof(object->comm)); 6158c2ecf20Sopenharmony_ci } 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci /* kernel backtrace */ 6188c2ecf20Sopenharmony_ci object->trace_len = __save_stack_trace(object->trace); 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_ci untagged_ptr = (unsigned long)kasan_reset_tag((void *)ptr); 6238c2ecf20Sopenharmony_ci min_addr = min(min_addr, untagged_ptr); 6248c2ecf20Sopenharmony_ci max_addr = max(max_addr, untagged_ptr + size); 6258c2ecf20Sopenharmony_ci link = &object_tree_root.rb_node; 6268c2ecf20Sopenharmony_ci rb_parent = NULL; 6278c2ecf20Sopenharmony_ci while (*link) { 6288c2ecf20Sopenharmony_ci rb_parent = *link; 6298c2ecf20Sopenharmony_ci parent = rb_entry(rb_parent, struct kmemleak_object, rb_node); 6308c2ecf20Sopenharmony_ci if (ptr + size <= parent->pointer) 6318c2ecf20Sopenharmony_ci link = &parent->rb_node.rb_left; 6328c2ecf20Sopenharmony_ci else if (parent->pointer + parent->size <= ptr) 6338c2ecf20Sopenharmony_ci link = &parent->rb_node.rb_right; 6348c2ecf20Sopenharmony_ci else { 6358c2ecf20Sopenharmony_ci kmemleak_stop("Cannot insert 0x%lx into the object search tree (overlaps existing)\n", 6368c2ecf20Sopenharmony_ci ptr); 6378c2ecf20Sopenharmony_ci /* 6388c2ecf20Sopenharmony_ci * No need for parent->lock here since "parent" cannot 6398c2ecf20Sopenharmony_ci * be freed while the kmemleak_lock is held. 6408c2ecf20Sopenharmony_ci */ 6418c2ecf20Sopenharmony_ci dump_object_info(parent); 6428c2ecf20Sopenharmony_ci kmem_cache_free(object_cache, object); 6438c2ecf20Sopenharmony_ci object = NULL; 6448c2ecf20Sopenharmony_ci goto out; 6458c2ecf20Sopenharmony_ci } 6468c2ecf20Sopenharmony_ci } 6478c2ecf20Sopenharmony_ci rb_link_node(&object->rb_node, rb_parent, link); 6488c2ecf20Sopenharmony_ci rb_insert_color(&object->rb_node, &object_tree_root); 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci list_add_tail_rcu(&object->object_list, &object_list); 6518c2ecf20Sopenharmony_ciout: 6528c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 6538c2ecf20Sopenharmony_ci return object; 6548c2ecf20Sopenharmony_ci} 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci/* 6578c2ecf20Sopenharmony_ci * Mark the object as not allocated and schedule RCU freeing via put_object(). 6588c2ecf20Sopenharmony_ci */ 6598c2ecf20Sopenharmony_cistatic void __delete_object(struct kmemleak_object *object) 6608c2ecf20Sopenharmony_ci{ 6618c2ecf20Sopenharmony_ci unsigned long flags; 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_ci WARN_ON(!(object->flags & OBJECT_ALLOCATED)); 6648c2ecf20Sopenharmony_ci WARN_ON(atomic_read(&object->use_count) < 1); 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci /* 6678c2ecf20Sopenharmony_ci * Locking here also ensures that the corresponding memory block 6688c2ecf20Sopenharmony_ci * cannot be freed when it is being scanned. 6698c2ecf20Sopenharmony_ci */ 6708c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 6718c2ecf20Sopenharmony_ci object->flags &= ~OBJECT_ALLOCATED; 6728c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 6738c2ecf20Sopenharmony_ci put_object(object); 6748c2ecf20Sopenharmony_ci} 6758c2ecf20Sopenharmony_ci 6768c2ecf20Sopenharmony_ci/* 6778c2ecf20Sopenharmony_ci * Look up the metadata (struct kmemleak_object) corresponding to ptr and 6788c2ecf20Sopenharmony_ci * delete it. 6798c2ecf20Sopenharmony_ci */ 6808c2ecf20Sopenharmony_cistatic void delete_object_full(unsigned long ptr) 6818c2ecf20Sopenharmony_ci{ 6828c2ecf20Sopenharmony_ci struct kmemleak_object *object; 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_ci object = find_and_remove_object(ptr, 0); 6858c2ecf20Sopenharmony_ci if (!object) { 6868c2ecf20Sopenharmony_ci#ifdef DEBUG 6878c2ecf20Sopenharmony_ci kmemleak_warn("Freeing unknown object at 0x%08lx\n", 6888c2ecf20Sopenharmony_ci ptr); 6898c2ecf20Sopenharmony_ci#endif 6908c2ecf20Sopenharmony_ci return; 6918c2ecf20Sopenharmony_ci } 6928c2ecf20Sopenharmony_ci __delete_object(object); 6938c2ecf20Sopenharmony_ci} 6948c2ecf20Sopenharmony_ci 6958c2ecf20Sopenharmony_ci/* 6968c2ecf20Sopenharmony_ci * Look up the metadata (struct kmemleak_object) corresponding to ptr and 6978c2ecf20Sopenharmony_ci * delete it. If the memory block is partially freed, the function may create 6988c2ecf20Sopenharmony_ci * additional metadata for the remaining parts of the block. 6998c2ecf20Sopenharmony_ci */ 7008c2ecf20Sopenharmony_cistatic void delete_object_part(unsigned long ptr, size_t size) 7018c2ecf20Sopenharmony_ci{ 7028c2ecf20Sopenharmony_ci struct kmemleak_object *object; 7038c2ecf20Sopenharmony_ci unsigned long start, end; 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci object = find_and_remove_object(ptr, 1); 7068c2ecf20Sopenharmony_ci if (!object) { 7078c2ecf20Sopenharmony_ci#ifdef DEBUG 7088c2ecf20Sopenharmony_ci kmemleak_warn("Partially freeing unknown object at 0x%08lx (size %zu)\n", 7098c2ecf20Sopenharmony_ci ptr, size); 7108c2ecf20Sopenharmony_ci#endif 7118c2ecf20Sopenharmony_ci return; 7128c2ecf20Sopenharmony_ci } 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci /* 7158c2ecf20Sopenharmony_ci * Create one or two objects that may result from the memory block 7168c2ecf20Sopenharmony_ci * split. Note that partial freeing is only done by free_bootmem() and 7178c2ecf20Sopenharmony_ci * this happens before kmemleak_init() is called. 7188c2ecf20Sopenharmony_ci */ 7198c2ecf20Sopenharmony_ci start = object->pointer; 7208c2ecf20Sopenharmony_ci end = object->pointer + object->size; 7218c2ecf20Sopenharmony_ci if (ptr > start) 7228c2ecf20Sopenharmony_ci create_object(start, ptr - start, object->min_count, 7238c2ecf20Sopenharmony_ci GFP_KERNEL); 7248c2ecf20Sopenharmony_ci if (ptr + size < end) 7258c2ecf20Sopenharmony_ci create_object(ptr + size, end - ptr - size, object->min_count, 7268c2ecf20Sopenharmony_ci GFP_KERNEL); 7278c2ecf20Sopenharmony_ci 7288c2ecf20Sopenharmony_ci __delete_object(object); 7298c2ecf20Sopenharmony_ci} 7308c2ecf20Sopenharmony_ci 7318c2ecf20Sopenharmony_cistatic void __paint_it(struct kmemleak_object *object, int color) 7328c2ecf20Sopenharmony_ci{ 7338c2ecf20Sopenharmony_ci object->min_count = color; 7348c2ecf20Sopenharmony_ci if (color == KMEMLEAK_BLACK) 7358c2ecf20Sopenharmony_ci object->flags |= OBJECT_NO_SCAN; 7368c2ecf20Sopenharmony_ci} 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_cistatic void paint_it(struct kmemleak_object *object, int color) 7398c2ecf20Sopenharmony_ci{ 7408c2ecf20Sopenharmony_ci unsigned long flags; 7418c2ecf20Sopenharmony_ci 7428c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 7438c2ecf20Sopenharmony_ci __paint_it(object, color); 7448c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 7458c2ecf20Sopenharmony_ci} 7468c2ecf20Sopenharmony_ci 7478c2ecf20Sopenharmony_cistatic void paint_ptr(unsigned long ptr, int color) 7488c2ecf20Sopenharmony_ci{ 7498c2ecf20Sopenharmony_ci struct kmemleak_object *object; 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_ci object = find_and_get_object(ptr, 0); 7528c2ecf20Sopenharmony_ci if (!object) { 7538c2ecf20Sopenharmony_ci kmemleak_warn("Trying to color unknown object at 0x%08lx as %s\n", 7548c2ecf20Sopenharmony_ci ptr, 7558c2ecf20Sopenharmony_ci (color == KMEMLEAK_GREY) ? "Grey" : 7568c2ecf20Sopenharmony_ci (color == KMEMLEAK_BLACK) ? "Black" : "Unknown"); 7578c2ecf20Sopenharmony_ci return; 7588c2ecf20Sopenharmony_ci } 7598c2ecf20Sopenharmony_ci paint_it(object, color); 7608c2ecf20Sopenharmony_ci put_object(object); 7618c2ecf20Sopenharmony_ci} 7628c2ecf20Sopenharmony_ci 7638c2ecf20Sopenharmony_ci/* 7648c2ecf20Sopenharmony_ci * Mark an object permanently as gray-colored so that it can no longer be 7658c2ecf20Sopenharmony_ci * reported as a leak. This is used in general to mark a false positive. 7668c2ecf20Sopenharmony_ci */ 7678c2ecf20Sopenharmony_cistatic void make_gray_object(unsigned long ptr) 7688c2ecf20Sopenharmony_ci{ 7698c2ecf20Sopenharmony_ci paint_ptr(ptr, KMEMLEAK_GREY); 7708c2ecf20Sopenharmony_ci} 7718c2ecf20Sopenharmony_ci 7728c2ecf20Sopenharmony_ci/* 7738c2ecf20Sopenharmony_ci * Mark the object as black-colored so that it is ignored from scans and 7748c2ecf20Sopenharmony_ci * reporting. 7758c2ecf20Sopenharmony_ci */ 7768c2ecf20Sopenharmony_cistatic void make_black_object(unsigned long ptr) 7778c2ecf20Sopenharmony_ci{ 7788c2ecf20Sopenharmony_ci paint_ptr(ptr, KMEMLEAK_BLACK); 7798c2ecf20Sopenharmony_ci} 7808c2ecf20Sopenharmony_ci 7818c2ecf20Sopenharmony_ci/* 7828c2ecf20Sopenharmony_ci * Add a scanning area to the object. If at least one such area is added, 7838c2ecf20Sopenharmony_ci * kmemleak will only scan these ranges rather than the whole memory block. 7848c2ecf20Sopenharmony_ci */ 7858c2ecf20Sopenharmony_cistatic void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) 7868c2ecf20Sopenharmony_ci{ 7878c2ecf20Sopenharmony_ci unsigned long flags; 7888c2ecf20Sopenharmony_ci struct kmemleak_object *object; 7898c2ecf20Sopenharmony_ci struct kmemleak_scan_area *area = NULL; 7908c2ecf20Sopenharmony_ci unsigned long untagged_ptr; 7918c2ecf20Sopenharmony_ci unsigned long untagged_objp; 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_ci object = find_and_get_object(ptr, 1); 7948c2ecf20Sopenharmony_ci if (!object) { 7958c2ecf20Sopenharmony_ci kmemleak_warn("Adding scan area to unknown object at 0x%08lx\n", 7968c2ecf20Sopenharmony_ci ptr); 7978c2ecf20Sopenharmony_ci return; 7988c2ecf20Sopenharmony_ci } 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_ci untagged_ptr = (unsigned long)kasan_reset_tag((void *)ptr); 8018c2ecf20Sopenharmony_ci untagged_objp = (unsigned long)kasan_reset_tag((void *)object->pointer); 8028c2ecf20Sopenharmony_ci 8038c2ecf20Sopenharmony_ci if (scan_area_cache) 8048c2ecf20Sopenharmony_ci area = kmem_cache_alloc(scan_area_cache, gfp_kmemleak_mask(gfp)); 8058c2ecf20Sopenharmony_ci 8068c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 8078c2ecf20Sopenharmony_ci if (!area) { 8088c2ecf20Sopenharmony_ci pr_warn_once("Cannot allocate a scan area, scanning the full object\n"); 8098c2ecf20Sopenharmony_ci /* mark the object for full scan to avoid false positives */ 8108c2ecf20Sopenharmony_ci object->flags |= OBJECT_FULL_SCAN; 8118c2ecf20Sopenharmony_ci goto out_unlock; 8128c2ecf20Sopenharmony_ci } 8138c2ecf20Sopenharmony_ci if (size == SIZE_MAX) { 8148c2ecf20Sopenharmony_ci size = untagged_objp + object->size - untagged_ptr; 8158c2ecf20Sopenharmony_ci } else if (untagged_ptr + size > untagged_objp + object->size) { 8168c2ecf20Sopenharmony_ci kmemleak_warn("Scan area larger than object 0x%08lx\n", ptr); 8178c2ecf20Sopenharmony_ci dump_object_info(object); 8188c2ecf20Sopenharmony_ci kmem_cache_free(scan_area_cache, area); 8198c2ecf20Sopenharmony_ci goto out_unlock; 8208c2ecf20Sopenharmony_ci } 8218c2ecf20Sopenharmony_ci 8228c2ecf20Sopenharmony_ci INIT_HLIST_NODE(&area->node); 8238c2ecf20Sopenharmony_ci area->start = ptr; 8248c2ecf20Sopenharmony_ci area->size = size; 8258c2ecf20Sopenharmony_ci 8268c2ecf20Sopenharmony_ci hlist_add_head(&area->node, &object->area_list); 8278c2ecf20Sopenharmony_ciout_unlock: 8288c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 8298c2ecf20Sopenharmony_ci put_object(object); 8308c2ecf20Sopenharmony_ci} 8318c2ecf20Sopenharmony_ci 8328c2ecf20Sopenharmony_ci/* 8338c2ecf20Sopenharmony_ci * Any surplus references (object already gray) to 'ptr' are passed to 8348c2ecf20Sopenharmony_ci * 'excess_ref'. This is used in the vmalloc() case where a pointer to 8358c2ecf20Sopenharmony_ci * vm_struct may be used as an alternative reference to the vmalloc'ed object 8368c2ecf20Sopenharmony_ci * (see free_thread_stack()). 8378c2ecf20Sopenharmony_ci */ 8388c2ecf20Sopenharmony_cistatic void object_set_excess_ref(unsigned long ptr, unsigned long excess_ref) 8398c2ecf20Sopenharmony_ci{ 8408c2ecf20Sopenharmony_ci unsigned long flags; 8418c2ecf20Sopenharmony_ci struct kmemleak_object *object; 8428c2ecf20Sopenharmony_ci 8438c2ecf20Sopenharmony_ci object = find_and_get_object(ptr, 0); 8448c2ecf20Sopenharmony_ci if (!object) { 8458c2ecf20Sopenharmony_ci kmemleak_warn("Setting excess_ref on unknown object at 0x%08lx\n", 8468c2ecf20Sopenharmony_ci ptr); 8478c2ecf20Sopenharmony_ci return; 8488c2ecf20Sopenharmony_ci } 8498c2ecf20Sopenharmony_ci 8508c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 8518c2ecf20Sopenharmony_ci object->excess_ref = excess_ref; 8528c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 8538c2ecf20Sopenharmony_ci put_object(object); 8548c2ecf20Sopenharmony_ci} 8558c2ecf20Sopenharmony_ci 8568c2ecf20Sopenharmony_ci/* 8578c2ecf20Sopenharmony_ci * Set the OBJECT_NO_SCAN flag for the object corresponding to the give 8588c2ecf20Sopenharmony_ci * pointer. Such object will not be scanned by kmemleak but references to it 8598c2ecf20Sopenharmony_ci * are searched. 8608c2ecf20Sopenharmony_ci */ 8618c2ecf20Sopenharmony_cistatic void object_no_scan(unsigned long ptr) 8628c2ecf20Sopenharmony_ci{ 8638c2ecf20Sopenharmony_ci unsigned long flags; 8648c2ecf20Sopenharmony_ci struct kmemleak_object *object; 8658c2ecf20Sopenharmony_ci 8668c2ecf20Sopenharmony_ci object = find_and_get_object(ptr, 0); 8678c2ecf20Sopenharmony_ci if (!object) { 8688c2ecf20Sopenharmony_ci kmemleak_warn("Not scanning unknown object at 0x%08lx\n", ptr); 8698c2ecf20Sopenharmony_ci return; 8708c2ecf20Sopenharmony_ci } 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 8738c2ecf20Sopenharmony_ci object->flags |= OBJECT_NO_SCAN; 8748c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 8758c2ecf20Sopenharmony_ci put_object(object); 8768c2ecf20Sopenharmony_ci} 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci/** 8798c2ecf20Sopenharmony_ci * kmemleak_alloc - register a newly allocated object 8808c2ecf20Sopenharmony_ci * @ptr: pointer to beginning of the object 8818c2ecf20Sopenharmony_ci * @size: size of the object 8828c2ecf20Sopenharmony_ci * @min_count: minimum number of references to this object. If during memory 8838c2ecf20Sopenharmony_ci * scanning a number of references less than @min_count is found, 8848c2ecf20Sopenharmony_ci * the object is reported as a memory leak. If @min_count is 0, 8858c2ecf20Sopenharmony_ci * the object is never reported as a leak. If @min_count is -1, 8868c2ecf20Sopenharmony_ci * the object is ignored (not scanned and not reported as a leak) 8878c2ecf20Sopenharmony_ci * @gfp: kmalloc() flags used for kmemleak internal memory allocations 8888c2ecf20Sopenharmony_ci * 8898c2ecf20Sopenharmony_ci * This function is called from the kernel allocators when a new object 8908c2ecf20Sopenharmony_ci * (memory block) is allocated (kmem_cache_alloc, kmalloc etc.). 8918c2ecf20Sopenharmony_ci */ 8928c2ecf20Sopenharmony_civoid __ref kmemleak_alloc(const void *ptr, size_t size, int min_count, 8938c2ecf20Sopenharmony_ci gfp_t gfp) 8948c2ecf20Sopenharmony_ci{ 8958c2ecf20Sopenharmony_ci pr_debug("%s(0x%p, %zu, %d)\n", __func__, ptr, size, min_count); 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 8988c2ecf20Sopenharmony_ci create_object((unsigned long)ptr, size, min_count, gfp); 8998c2ecf20Sopenharmony_ci} 9008c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_alloc); 9018c2ecf20Sopenharmony_ci 9028c2ecf20Sopenharmony_ci/** 9038c2ecf20Sopenharmony_ci * kmemleak_alloc_percpu - register a newly allocated __percpu object 9048c2ecf20Sopenharmony_ci * @ptr: __percpu pointer to beginning of the object 9058c2ecf20Sopenharmony_ci * @size: size of the object 9068c2ecf20Sopenharmony_ci * @gfp: flags used for kmemleak internal memory allocations 9078c2ecf20Sopenharmony_ci * 9088c2ecf20Sopenharmony_ci * This function is called from the kernel percpu allocator when a new object 9098c2ecf20Sopenharmony_ci * (memory block) is allocated (alloc_percpu). 9108c2ecf20Sopenharmony_ci */ 9118c2ecf20Sopenharmony_civoid __ref kmemleak_alloc_percpu(const void __percpu *ptr, size_t size, 9128c2ecf20Sopenharmony_ci gfp_t gfp) 9138c2ecf20Sopenharmony_ci{ 9148c2ecf20Sopenharmony_ci unsigned int cpu; 9158c2ecf20Sopenharmony_ci 9168c2ecf20Sopenharmony_ci pr_debug("%s(0x%p, %zu)\n", __func__, ptr, size); 9178c2ecf20Sopenharmony_ci 9188c2ecf20Sopenharmony_ci /* 9198c2ecf20Sopenharmony_ci * Percpu allocations are only scanned and not reported as leaks 9208c2ecf20Sopenharmony_ci * (min_count is set to 0). 9218c2ecf20Sopenharmony_ci */ 9228c2ecf20Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 9238c2ecf20Sopenharmony_ci for_each_possible_cpu(cpu) 9248c2ecf20Sopenharmony_ci create_object((unsigned long)per_cpu_ptr(ptr, cpu), 9258c2ecf20Sopenharmony_ci size, 0, gfp); 9268c2ecf20Sopenharmony_ci} 9278c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_alloc_percpu); 9288c2ecf20Sopenharmony_ci 9298c2ecf20Sopenharmony_ci/** 9308c2ecf20Sopenharmony_ci * kmemleak_vmalloc - register a newly vmalloc'ed object 9318c2ecf20Sopenharmony_ci * @area: pointer to vm_struct 9328c2ecf20Sopenharmony_ci * @size: size of the object 9338c2ecf20Sopenharmony_ci * @gfp: __vmalloc() flags used for kmemleak internal memory allocations 9348c2ecf20Sopenharmony_ci * 9358c2ecf20Sopenharmony_ci * This function is called from the vmalloc() kernel allocator when a new 9368c2ecf20Sopenharmony_ci * object (memory block) is allocated. 9378c2ecf20Sopenharmony_ci */ 9388c2ecf20Sopenharmony_civoid __ref kmemleak_vmalloc(const struct vm_struct *area, size_t size, gfp_t gfp) 9398c2ecf20Sopenharmony_ci{ 9408c2ecf20Sopenharmony_ci pr_debug("%s(0x%p, %zu)\n", __func__, area, size); 9418c2ecf20Sopenharmony_ci 9428c2ecf20Sopenharmony_ci /* 9438c2ecf20Sopenharmony_ci * A min_count = 2 is needed because vm_struct contains a reference to 9448c2ecf20Sopenharmony_ci * the virtual address of the vmalloc'ed block. 9458c2ecf20Sopenharmony_ci */ 9468c2ecf20Sopenharmony_ci if (kmemleak_enabled) { 9478c2ecf20Sopenharmony_ci create_object((unsigned long)area->addr, size, 2, gfp); 9488c2ecf20Sopenharmony_ci object_set_excess_ref((unsigned long)area, 9498c2ecf20Sopenharmony_ci (unsigned long)area->addr); 9508c2ecf20Sopenharmony_ci } 9518c2ecf20Sopenharmony_ci} 9528c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_vmalloc); 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_ci/** 9558c2ecf20Sopenharmony_ci * kmemleak_free - unregister a previously registered object 9568c2ecf20Sopenharmony_ci * @ptr: pointer to beginning of the object 9578c2ecf20Sopenharmony_ci * 9588c2ecf20Sopenharmony_ci * This function is called from the kernel allocators when an object (memory 9598c2ecf20Sopenharmony_ci * block) is freed (kmem_cache_free, kfree, vfree etc.). 9608c2ecf20Sopenharmony_ci */ 9618c2ecf20Sopenharmony_civoid __ref kmemleak_free(const void *ptr) 9628c2ecf20Sopenharmony_ci{ 9638c2ecf20Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 9648c2ecf20Sopenharmony_ci 9658c2ecf20Sopenharmony_ci if (kmemleak_free_enabled && ptr && !IS_ERR(ptr)) 9668c2ecf20Sopenharmony_ci delete_object_full((unsigned long)ptr); 9678c2ecf20Sopenharmony_ci} 9688c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_free); 9698c2ecf20Sopenharmony_ci 9708c2ecf20Sopenharmony_ci/** 9718c2ecf20Sopenharmony_ci * kmemleak_free_part - partially unregister a previously registered object 9728c2ecf20Sopenharmony_ci * @ptr: pointer to the beginning or inside the object. This also 9738c2ecf20Sopenharmony_ci * represents the start of the range to be freed 9748c2ecf20Sopenharmony_ci * @size: size to be unregistered 9758c2ecf20Sopenharmony_ci * 9768c2ecf20Sopenharmony_ci * This function is called when only a part of a memory block is freed 9778c2ecf20Sopenharmony_ci * (usually from the bootmem allocator). 9788c2ecf20Sopenharmony_ci */ 9798c2ecf20Sopenharmony_civoid __ref kmemleak_free_part(const void *ptr, size_t size) 9808c2ecf20Sopenharmony_ci{ 9818c2ecf20Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 9828c2ecf20Sopenharmony_ci 9838c2ecf20Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 9848c2ecf20Sopenharmony_ci delete_object_part((unsigned long)ptr, size); 9858c2ecf20Sopenharmony_ci} 9868c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_free_part); 9878c2ecf20Sopenharmony_ci 9888c2ecf20Sopenharmony_ci/** 9898c2ecf20Sopenharmony_ci * kmemleak_free_percpu - unregister a previously registered __percpu object 9908c2ecf20Sopenharmony_ci * @ptr: __percpu pointer to beginning of the object 9918c2ecf20Sopenharmony_ci * 9928c2ecf20Sopenharmony_ci * This function is called from the kernel percpu allocator when an object 9938c2ecf20Sopenharmony_ci * (memory block) is freed (free_percpu). 9948c2ecf20Sopenharmony_ci */ 9958c2ecf20Sopenharmony_civoid __ref kmemleak_free_percpu(const void __percpu *ptr) 9968c2ecf20Sopenharmony_ci{ 9978c2ecf20Sopenharmony_ci unsigned int cpu; 9988c2ecf20Sopenharmony_ci 9998c2ecf20Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 10008c2ecf20Sopenharmony_ci 10018c2ecf20Sopenharmony_ci if (kmemleak_free_enabled && ptr && !IS_ERR(ptr)) 10028c2ecf20Sopenharmony_ci for_each_possible_cpu(cpu) 10038c2ecf20Sopenharmony_ci delete_object_full((unsigned long)per_cpu_ptr(ptr, 10048c2ecf20Sopenharmony_ci cpu)); 10058c2ecf20Sopenharmony_ci} 10068c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_free_percpu); 10078c2ecf20Sopenharmony_ci 10088c2ecf20Sopenharmony_ci/** 10098c2ecf20Sopenharmony_ci * kmemleak_update_trace - update object allocation stack trace 10108c2ecf20Sopenharmony_ci * @ptr: pointer to beginning of the object 10118c2ecf20Sopenharmony_ci * 10128c2ecf20Sopenharmony_ci * Override the object allocation stack trace for cases where the actual 10138c2ecf20Sopenharmony_ci * allocation place is not always useful. 10148c2ecf20Sopenharmony_ci */ 10158c2ecf20Sopenharmony_civoid __ref kmemleak_update_trace(const void *ptr) 10168c2ecf20Sopenharmony_ci{ 10178c2ecf20Sopenharmony_ci struct kmemleak_object *object; 10188c2ecf20Sopenharmony_ci unsigned long flags; 10198c2ecf20Sopenharmony_ci 10208c2ecf20Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 10218c2ecf20Sopenharmony_ci 10228c2ecf20Sopenharmony_ci if (!kmemleak_enabled || IS_ERR_OR_NULL(ptr)) 10238c2ecf20Sopenharmony_ci return; 10248c2ecf20Sopenharmony_ci 10258c2ecf20Sopenharmony_ci object = find_and_get_object((unsigned long)ptr, 1); 10268c2ecf20Sopenharmony_ci if (!object) { 10278c2ecf20Sopenharmony_ci#ifdef DEBUG 10288c2ecf20Sopenharmony_ci kmemleak_warn("Updating stack trace for unknown object at %p\n", 10298c2ecf20Sopenharmony_ci ptr); 10308c2ecf20Sopenharmony_ci#endif 10318c2ecf20Sopenharmony_ci return; 10328c2ecf20Sopenharmony_ci } 10338c2ecf20Sopenharmony_ci 10348c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 10358c2ecf20Sopenharmony_ci object->trace_len = __save_stack_trace(object->trace); 10368c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 10378c2ecf20Sopenharmony_ci 10388c2ecf20Sopenharmony_ci put_object(object); 10398c2ecf20Sopenharmony_ci} 10408c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmemleak_update_trace); 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_ci/** 10438c2ecf20Sopenharmony_ci * kmemleak_not_leak - mark an allocated object as false positive 10448c2ecf20Sopenharmony_ci * @ptr: pointer to beginning of the object 10458c2ecf20Sopenharmony_ci * 10468c2ecf20Sopenharmony_ci * Calling this function on an object will cause the memory block to no longer 10478c2ecf20Sopenharmony_ci * be reported as leak and always be scanned. 10488c2ecf20Sopenharmony_ci */ 10498c2ecf20Sopenharmony_civoid __ref kmemleak_not_leak(const void *ptr) 10508c2ecf20Sopenharmony_ci{ 10518c2ecf20Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 10528c2ecf20Sopenharmony_ci 10538c2ecf20Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 10548c2ecf20Sopenharmony_ci make_gray_object((unsigned long)ptr); 10558c2ecf20Sopenharmony_ci} 10568c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmemleak_not_leak); 10578c2ecf20Sopenharmony_ci 10588c2ecf20Sopenharmony_ci/** 10598c2ecf20Sopenharmony_ci * kmemleak_ignore - ignore an allocated object 10608c2ecf20Sopenharmony_ci * @ptr: pointer to beginning of the object 10618c2ecf20Sopenharmony_ci * 10628c2ecf20Sopenharmony_ci * Calling this function on an object will cause the memory block to be 10638c2ecf20Sopenharmony_ci * ignored (not scanned and not reported as a leak). This is usually done when 10648c2ecf20Sopenharmony_ci * it is known that the corresponding block is not a leak and does not contain 10658c2ecf20Sopenharmony_ci * any references to other allocated memory blocks. 10668c2ecf20Sopenharmony_ci */ 10678c2ecf20Sopenharmony_civoid __ref kmemleak_ignore(const void *ptr) 10688c2ecf20Sopenharmony_ci{ 10698c2ecf20Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 10708c2ecf20Sopenharmony_ci 10718c2ecf20Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 10728c2ecf20Sopenharmony_ci make_black_object((unsigned long)ptr); 10738c2ecf20Sopenharmony_ci} 10748c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmemleak_ignore); 10758c2ecf20Sopenharmony_ci 10768c2ecf20Sopenharmony_ci/** 10778c2ecf20Sopenharmony_ci * kmemleak_scan_area - limit the range to be scanned in an allocated object 10788c2ecf20Sopenharmony_ci * @ptr: pointer to beginning or inside the object. This also 10798c2ecf20Sopenharmony_ci * represents the start of the scan area 10808c2ecf20Sopenharmony_ci * @size: size of the scan area 10818c2ecf20Sopenharmony_ci * @gfp: kmalloc() flags used for kmemleak internal memory allocations 10828c2ecf20Sopenharmony_ci * 10838c2ecf20Sopenharmony_ci * This function is used when it is known that only certain parts of an object 10848c2ecf20Sopenharmony_ci * contain references to other objects. Kmemleak will only scan these areas 10858c2ecf20Sopenharmony_ci * reducing the number false negatives. 10868c2ecf20Sopenharmony_ci */ 10878c2ecf20Sopenharmony_civoid __ref kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) 10888c2ecf20Sopenharmony_ci{ 10898c2ecf20Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 10908c2ecf20Sopenharmony_ci 10918c2ecf20Sopenharmony_ci if (kmemleak_enabled && ptr && size && !IS_ERR(ptr)) 10928c2ecf20Sopenharmony_ci add_scan_area((unsigned long)ptr, size, gfp); 10938c2ecf20Sopenharmony_ci} 10948c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmemleak_scan_area); 10958c2ecf20Sopenharmony_ci 10968c2ecf20Sopenharmony_ci/** 10978c2ecf20Sopenharmony_ci * kmemleak_no_scan - do not scan an allocated object 10988c2ecf20Sopenharmony_ci * @ptr: pointer to beginning of the object 10998c2ecf20Sopenharmony_ci * 11008c2ecf20Sopenharmony_ci * This function notifies kmemleak not to scan the given memory block. Useful 11018c2ecf20Sopenharmony_ci * in situations where it is known that the given object does not contain any 11028c2ecf20Sopenharmony_ci * references to other objects. Kmemleak will not scan such objects reducing 11038c2ecf20Sopenharmony_ci * the number of false negatives. 11048c2ecf20Sopenharmony_ci */ 11058c2ecf20Sopenharmony_civoid __ref kmemleak_no_scan(const void *ptr) 11068c2ecf20Sopenharmony_ci{ 11078c2ecf20Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 11088c2ecf20Sopenharmony_ci 11098c2ecf20Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 11108c2ecf20Sopenharmony_ci object_no_scan((unsigned long)ptr); 11118c2ecf20Sopenharmony_ci} 11128c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmemleak_no_scan); 11138c2ecf20Sopenharmony_ci 11148c2ecf20Sopenharmony_ci/** 11158c2ecf20Sopenharmony_ci * kmemleak_alloc_phys - similar to kmemleak_alloc but taking a physical 11168c2ecf20Sopenharmony_ci * address argument 11178c2ecf20Sopenharmony_ci * @phys: physical address of the object 11188c2ecf20Sopenharmony_ci * @size: size of the object 11198c2ecf20Sopenharmony_ci * @min_count: minimum number of references to this object. 11208c2ecf20Sopenharmony_ci * See kmemleak_alloc() 11218c2ecf20Sopenharmony_ci * @gfp: kmalloc() flags used for kmemleak internal memory allocations 11228c2ecf20Sopenharmony_ci */ 11238c2ecf20Sopenharmony_civoid __ref kmemleak_alloc_phys(phys_addr_t phys, size_t size, int min_count, 11248c2ecf20Sopenharmony_ci gfp_t gfp) 11258c2ecf20Sopenharmony_ci{ 11268c2ecf20Sopenharmony_ci if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn) 11278c2ecf20Sopenharmony_ci kmemleak_alloc(__va(phys), size, min_count, gfp); 11288c2ecf20Sopenharmony_ci} 11298c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmemleak_alloc_phys); 11308c2ecf20Sopenharmony_ci 11318c2ecf20Sopenharmony_ci/** 11328c2ecf20Sopenharmony_ci * kmemleak_free_part_phys - similar to kmemleak_free_part but taking a 11338c2ecf20Sopenharmony_ci * physical address argument 11348c2ecf20Sopenharmony_ci * @phys: physical address if the beginning or inside an object. This 11358c2ecf20Sopenharmony_ci * also represents the start of the range to be freed 11368c2ecf20Sopenharmony_ci * @size: size to be unregistered 11378c2ecf20Sopenharmony_ci */ 11388c2ecf20Sopenharmony_civoid __ref kmemleak_free_part_phys(phys_addr_t phys, size_t size) 11398c2ecf20Sopenharmony_ci{ 11408c2ecf20Sopenharmony_ci if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn) 11418c2ecf20Sopenharmony_ci kmemleak_free_part(__va(phys), size); 11428c2ecf20Sopenharmony_ci} 11438c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmemleak_free_part_phys); 11448c2ecf20Sopenharmony_ci 11458c2ecf20Sopenharmony_ci/** 11468c2ecf20Sopenharmony_ci * kmemleak_not_leak_phys - similar to kmemleak_not_leak but taking a physical 11478c2ecf20Sopenharmony_ci * address argument 11488c2ecf20Sopenharmony_ci * @phys: physical address of the object 11498c2ecf20Sopenharmony_ci */ 11508c2ecf20Sopenharmony_civoid __ref kmemleak_not_leak_phys(phys_addr_t phys) 11518c2ecf20Sopenharmony_ci{ 11528c2ecf20Sopenharmony_ci if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn) 11538c2ecf20Sopenharmony_ci kmemleak_not_leak(__va(phys)); 11548c2ecf20Sopenharmony_ci} 11558c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmemleak_not_leak_phys); 11568c2ecf20Sopenharmony_ci 11578c2ecf20Sopenharmony_ci/** 11588c2ecf20Sopenharmony_ci * kmemleak_ignore_phys - similar to kmemleak_ignore but taking a physical 11598c2ecf20Sopenharmony_ci * address argument 11608c2ecf20Sopenharmony_ci * @phys: physical address of the object 11618c2ecf20Sopenharmony_ci */ 11628c2ecf20Sopenharmony_civoid __ref kmemleak_ignore_phys(phys_addr_t phys) 11638c2ecf20Sopenharmony_ci{ 11648c2ecf20Sopenharmony_ci if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn) 11658c2ecf20Sopenharmony_ci kmemleak_ignore(__va(phys)); 11668c2ecf20Sopenharmony_ci} 11678c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmemleak_ignore_phys); 11688c2ecf20Sopenharmony_ci 11698c2ecf20Sopenharmony_ci/* 11708c2ecf20Sopenharmony_ci * Update an object's checksum and return true if it was modified. 11718c2ecf20Sopenharmony_ci */ 11728c2ecf20Sopenharmony_cistatic bool update_checksum(struct kmemleak_object *object) 11738c2ecf20Sopenharmony_ci{ 11748c2ecf20Sopenharmony_ci u32 old_csum = object->checksum; 11758c2ecf20Sopenharmony_ci 11768c2ecf20Sopenharmony_ci kasan_disable_current(); 11778c2ecf20Sopenharmony_ci kcsan_disable_current(); 11788c2ecf20Sopenharmony_ci object->checksum = crc32(0, (void *)object->pointer, object->size); 11798c2ecf20Sopenharmony_ci kasan_enable_current(); 11808c2ecf20Sopenharmony_ci kcsan_enable_current(); 11818c2ecf20Sopenharmony_ci 11828c2ecf20Sopenharmony_ci return object->checksum != old_csum; 11838c2ecf20Sopenharmony_ci} 11848c2ecf20Sopenharmony_ci 11858c2ecf20Sopenharmony_ci/* 11868c2ecf20Sopenharmony_ci * Update an object's references. object->lock must be held by the caller. 11878c2ecf20Sopenharmony_ci */ 11888c2ecf20Sopenharmony_cistatic void update_refs(struct kmemleak_object *object) 11898c2ecf20Sopenharmony_ci{ 11908c2ecf20Sopenharmony_ci if (!color_white(object)) { 11918c2ecf20Sopenharmony_ci /* non-orphan, ignored or new */ 11928c2ecf20Sopenharmony_ci return; 11938c2ecf20Sopenharmony_ci } 11948c2ecf20Sopenharmony_ci 11958c2ecf20Sopenharmony_ci /* 11968c2ecf20Sopenharmony_ci * Increase the object's reference count (number of pointers to the 11978c2ecf20Sopenharmony_ci * memory block). If this count reaches the required minimum, the 11988c2ecf20Sopenharmony_ci * object's color will become gray and it will be added to the 11998c2ecf20Sopenharmony_ci * gray_list. 12008c2ecf20Sopenharmony_ci */ 12018c2ecf20Sopenharmony_ci object->count++; 12028c2ecf20Sopenharmony_ci if (color_gray(object)) { 12038c2ecf20Sopenharmony_ci /* put_object() called when removing from gray_list */ 12048c2ecf20Sopenharmony_ci WARN_ON(!get_object(object)); 12058c2ecf20Sopenharmony_ci list_add_tail(&object->gray_list, &gray_list); 12068c2ecf20Sopenharmony_ci } 12078c2ecf20Sopenharmony_ci} 12088c2ecf20Sopenharmony_ci 12098c2ecf20Sopenharmony_ci/* 12108c2ecf20Sopenharmony_ci * Memory scanning is a long process and it needs to be interruptable. This 12118c2ecf20Sopenharmony_ci * function checks whether such interrupt condition occurred. 12128c2ecf20Sopenharmony_ci */ 12138c2ecf20Sopenharmony_cistatic int scan_should_stop(void) 12148c2ecf20Sopenharmony_ci{ 12158c2ecf20Sopenharmony_ci if (!kmemleak_enabled) 12168c2ecf20Sopenharmony_ci return 1; 12178c2ecf20Sopenharmony_ci 12188c2ecf20Sopenharmony_ci /* 12198c2ecf20Sopenharmony_ci * This function may be called from either process or kthread context, 12208c2ecf20Sopenharmony_ci * hence the need to check for both stop conditions. 12218c2ecf20Sopenharmony_ci */ 12228c2ecf20Sopenharmony_ci if (current->mm) 12238c2ecf20Sopenharmony_ci return signal_pending(current); 12248c2ecf20Sopenharmony_ci else 12258c2ecf20Sopenharmony_ci return kthread_should_stop(); 12268c2ecf20Sopenharmony_ci 12278c2ecf20Sopenharmony_ci return 0; 12288c2ecf20Sopenharmony_ci} 12298c2ecf20Sopenharmony_ci 12308c2ecf20Sopenharmony_ci/* 12318c2ecf20Sopenharmony_ci * Scan a memory block (exclusive range) for valid pointers and add those 12328c2ecf20Sopenharmony_ci * found to the gray list. 12338c2ecf20Sopenharmony_ci */ 12348c2ecf20Sopenharmony_cistatic void scan_block(void *_start, void *_end, 12358c2ecf20Sopenharmony_ci struct kmemleak_object *scanned) 12368c2ecf20Sopenharmony_ci{ 12378c2ecf20Sopenharmony_ci unsigned long *ptr; 12388c2ecf20Sopenharmony_ci unsigned long *start = PTR_ALIGN(_start, BYTES_PER_POINTER); 12398c2ecf20Sopenharmony_ci unsigned long *end = _end - (BYTES_PER_POINTER - 1); 12408c2ecf20Sopenharmony_ci unsigned long flags; 12418c2ecf20Sopenharmony_ci unsigned long untagged_ptr; 12428c2ecf20Sopenharmony_ci 12438c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 12448c2ecf20Sopenharmony_ci for (ptr = start; ptr < end; ptr++) { 12458c2ecf20Sopenharmony_ci struct kmemleak_object *object; 12468c2ecf20Sopenharmony_ci unsigned long pointer; 12478c2ecf20Sopenharmony_ci unsigned long excess_ref; 12488c2ecf20Sopenharmony_ci 12498c2ecf20Sopenharmony_ci if (scan_should_stop()) 12508c2ecf20Sopenharmony_ci break; 12518c2ecf20Sopenharmony_ci 12528c2ecf20Sopenharmony_ci kasan_disable_current(); 12538c2ecf20Sopenharmony_ci pointer = *ptr; 12548c2ecf20Sopenharmony_ci kasan_enable_current(); 12558c2ecf20Sopenharmony_ci 12568c2ecf20Sopenharmony_ci untagged_ptr = (unsigned long)kasan_reset_tag((void *)pointer); 12578c2ecf20Sopenharmony_ci if (untagged_ptr < min_addr || untagged_ptr >= max_addr) 12588c2ecf20Sopenharmony_ci continue; 12598c2ecf20Sopenharmony_ci 12608c2ecf20Sopenharmony_ci /* 12618c2ecf20Sopenharmony_ci * No need for get_object() here since we hold kmemleak_lock. 12628c2ecf20Sopenharmony_ci * object->use_count cannot be dropped to 0 while the object 12638c2ecf20Sopenharmony_ci * is still present in object_tree_root and object_list 12648c2ecf20Sopenharmony_ci * (with updates protected by kmemleak_lock). 12658c2ecf20Sopenharmony_ci */ 12668c2ecf20Sopenharmony_ci object = lookup_object(pointer, 1); 12678c2ecf20Sopenharmony_ci if (!object) 12688c2ecf20Sopenharmony_ci continue; 12698c2ecf20Sopenharmony_ci if (object == scanned) 12708c2ecf20Sopenharmony_ci /* self referenced, ignore */ 12718c2ecf20Sopenharmony_ci continue; 12728c2ecf20Sopenharmony_ci 12738c2ecf20Sopenharmony_ci /* 12748c2ecf20Sopenharmony_ci * Avoid the lockdep recursive warning on object->lock being 12758c2ecf20Sopenharmony_ci * previously acquired in scan_object(). These locks are 12768c2ecf20Sopenharmony_ci * enclosed by scan_mutex. 12778c2ecf20Sopenharmony_ci */ 12788c2ecf20Sopenharmony_ci raw_spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); 12798c2ecf20Sopenharmony_ci /* only pass surplus references (object already gray) */ 12808c2ecf20Sopenharmony_ci if (color_gray(object)) { 12818c2ecf20Sopenharmony_ci excess_ref = object->excess_ref; 12828c2ecf20Sopenharmony_ci /* no need for update_refs() if object already gray */ 12838c2ecf20Sopenharmony_ci } else { 12848c2ecf20Sopenharmony_ci excess_ref = 0; 12858c2ecf20Sopenharmony_ci update_refs(object); 12868c2ecf20Sopenharmony_ci } 12878c2ecf20Sopenharmony_ci raw_spin_unlock(&object->lock); 12888c2ecf20Sopenharmony_ci 12898c2ecf20Sopenharmony_ci if (excess_ref) { 12908c2ecf20Sopenharmony_ci object = lookup_object(excess_ref, 0); 12918c2ecf20Sopenharmony_ci if (!object) 12928c2ecf20Sopenharmony_ci continue; 12938c2ecf20Sopenharmony_ci if (object == scanned) 12948c2ecf20Sopenharmony_ci /* circular reference, ignore */ 12958c2ecf20Sopenharmony_ci continue; 12968c2ecf20Sopenharmony_ci raw_spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); 12978c2ecf20Sopenharmony_ci update_refs(object); 12988c2ecf20Sopenharmony_ci raw_spin_unlock(&object->lock); 12998c2ecf20Sopenharmony_ci } 13008c2ecf20Sopenharmony_ci } 13018c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 13028c2ecf20Sopenharmony_ci} 13038c2ecf20Sopenharmony_ci 13048c2ecf20Sopenharmony_ci/* 13058c2ecf20Sopenharmony_ci * Scan a large memory block in MAX_SCAN_SIZE chunks to reduce the latency. 13068c2ecf20Sopenharmony_ci */ 13078c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 13088c2ecf20Sopenharmony_cistatic void scan_large_block(void *start, void *end) 13098c2ecf20Sopenharmony_ci{ 13108c2ecf20Sopenharmony_ci void *next; 13118c2ecf20Sopenharmony_ci 13128c2ecf20Sopenharmony_ci while (start < end) { 13138c2ecf20Sopenharmony_ci next = min(start + MAX_SCAN_SIZE, end); 13148c2ecf20Sopenharmony_ci scan_block(start, next, NULL); 13158c2ecf20Sopenharmony_ci start = next; 13168c2ecf20Sopenharmony_ci cond_resched(); 13178c2ecf20Sopenharmony_ci } 13188c2ecf20Sopenharmony_ci} 13198c2ecf20Sopenharmony_ci#endif 13208c2ecf20Sopenharmony_ci 13218c2ecf20Sopenharmony_ci/* 13228c2ecf20Sopenharmony_ci * Scan a memory block corresponding to a kmemleak_object. A condition is 13238c2ecf20Sopenharmony_ci * that object->use_count >= 1. 13248c2ecf20Sopenharmony_ci */ 13258c2ecf20Sopenharmony_cistatic void scan_object(struct kmemleak_object *object) 13268c2ecf20Sopenharmony_ci{ 13278c2ecf20Sopenharmony_ci struct kmemleak_scan_area *area; 13288c2ecf20Sopenharmony_ci unsigned long flags; 13298c2ecf20Sopenharmony_ci 13308c2ecf20Sopenharmony_ci /* 13318c2ecf20Sopenharmony_ci * Once the object->lock is acquired, the corresponding memory block 13328c2ecf20Sopenharmony_ci * cannot be freed (the same lock is acquired in delete_object). 13338c2ecf20Sopenharmony_ci */ 13348c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 13358c2ecf20Sopenharmony_ci if (object->flags & OBJECT_NO_SCAN) 13368c2ecf20Sopenharmony_ci goto out; 13378c2ecf20Sopenharmony_ci if (!(object->flags & OBJECT_ALLOCATED)) 13388c2ecf20Sopenharmony_ci /* already freed object */ 13398c2ecf20Sopenharmony_ci goto out; 13408c2ecf20Sopenharmony_ci if (hlist_empty(&object->area_list) || 13418c2ecf20Sopenharmony_ci object->flags & OBJECT_FULL_SCAN) { 13428c2ecf20Sopenharmony_ci void *start = (void *)object->pointer; 13438c2ecf20Sopenharmony_ci void *end = (void *)(object->pointer + object->size); 13448c2ecf20Sopenharmony_ci void *next; 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_ci do { 13478c2ecf20Sopenharmony_ci next = min(start + MAX_SCAN_SIZE, end); 13488c2ecf20Sopenharmony_ci scan_block(start, next, object); 13498c2ecf20Sopenharmony_ci 13508c2ecf20Sopenharmony_ci start = next; 13518c2ecf20Sopenharmony_ci if (start >= end) 13528c2ecf20Sopenharmony_ci break; 13538c2ecf20Sopenharmony_ci 13548c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 13558c2ecf20Sopenharmony_ci cond_resched(); 13568c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 13578c2ecf20Sopenharmony_ci } while (object->flags & OBJECT_ALLOCATED); 13588c2ecf20Sopenharmony_ci } else 13598c2ecf20Sopenharmony_ci hlist_for_each_entry(area, &object->area_list, node) 13608c2ecf20Sopenharmony_ci scan_block((void *)area->start, 13618c2ecf20Sopenharmony_ci (void *)(area->start + area->size), 13628c2ecf20Sopenharmony_ci object); 13638c2ecf20Sopenharmony_ciout: 13648c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 13658c2ecf20Sopenharmony_ci} 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_ci/* 13688c2ecf20Sopenharmony_ci * Scan the objects already referenced (gray objects). More objects will be 13698c2ecf20Sopenharmony_ci * referenced and, if there are no memory leaks, all the objects are scanned. 13708c2ecf20Sopenharmony_ci */ 13718c2ecf20Sopenharmony_cistatic void scan_gray_list(void) 13728c2ecf20Sopenharmony_ci{ 13738c2ecf20Sopenharmony_ci struct kmemleak_object *object, *tmp; 13748c2ecf20Sopenharmony_ci 13758c2ecf20Sopenharmony_ci /* 13768c2ecf20Sopenharmony_ci * The list traversal is safe for both tail additions and removals 13778c2ecf20Sopenharmony_ci * from inside the loop. The kmemleak objects cannot be freed from 13788c2ecf20Sopenharmony_ci * outside the loop because their use_count was incremented. 13798c2ecf20Sopenharmony_ci */ 13808c2ecf20Sopenharmony_ci object = list_entry(gray_list.next, typeof(*object), gray_list); 13818c2ecf20Sopenharmony_ci while (&object->gray_list != &gray_list) { 13828c2ecf20Sopenharmony_ci cond_resched(); 13838c2ecf20Sopenharmony_ci 13848c2ecf20Sopenharmony_ci /* may add new objects to the list */ 13858c2ecf20Sopenharmony_ci if (!scan_should_stop()) 13868c2ecf20Sopenharmony_ci scan_object(object); 13878c2ecf20Sopenharmony_ci 13888c2ecf20Sopenharmony_ci tmp = list_entry(object->gray_list.next, typeof(*object), 13898c2ecf20Sopenharmony_ci gray_list); 13908c2ecf20Sopenharmony_ci 13918c2ecf20Sopenharmony_ci /* remove the object from the list and release it */ 13928c2ecf20Sopenharmony_ci list_del(&object->gray_list); 13938c2ecf20Sopenharmony_ci put_object(object); 13948c2ecf20Sopenharmony_ci 13958c2ecf20Sopenharmony_ci object = tmp; 13968c2ecf20Sopenharmony_ci } 13978c2ecf20Sopenharmony_ci WARN_ON(!list_empty(&gray_list)); 13988c2ecf20Sopenharmony_ci} 13998c2ecf20Sopenharmony_ci 14008c2ecf20Sopenharmony_ci/* 14018c2ecf20Sopenharmony_ci * Scan data sections and all the referenced memory blocks allocated via the 14028c2ecf20Sopenharmony_ci * kernel's standard allocators. This function must be called with the 14038c2ecf20Sopenharmony_ci * scan_mutex held. 14048c2ecf20Sopenharmony_ci */ 14058c2ecf20Sopenharmony_cistatic void kmemleak_scan(void) 14068c2ecf20Sopenharmony_ci{ 14078c2ecf20Sopenharmony_ci unsigned long flags; 14088c2ecf20Sopenharmony_ci struct kmemleak_object *object; 14098c2ecf20Sopenharmony_ci struct zone *zone; 14108c2ecf20Sopenharmony_ci int __maybe_unused i; 14118c2ecf20Sopenharmony_ci int new_leaks = 0; 14128c2ecf20Sopenharmony_ci 14138c2ecf20Sopenharmony_ci jiffies_last_scan = jiffies; 14148c2ecf20Sopenharmony_ci 14158c2ecf20Sopenharmony_ci /* prepare the kmemleak_object's */ 14168c2ecf20Sopenharmony_ci rcu_read_lock(); 14178c2ecf20Sopenharmony_ci list_for_each_entry_rcu(object, &object_list, object_list) { 14188c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 14198c2ecf20Sopenharmony_ci#ifdef DEBUG 14208c2ecf20Sopenharmony_ci /* 14218c2ecf20Sopenharmony_ci * With a few exceptions there should be a maximum of 14228c2ecf20Sopenharmony_ci * 1 reference to any object at this point. 14238c2ecf20Sopenharmony_ci */ 14248c2ecf20Sopenharmony_ci if (atomic_read(&object->use_count) > 1) { 14258c2ecf20Sopenharmony_ci pr_debug("object->use_count = %d\n", 14268c2ecf20Sopenharmony_ci atomic_read(&object->use_count)); 14278c2ecf20Sopenharmony_ci dump_object_info(object); 14288c2ecf20Sopenharmony_ci } 14298c2ecf20Sopenharmony_ci#endif 14308c2ecf20Sopenharmony_ci /* reset the reference count (whiten the object) */ 14318c2ecf20Sopenharmony_ci object->count = 0; 14328c2ecf20Sopenharmony_ci if (color_gray(object) && get_object(object)) 14338c2ecf20Sopenharmony_ci list_add_tail(&object->gray_list, &gray_list); 14348c2ecf20Sopenharmony_ci 14358c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 14368c2ecf20Sopenharmony_ci } 14378c2ecf20Sopenharmony_ci rcu_read_unlock(); 14388c2ecf20Sopenharmony_ci 14398c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 14408c2ecf20Sopenharmony_ci /* per-cpu sections scanning */ 14418c2ecf20Sopenharmony_ci for_each_possible_cpu(i) 14428c2ecf20Sopenharmony_ci scan_large_block(__per_cpu_start + per_cpu_offset(i), 14438c2ecf20Sopenharmony_ci __per_cpu_end + per_cpu_offset(i)); 14448c2ecf20Sopenharmony_ci#endif 14458c2ecf20Sopenharmony_ci 14468c2ecf20Sopenharmony_ci /* 14478c2ecf20Sopenharmony_ci * Struct page scanning for each node. 14488c2ecf20Sopenharmony_ci */ 14498c2ecf20Sopenharmony_ci get_online_mems(); 14508c2ecf20Sopenharmony_ci for_each_populated_zone(zone) { 14518c2ecf20Sopenharmony_ci unsigned long start_pfn = zone->zone_start_pfn; 14528c2ecf20Sopenharmony_ci unsigned long end_pfn = zone_end_pfn(zone); 14538c2ecf20Sopenharmony_ci unsigned long pfn; 14548c2ecf20Sopenharmony_ci 14558c2ecf20Sopenharmony_ci for (pfn = start_pfn; pfn < end_pfn; pfn++) { 14568c2ecf20Sopenharmony_ci struct page *page = pfn_to_online_page(pfn); 14578c2ecf20Sopenharmony_ci 14588c2ecf20Sopenharmony_ci if (!page) 14598c2ecf20Sopenharmony_ci continue; 14608c2ecf20Sopenharmony_ci 14618c2ecf20Sopenharmony_ci /* only scan pages belonging to this zone */ 14628c2ecf20Sopenharmony_ci if (page_zone(page) != zone) 14638c2ecf20Sopenharmony_ci continue; 14648c2ecf20Sopenharmony_ci /* only scan if page is in use */ 14658c2ecf20Sopenharmony_ci if (page_count(page) == 0) 14668c2ecf20Sopenharmony_ci continue; 14678c2ecf20Sopenharmony_ci scan_block(page, page + 1, NULL); 14688c2ecf20Sopenharmony_ci if (!(pfn & 63)) 14698c2ecf20Sopenharmony_ci cond_resched(); 14708c2ecf20Sopenharmony_ci } 14718c2ecf20Sopenharmony_ci } 14728c2ecf20Sopenharmony_ci put_online_mems(); 14738c2ecf20Sopenharmony_ci 14748c2ecf20Sopenharmony_ci /* 14758c2ecf20Sopenharmony_ci * Scanning the task stacks (may introduce false negatives). 14768c2ecf20Sopenharmony_ci */ 14778c2ecf20Sopenharmony_ci if (kmemleak_stack_scan) { 14788c2ecf20Sopenharmony_ci struct task_struct *p, *g; 14798c2ecf20Sopenharmony_ci 14808c2ecf20Sopenharmony_ci rcu_read_lock(); 14818c2ecf20Sopenharmony_ci for_each_process_thread(g, p) { 14828c2ecf20Sopenharmony_ci void *stack = try_get_task_stack(p); 14838c2ecf20Sopenharmony_ci if (stack) { 14848c2ecf20Sopenharmony_ci scan_block(stack, stack + THREAD_SIZE, NULL); 14858c2ecf20Sopenharmony_ci put_task_stack(p); 14868c2ecf20Sopenharmony_ci } 14878c2ecf20Sopenharmony_ci } 14888c2ecf20Sopenharmony_ci rcu_read_unlock(); 14898c2ecf20Sopenharmony_ci } 14908c2ecf20Sopenharmony_ci 14918c2ecf20Sopenharmony_ci /* 14928c2ecf20Sopenharmony_ci * Scan the objects already referenced from the sections scanned 14938c2ecf20Sopenharmony_ci * above. 14948c2ecf20Sopenharmony_ci */ 14958c2ecf20Sopenharmony_ci scan_gray_list(); 14968c2ecf20Sopenharmony_ci 14978c2ecf20Sopenharmony_ci /* 14988c2ecf20Sopenharmony_ci * Check for new or unreferenced objects modified since the previous 14998c2ecf20Sopenharmony_ci * scan and color them gray until the next scan. 15008c2ecf20Sopenharmony_ci */ 15018c2ecf20Sopenharmony_ci rcu_read_lock(); 15028c2ecf20Sopenharmony_ci list_for_each_entry_rcu(object, &object_list, object_list) { 15038c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 15048c2ecf20Sopenharmony_ci if (color_white(object) && (object->flags & OBJECT_ALLOCATED) 15058c2ecf20Sopenharmony_ci && update_checksum(object) && get_object(object)) { 15068c2ecf20Sopenharmony_ci /* color it gray temporarily */ 15078c2ecf20Sopenharmony_ci object->count = object->min_count; 15088c2ecf20Sopenharmony_ci list_add_tail(&object->gray_list, &gray_list); 15098c2ecf20Sopenharmony_ci } 15108c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 15118c2ecf20Sopenharmony_ci } 15128c2ecf20Sopenharmony_ci rcu_read_unlock(); 15138c2ecf20Sopenharmony_ci 15148c2ecf20Sopenharmony_ci /* 15158c2ecf20Sopenharmony_ci * Re-scan the gray list for modified unreferenced objects. 15168c2ecf20Sopenharmony_ci */ 15178c2ecf20Sopenharmony_ci scan_gray_list(); 15188c2ecf20Sopenharmony_ci 15198c2ecf20Sopenharmony_ci /* 15208c2ecf20Sopenharmony_ci * If scanning was stopped do not report any new unreferenced objects. 15218c2ecf20Sopenharmony_ci */ 15228c2ecf20Sopenharmony_ci if (scan_should_stop()) 15238c2ecf20Sopenharmony_ci return; 15248c2ecf20Sopenharmony_ci 15258c2ecf20Sopenharmony_ci /* 15268c2ecf20Sopenharmony_ci * Scanning result reporting. 15278c2ecf20Sopenharmony_ci */ 15288c2ecf20Sopenharmony_ci rcu_read_lock(); 15298c2ecf20Sopenharmony_ci list_for_each_entry_rcu(object, &object_list, object_list) { 15308c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 15318c2ecf20Sopenharmony_ci if (unreferenced_object(object) && 15328c2ecf20Sopenharmony_ci !(object->flags & OBJECT_REPORTED)) { 15338c2ecf20Sopenharmony_ci object->flags |= OBJECT_REPORTED; 15348c2ecf20Sopenharmony_ci 15358c2ecf20Sopenharmony_ci if (kmemleak_verbose) 15368c2ecf20Sopenharmony_ci print_unreferenced(NULL, object); 15378c2ecf20Sopenharmony_ci 15388c2ecf20Sopenharmony_ci new_leaks++; 15398c2ecf20Sopenharmony_ci } 15408c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 15418c2ecf20Sopenharmony_ci } 15428c2ecf20Sopenharmony_ci rcu_read_unlock(); 15438c2ecf20Sopenharmony_ci 15448c2ecf20Sopenharmony_ci if (new_leaks) { 15458c2ecf20Sopenharmony_ci kmemleak_found_leaks = true; 15468c2ecf20Sopenharmony_ci 15478c2ecf20Sopenharmony_ci pr_info("%d new suspected memory leaks (see /sys/kernel/debug/kmemleak)\n", 15488c2ecf20Sopenharmony_ci new_leaks); 15498c2ecf20Sopenharmony_ci } 15508c2ecf20Sopenharmony_ci 15518c2ecf20Sopenharmony_ci} 15528c2ecf20Sopenharmony_ci 15538c2ecf20Sopenharmony_ci/* 15548c2ecf20Sopenharmony_ci * Thread function performing automatic memory scanning. Unreferenced objects 15558c2ecf20Sopenharmony_ci * at the end of a memory scan are reported but only the first time. 15568c2ecf20Sopenharmony_ci */ 15578c2ecf20Sopenharmony_cistatic int kmemleak_scan_thread(void *arg) 15588c2ecf20Sopenharmony_ci{ 15598c2ecf20Sopenharmony_ci static int first_run = IS_ENABLED(CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN); 15608c2ecf20Sopenharmony_ci 15618c2ecf20Sopenharmony_ci pr_info("Automatic memory scanning thread started\n"); 15628c2ecf20Sopenharmony_ci set_user_nice(current, 10); 15638c2ecf20Sopenharmony_ci 15648c2ecf20Sopenharmony_ci /* 15658c2ecf20Sopenharmony_ci * Wait before the first scan to allow the system to fully initialize. 15668c2ecf20Sopenharmony_ci */ 15678c2ecf20Sopenharmony_ci if (first_run) { 15688c2ecf20Sopenharmony_ci signed long timeout = msecs_to_jiffies(SECS_FIRST_SCAN * 1000); 15698c2ecf20Sopenharmony_ci first_run = 0; 15708c2ecf20Sopenharmony_ci while (timeout && !kthread_should_stop()) 15718c2ecf20Sopenharmony_ci timeout = schedule_timeout_interruptible(timeout); 15728c2ecf20Sopenharmony_ci } 15738c2ecf20Sopenharmony_ci 15748c2ecf20Sopenharmony_ci while (!kthread_should_stop()) { 15758c2ecf20Sopenharmony_ci signed long timeout = jiffies_scan_wait; 15768c2ecf20Sopenharmony_ci 15778c2ecf20Sopenharmony_ci mutex_lock(&scan_mutex); 15788c2ecf20Sopenharmony_ci kmemleak_scan(); 15798c2ecf20Sopenharmony_ci mutex_unlock(&scan_mutex); 15808c2ecf20Sopenharmony_ci 15818c2ecf20Sopenharmony_ci /* wait before the next scan */ 15828c2ecf20Sopenharmony_ci while (timeout && !kthread_should_stop()) 15838c2ecf20Sopenharmony_ci timeout = schedule_timeout_interruptible(timeout); 15848c2ecf20Sopenharmony_ci } 15858c2ecf20Sopenharmony_ci 15868c2ecf20Sopenharmony_ci pr_info("Automatic memory scanning thread ended\n"); 15878c2ecf20Sopenharmony_ci 15888c2ecf20Sopenharmony_ci return 0; 15898c2ecf20Sopenharmony_ci} 15908c2ecf20Sopenharmony_ci 15918c2ecf20Sopenharmony_ci/* 15928c2ecf20Sopenharmony_ci * Start the automatic memory scanning thread. This function must be called 15938c2ecf20Sopenharmony_ci * with the scan_mutex held. 15948c2ecf20Sopenharmony_ci */ 15958c2ecf20Sopenharmony_cistatic void start_scan_thread(void) 15968c2ecf20Sopenharmony_ci{ 15978c2ecf20Sopenharmony_ci if (scan_thread) 15988c2ecf20Sopenharmony_ci return; 15998c2ecf20Sopenharmony_ci scan_thread = kthread_run(kmemleak_scan_thread, NULL, "kmemleak"); 16008c2ecf20Sopenharmony_ci if (IS_ERR(scan_thread)) { 16018c2ecf20Sopenharmony_ci pr_warn("Failed to create the scan thread\n"); 16028c2ecf20Sopenharmony_ci scan_thread = NULL; 16038c2ecf20Sopenharmony_ci } 16048c2ecf20Sopenharmony_ci} 16058c2ecf20Sopenharmony_ci 16068c2ecf20Sopenharmony_ci/* 16078c2ecf20Sopenharmony_ci * Stop the automatic memory scanning thread. 16088c2ecf20Sopenharmony_ci */ 16098c2ecf20Sopenharmony_cistatic void stop_scan_thread(void) 16108c2ecf20Sopenharmony_ci{ 16118c2ecf20Sopenharmony_ci if (scan_thread) { 16128c2ecf20Sopenharmony_ci kthread_stop(scan_thread); 16138c2ecf20Sopenharmony_ci scan_thread = NULL; 16148c2ecf20Sopenharmony_ci } 16158c2ecf20Sopenharmony_ci} 16168c2ecf20Sopenharmony_ci 16178c2ecf20Sopenharmony_ci/* 16188c2ecf20Sopenharmony_ci * Iterate over the object_list and return the first valid object at or after 16198c2ecf20Sopenharmony_ci * the required position with its use_count incremented. The function triggers 16208c2ecf20Sopenharmony_ci * a memory scanning when the pos argument points to the first position. 16218c2ecf20Sopenharmony_ci */ 16228c2ecf20Sopenharmony_cistatic void *kmemleak_seq_start(struct seq_file *seq, loff_t *pos) 16238c2ecf20Sopenharmony_ci{ 16248c2ecf20Sopenharmony_ci struct kmemleak_object *object; 16258c2ecf20Sopenharmony_ci loff_t n = *pos; 16268c2ecf20Sopenharmony_ci int err; 16278c2ecf20Sopenharmony_ci 16288c2ecf20Sopenharmony_ci err = mutex_lock_interruptible(&scan_mutex); 16298c2ecf20Sopenharmony_ci if (err < 0) 16308c2ecf20Sopenharmony_ci return ERR_PTR(err); 16318c2ecf20Sopenharmony_ci 16328c2ecf20Sopenharmony_ci rcu_read_lock(); 16338c2ecf20Sopenharmony_ci list_for_each_entry_rcu(object, &object_list, object_list) { 16348c2ecf20Sopenharmony_ci if (n-- > 0) 16358c2ecf20Sopenharmony_ci continue; 16368c2ecf20Sopenharmony_ci if (get_object(object)) 16378c2ecf20Sopenharmony_ci goto out; 16388c2ecf20Sopenharmony_ci } 16398c2ecf20Sopenharmony_ci object = NULL; 16408c2ecf20Sopenharmony_ciout: 16418c2ecf20Sopenharmony_ci return object; 16428c2ecf20Sopenharmony_ci} 16438c2ecf20Sopenharmony_ci 16448c2ecf20Sopenharmony_ci/* 16458c2ecf20Sopenharmony_ci * Return the next object in the object_list. The function decrements the 16468c2ecf20Sopenharmony_ci * use_count of the previous object and increases that of the next one. 16478c2ecf20Sopenharmony_ci */ 16488c2ecf20Sopenharmony_cistatic void *kmemleak_seq_next(struct seq_file *seq, void *v, loff_t *pos) 16498c2ecf20Sopenharmony_ci{ 16508c2ecf20Sopenharmony_ci struct kmemleak_object *prev_obj = v; 16518c2ecf20Sopenharmony_ci struct kmemleak_object *next_obj = NULL; 16528c2ecf20Sopenharmony_ci struct kmemleak_object *obj = prev_obj; 16538c2ecf20Sopenharmony_ci 16548c2ecf20Sopenharmony_ci ++(*pos); 16558c2ecf20Sopenharmony_ci 16568c2ecf20Sopenharmony_ci list_for_each_entry_continue_rcu(obj, &object_list, object_list) { 16578c2ecf20Sopenharmony_ci if (get_object(obj)) { 16588c2ecf20Sopenharmony_ci next_obj = obj; 16598c2ecf20Sopenharmony_ci break; 16608c2ecf20Sopenharmony_ci } 16618c2ecf20Sopenharmony_ci } 16628c2ecf20Sopenharmony_ci 16638c2ecf20Sopenharmony_ci put_object(prev_obj); 16648c2ecf20Sopenharmony_ci return next_obj; 16658c2ecf20Sopenharmony_ci} 16668c2ecf20Sopenharmony_ci 16678c2ecf20Sopenharmony_ci/* 16688c2ecf20Sopenharmony_ci * Decrement the use_count of the last object required, if any. 16698c2ecf20Sopenharmony_ci */ 16708c2ecf20Sopenharmony_cistatic void kmemleak_seq_stop(struct seq_file *seq, void *v) 16718c2ecf20Sopenharmony_ci{ 16728c2ecf20Sopenharmony_ci if (!IS_ERR(v)) { 16738c2ecf20Sopenharmony_ci /* 16748c2ecf20Sopenharmony_ci * kmemleak_seq_start may return ERR_PTR if the scan_mutex 16758c2ecf20Sopenharmony_ci * waiting was interrupted, so only release it if !IS_ERR. 16768c2ecf20Sopenharmony_ci */ 16778c2ecf20Sopenharmony_ci rcu_read_unlock(); 16788c2ecf20Sopenharmony_ci mutex_unlock(&scan_mutex); 16798c2ecf20Sopenharmony_ci if (v) 16808c2ecf20Sopenharmony_ci put_object(v); 16818c2ecf20Sopenharmony_ci } 16828c2ecf20Sopenharmony_ci} 16838c2ecf20Sopenharmony_ci 16848c2ecf20Sopenharmony_ci/* 16858c2ecf20Sopenharmony_ci * Print the information for an unreferenced object to the seq file. 16868c2ecf20Sopenharmony_ci */ 16878c2ecf20Sopenharmony_cistatic int kmemleak_seq_show(struct seq_file *seq, void *v) 16888c2ecf20Sopenharmony_ci{ 16898c2ecf20Sopenharmony_ci struct kmemleak_object *object = v; 16908c2ecf20Sopenharmony_ci unsigned long flags; 16918c2ecf20Sopenharmony_ci 16928c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 16938c2ecf20Sopenharmony_ci if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) 16948c2ecf20Sopenharmony_ci print_unreferenced(seq, object); 16958c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 16968c2ecf20Sopenharmony_ci return 0; 16978c2ecf20Sopenharmony_ci} 16988c2ecf20Sopenharmony_ci 16998c2ecf20Sopenharmony_cistatic const struct seq_operations kmemleak_seq_ops = { 17008c2ecf20Sopenharmony_ci .start = kmemleak_seq_start, 17018c2ecf20Sopenharmony_ci .next = kmemleak_seq_next, 17028c2ecf20Sopenharmony_ci .stop = kmemleak_seq_stop, 17038c2ecf20Sopenharmony_ci .show = kmemleak_seq_show, 17048c2ecf20Sopenharmony_ci}; 17058c2ecf20Sopenharmony_ci 17068c2ecf20Sopenharmony_cistatic int kmemleak_open(struct inode *inode, struct file *file) 17078c2ecf20Sopenharmony_ci{ 17088c2ecf20Sopenharmony_ci return seq_open(file, &kmemleak_seq_ops); 17098c2ecf20Sopenharmony_ci} 17108c2ecf20Sopenharmony_ci 17118c2ecf20Sopenharmony_cistatic int dump_str_object_info(const char *str) 17128c2ecf20Sopenharmony_ci{ 17138c2ecf20Sopenharmony_ci unsigned long flags; 17148c2ecf20Sopenharmony_ci struct kmemleak_object *object; 17158c2ecf20Sopenharmony_ci unsigned long addr; 17168c2ecf20Sopenharmony_ci 17178c2ecf20Sopenharmony_ci if (kstrtoul(str, 0, &addr)) 17188c2ecf20Sopenharmony_ci return -EINVAL; 17198c2ecf20Sopenharmony_ci object = find_and_get_object(addr, 0); 17208c2ecf20Sopenharmony_ci if (!object) { 17218c2ecf20Sopenharmony_ci pr_info("Unknown object at 0x%08lx\n", addr); 17228c2ecf20Sopenharmony_ci return -EINVAL; 17238c2ecf20Sopenharmony_ci } 17248c2ecf20Sopenharmony_ci 17258c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 17268c2ecf20Sopenharmony_ci dump_object_info(object); 17278c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 17288c2ecf20Sopenharmony_ci 17298c2ecf20Sopenharmony_ci put_object(object); 17308c2ecf20Sopenharmony_ci return 0; 17318c2ecf20Sopenharmony_ci} 17328c2ecf20Sopenharmony_ci 17338c2ecf20Sopenharmony_ci/* 17348c2ecf20Sopenharmony_ci * We use grey instead of black to ensure we can do future scans on the same 17358c2ecf20Sopenharmony_ci * objects. If we did not do future scans these black objects could 17368c2ecf20Sopenharmony_ci * potentially contain references to newly allocated objects in the future and 17378c2ecf20Sopenharmony_ci * we'd end up with false positives. 17388c2ecf20Sopenharmony_ci */ 17398c2ecf20Sopenharmony_cistatic void kmemleak_clear(void) 17408c2ecf20Sopenharmony_ci{ 17418c2ecf20Sopenharmony_ci struct kmemleak_object *object; 17428c2ecf20Sopenharmony_ci unsigned long flags; 17438c2ecf20Sopenharmony_ci 17448c2ecf20Sopenharmony_ci rcu_read_lock(); 17458c2ecf20Sopenharmony_ci list_for_each_entry_rcu(object, &object_list, object_list) { 17468c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 17478c2ecf20Sopenharmony_ci if ((object->flags & OBJECT_REPORTED) && 17488c2ecf20Sopenharmony_ci unreferenced_object(object)) 17498c2ecf20Sopenharmony_ci __paint_it(object, KMEMLEAK_GREY); 17508c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 17518c2ecf20Sopenharmony_ci } 17528c2ecf20Sopenharmony_ci rcu_read_unlock(); 17538c2ecf20Sopenharmony_ci 17548c2ecf20Sopenharmony_ci kmemleak_found_leaks = false; 17558c2ecf20Sopenharmony_ci} 17568c2ecf20Sopenharmony_ci 17578c2ecf20Sopenharmony_cistatic void __kmemleak_do_cleanup(void); 17588c2ecf20Sopenharmony_ci 17598c2ecf20Sopenharmony_ci/* 17608c2ecf20Sopenharmony_ci * File write operation to configure kmemleak at run-time. The following 17618c2ecf20Sopenharmony_ci * commands can be written to the /sys/kernel/debug/kmemleak file: 17628c2ecf20Sopenharmony_ci * off - disable kmemleak (irreversible) 17638c2ecf20Sopenharmony_ci * stack=on - enable the task stacks scanning 17648c2ecf20Sopenharmony_ci * stack=off - disable the tasks stacks scanning 17658c2ecf20Sopenharmony_ci * scan=on - start the automatic memory scanning thread 17668c2ecf20Sopenharmony_ci * scan=off - stop the automatic memory scanning thread 17678c2ecf20Sopenharmony_ci * scan=... - set the automatic memory scanning period in seconds (0 to 17688c2ecf20Sopenharmony_ci * disable it) 17698c2ecf20Sopenharmony_ci * scan - trigger a memory scan 17708c2ecf20Sopenharmony_ci * clear - mark all current reported unreferenced kmemleak objects as 17718c2ecf20Sopenharmony_ci * grey to ignore printing them, or free all kmemleak objects 17728c2ecf20Sopenharmony_ci * if kmemleak has been disabled. 17738c2ecf20Sopenharmony_ci * dump=... - dump information about the object found at the given address 17748c2ecf20Sopenharmony_ci */ 17758c2ecf20Sopenharmony_cistatic ssize_t kmemleak_write(struct file *file, const char __user *user_buf, 17768c2ecf20Sopenharmony_ci size_t size, loff_t *ppos) 17778c2ecf20Sopenharmony_ci{ 17788c2ecf20Sopenharmony_ci char buf[64]; 17798c2ecf20Sopenharmony_ci int buf_size; 17808c2ecf20Sopenharmony_ci int ret; 17818c2ecf20Sopenharmony_ci 17828c2ecf20Sopenharmony_ci buf_size = min(size, (sizeof(buf) - 1)); 17838c2ecf20Sopenharmony_ci if (strncpy_from_user(buf, user_buf, buf_size) < 0) 17848c2ecf20Sopenharmony_ci return -EFAULT; 17858c2ecf20Sopenharmony_ci buf[buf_size] = 0; 17868c2ecf20Sopenharmony_ci 17878c2ecf20Sopenharmony_ci ret = mutex_lock_interruptible(&scan_mutex); 17888c2ecf20Sopenharmony_ci if (ret < 0) 17898c2ecf20Sopenharmony_ci return ret; 17908c2ecf20Sopenharmony_ci 17918c2ecf20Sopenharmony_ci if (strncmp(buf, "clear", 5) == 0) { 17928c2ecf20Sopenharmony_ci if (kmemleak_enabled) 17938c2ecf20Sopenharmony_ci kmemleak_clear(); 17948c2ecf20Sopenharmony_ci else 17958c2ecf20Sopenharmony_ci __kmemleak_do_cleanup(); 17968c2ecf20Sopenharmony_ci goto out; 17978c2ecf20Sopenharmony_ci } 17988c2ecf20Sopenharmony_ci 17998c2ecf20Sopenharmony_ci if (!kmemleak_enabled) { 18008c2ecf20Sopenharmony_ci ret = -EPERM; 18018c2ecf20Sopenharmony_ci goto out; 18028c2ecf20Sopenharmony_ci } 18038c2ecf20Sopenharmony_ci 18048c2ecf20Sopenharmony_ci if (strncmp(buf, "off", 3) == 0) 18058c2ecf20Sopenharmony_ci kmemleak_disable(); 18068c2ecf20Sopenharmony_ci else if (strncmp(buf, "stack=on", 8) == 0) 18078c2ecf20Sopenharmony_ci kmemleak_stack_scan = 1; 18088c2ecf20Sopenharmony_ci else if (strncmp(buf, "stack=off", 9) == 0) 18098c2ecf20Sopenharmony_ci kmemleak_stack_scan = 0; 18108c2ecf20Sopenharmony_ci else if (strncmp(buf, "scan=on", 7) == 0) 18118c2ecf20Sopenharmony_ci start_scan_thread(); 18128c2ecf20Sopenharmony_ci else if (strncmp(buf, "scan=off", 8) == 0) 18138c2ecf20Sopenharmony_ci stop_scan_thread(); 18148c2ecf20Sopenharmony_ci else if (strncmp(buf, "scan=", 5) == 0) { 18158c2ecf20Sopenharmony_ci unsigned long secs; 18168c2ecf20Sopenharmony_ci 18178c2ecf20Sopenharmony_ci ret = kstrtoul(buf + 5, 0, &secs); 18188c2ecf20Sopenharmony_ci if (ret < 0) 18198c2ecf20Sopenharmony_ci goto out; 18208c2ecf20Sopenharmony_ci stop_scan_thread(); 18218c2ecf20Sopenharmony_ci if (secs) { 18228c2ecf20Sopenharmony_ci jiffies_scan_wait = msecs_to_jiffies(secs * 1000); 18238c2ecf20Sopenharmony_ci start_scan_thread(); 18248c2ecf20Sopenharmony_ci } 18258c2ecf20Sopenharmony_ci } else if (strncmp(buf, "scan", 4) == 0) 18268c2ecf20Sopenharmony_ci kmemleak_scan(); 18278c2ecf20Sopenharmony_ci else if (strncmp(buf, "dump=", 5) == 0) 18288c2ecf20Sopenharmony_ci ret = dump_str_object_info(buf + 5); 18298c2ecf20Sopenharmony_ci else 18308c2ecf20Sopenharmony_ci ret = -EINVAL; 18318c2ecf20Sopenharmony_ci 18328c2ecf20Sopenharmony_ciout: 18338c2ecf20Sopenharmony_ci mutex_unlock(&scan_mutex); 18348c2ecf20Sopenharmony_ci if (ret < 0) 18358c2ecf20Sopenharmony_ci return ret; 18368c2ecf20Sopenharmony_ci 18378c2ecf20Sopenharmony_ci /* ignore the rest of the buffer, only one command at a time */ 18388c2ecf20Sopenharmony_ci *ppos += size; 18398c2ecf20Sopenharmony_ci return size; 18408c2ecf20Sopenharmony_ci} 18418c2ecf20Sopenharmony_ci 18428c2ecf20Sopenharmony_cistatic const struct file_operations kmemleak_fops = { 18438c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 18448c2ecf20Sopenharmony_ci .open = kmemleak_open, 18458c2ecf20Sopenharmony_ci .read = seq_read, 18468c2ecf20Sopenharmony_ci .write = kmemleak_write, 18478c2ecf20Sopenharmony_ci .llseek = seq_lseek, 18488c2ecf20Sopenharmony_ci .release = seq_release, 18498c2ecf20Sopenharmony_ci}; 18508c2ecf20Sopenharmony_ci 18518c2ecf20Sopenharmony_cistatic void __kmemleak_do_cleanup(void) 18528c2ecf20Sopenharmony_ci{ 18538c2ecf20Sopenharmony_ci struct kmemleak_object *object, *tmp; 18548c2ecf20Sopenharmony_ci 18558c2ecf20Sopenharmony_ci /* 18568c2ecf20Sopenharmony_ci * Kmemleak has already been disabled, no need for RCU list traversal 18578c2ecf20Sopenharmony_ci * or kmemleak_lock held. 18588c2ecf20Sopenharmony_ci */ 18598c2ecf20Sopenharmony_ci list_for_each_entry_safe(object, tmp, &object_list, object_list) { 18608c2ecf20Sopenharmony_ci __remove_object(object); 18618c2ecf20Sopenharmony_ci __delete_object(object); 18628c2ecf20Sopenharmony_ci } 18638c2ecf20Sopenharmony_ci} 18648c2ecf20Sopenharmony_ci 18658c2ecf20Sopenharmony_ci/* 18668c2ecf20Sopenharmony_ci * Stop the memory scanning thread and free the kmemleak internal objects if 18678c2ecf20Sopenharmony_ci * no previous scan thread (otherwise, kmemleak may still have some useful 18688c2ecf20Sopenharmony_ci * information on memory leaks). 18698c2ecf20Sopenharmony_ci */ 18708c2ecf20Sopenharmony_cistatic void kmemleak_do_cleanup(struct work_struct *work) 18718c2ecf20Sopenharmony_ci{ 18728c2ecf20Sopenharmony_ci stop_scan_thread(); 18738c2ecf20Sopenharmony_ci 18748c2ecf20Sopenharmony_ci mutex_lock(&scan_mutex); 18758c2ecf20Sopenharmony_ci /* 18768c2ecf20Sopenharmony_ci * Once it is made sure that kmemleak_scan has stopped, it is safe to no 18778c2ecf20Sopenharmony_ci * longer track object freeing. Ordering of the scan thread stopping and 18788c2ecf20Sopenharmony_ci * the memory accesses below is guaranteed by the kthread_stop() 18798c2ecf20Sopenharmony_ci * function. 18808c2ecf20Sopenharmony_ci */ 18818c2ecf20Sopenharmony_ci kmemleak_free_enabled = 0; 18828c2ecf20Sopenharmony_ci mutex_unlock(&scan_mutex); 18838c2ecf20Sopenharmony_ci 18848c2ecf20Sopenharmony_ci if (!kmemleak_found_leaks) 18858c2ecf20Sopenharmony_ci __kmemleak_do_cleanup(); 18868c2ecf20Sopenharmony_ci else 18878c2ecf20Sopenharmony_ci pr_info("Kmemleak disabled without freeing internal data. Reclaim the memory with \"echo clear > /sys/kernel/debug/kmemleak\".\n"); 18888c2ecf20Sopenharmony_ci} 18898c2ecf20Sopenharmony_ci 18908c2ecf20Sopenharmony_cistatic DECLARE_WORK(cleanup_work, kmemleak_do_cleanup); 18918c2ecf20Sopenharmony_ci 18928c2ecf20Sopenharmony_ci/* 18938c2ecf20Sopenharmony_ci * Disable kmemleak. No memory allocation/freeing will be traced once this 18948c2ecf20Sopenharmony_ci * function is called. Disabling kmemleak is an irreversible operation. 18958c2ecf20Sopenharmony_ci */ 18968c2ecf20Sopenharmony_cistatic void kmemleak_disable(void) 18978c2ecf20Sopenharmony_ci{ 18988c2ecf20Sopenharmony_ci /* atomically check whether it was already invoked */ 18998c2ecf20Sopenharmony_ci if (cmpxchg(&kmemleak_error, 0, 1)) 19008c2ecf20Sopenharmony_ci return; 19018c2ecf20Sopenharmony_ci 19028c2ecf20Sopenharmony_ci /* stop any memory operation tracing */ 19038c2ecf20Sopenharmony_ci kmemleak_enabled = 0; 19048c2ecf20Sopenharmony_ci 19058c2ecf20Sopenharmony_ci /* check whether it is too early for a kernel thread */ 19068c2ecf20Sopenharmony_ci if (kmemleak_initialized) 19078c2ecf20Sopenharmony_ci schedule_work(&cleanup_work); 19088c2ecf20Sopenharmony_ci else 19098c2ecf20Sopenharmony_ci kmemleak_free_enabled = 0; 19108c2ecf20Sopenharmony_ci 19118c2ecf20Sopenharmony_ci pr_info("Kernel memory leak detector disabled\n"); 19128c2ecf20Sopenharmony_ci} 19138c2ecf20Sopenharmony_ci 19148c2ecf20Sopenharmony_ci/* 19158c2ecf20Sopenharmony_ci * Allow boot-time kmemleak disabling (enabled by default). 19168c2ecf20Sopenharmony_ci */ 19178c2ecf20Sopenharmony_cistatic int __init kmemleak_boot_config(char *str) 19188c2ecf20Sopenharmony_ci{ 19198c2ecf20Sopenharmony_ci if (!str) 19208c2ecf20Sopenharmony_ci return -EINVAL; 19218c2ecf20Sopenharmony_ci if (strcmp(str, "off") == 0) 19228c2ecf20Sopenharmony_ci kmemleak_disable(); 19238c2ecf20Sopenharmony_ci else if (strcmp(str, "on") == 0) 19248c2ecf20Sopenharmony_ci kmemleak_skip_disable = 1; 19258c2ecf20Sopenharmony_ci else 19268c2ecf20Sopenharmony_ci return -EINVAL; 19278c2ecf20Sopenharmony_ci return 0; 19288c2ecf20Sopenharmony_ci} 19298c2ecf20Sopenharmony_ciearly_param("kmemleak", kmemleak_boot_config); 19308c2ecf20Sopenharmony_ci 19318c2ecf20Sopenharmony_ci/* 19328c2ecf20Sopenharmony_ci * Kmemleak initialization. 19338c2ecf20Sopenharmony_ci */ 19348c2ecf20Sopenharmony_civoid __init kmemleak_init(void) 19358c2ecf20Sopenharmony_ci{ 19368c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF 19378c2ecf20Sopenharmony_ci if (!kmemleak_skip_disable) { 19388c2ecf20Sopenharmony_ci kmemleak_disable(); 19398c2ecf20Sopenharmony_ci return; 19408c2ecf20Sopenharmony_ci } 19418c2ecf20Sopenharmony_ci#endif 19428c2ecf20Sopenharmony_ci 19438c2ecf20Sopenharmony_ci if (kmemleak_error) 19448c2ecf20Sopenharmony_ci return; 19458c2ecf20Sopenharmony_ci 19468c2ecf20Sopenharmony_ci jiffies_min_age = msecs_to_jiffies(MSECS_MIN_AGE); 19478c2ecf20Sopenharmony_ci jiffies_scan_wait = msecs_to_jiffies(SECS_SCAN_WAIT * 1000); 19488c2ecf20Sopenharmony_ci 19498c2ecf20Sopenharmony_ci object_cache = KMEM_CACHE(kmemleak_object, SLAB_NOLEAKTRACE); 19508c2ecf20Sopenharmony_ci scan_area_cache = KMEM_CACHE(kmemleak_scan_area, SLAB_NOLEAKTRACE); 19518c2ecf20Sopenharmony_ci 19528c2ecf20Sopenharmony_ci /* register the data/bss sections */ 19538c2ecf20Sopenharmony_ci create_object((unsigned long)_sdata, _edata - _sdata, 19548c2ecf20Sopenharmony_ci KMEMLEAK_GREY, GFP_ATOMIC); 19558c2ecf20Sopenharmony_ci create_object((unsigned long)__bss_start, __bss_stop - __bss_start, 19568c2ecf20Sopenharmony_ci KMEMLEAK_GREY, GFP_ATOMIC); 19578c2ecf20Sopenharmony_ci /* only register .data..ro_after_init if not within .data */ 19588c2ecf20Sopenharmony_ci if (&__start_ro_after_init < &_sdata || &__end_ro_after_init > &_edata) 19598c2ecf20Sopenharmony_ci create_object((unsigned long)__start_ro_after_init, 19608c2ecf20Sopenharmony_ci __end_ro_after_init - __start_ro_after_init, 19618c2ecf20Sopenharmony_ci KMEMLEAK_GREY, GFP_ATOMIC); 19628c2ecf20Sopenharmony_ci} 19638c2ecf20Sopenharmony_ci 19648c2ecf20Sopenharmony_ci/* 19658c2ecf20Sopenharmony_ci * Late initialization function. 19668c2ecf20Sopenharmony_ci */ 19678c2ecf20Sopenharmony_cistatic int __init kmemleak_late_init(void) 19688c2ecf20Sopenharmony_ci{ 19698c2ecf20Sopenharmony_ci kmemleak_initialized = 1; 19708c2ecf20Sopenharmony_ci 19718c2ecf20Sopenharmony_ci debugfs_create_file("kmemleak", 0644, NULL, NULL, &kmemleak_fops); 19728c2ecf20Sopenharmony_ci 19738c2ecf20Sopenharmony_ci if (kmemleak_error) { 19748c2ecf20Sopenharmony_ci /* 19758c2ecf20Sopenharmony_ci * Some error occurred and kmemleak was disabled. There is a 19768c2ecf20Sopenharmony_ci * small chance that kmemleak_disable() was called immediately 19778c2ecf20Sopenharmony_ci * after setting kmemleak_initialized and we may end up with 19788c2ecf20Sopenharmony_ci * two clean-up threads but serialized by scan_mutex. 19798c2ecf20Sopenharmony_ci */ 19808c2ecf20Sopenharmony_ci schedule_work(&cleanup_work); 19818c2ecf20Sopenharmony_ci return -ENOMEM; 19828c2ecf20Sopenharmony_ci } 19838c2ecf20Sopenharmony_ci 19848c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN)) { 19858c2ecf20Sopenharmony_ci mutex_lock(&scan_mutex); 19868c2ecf20Sopenharmony_ci start_scan_thread(); 19878c2ecf20Sopenharmony_ci mutex_unlock(&scan_mutex); 19888c2ecf20Sopenharmony_ci } 19898c2ecf20Sopenharmony_ci 19908c2ecf20Sopenharmony_ci pr_info("Kernel memory leak detector initialized (mem pool available: %d)\n", 19918c2ecf20Sopenharmony_ci mem_pool_free_count); 19928c2ecf20Sopenharmony_ci 19938c2ecf20Sopenharmony_ci return 0; 19948c2ecf20Sopenharmony_ci} 19958c2ecf20Sopenharmony_cilate_initcall(kmemleak_late_init); 1996