162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * mm/kmemleak.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2008 ARM Limited 662306a36Sopenharmony_ci * Written by Catalin Marinas <catalin.marinas@arm.com> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * For more information on the algorithm and kmemleak usage, please see 962306a36Sopenharmony_ci * Documentation/dev-tools/kmemleak.rst. 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Notes on locking 1262306a36Sopenharmony_ci * ---------------- 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * The following locks and mutexes are used by kmemleak: 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * - kmemleak_lock (raw_spinlock_t): protects the object_list as well as 1762306a36Sopenharmony_ci * del_state modifications and accesses to the object_tree_root (or 1862306a36Sopenharmony_ci * object_phys_tree_root). The object_list is the main list holding the 1962306a36Sopenharmony_ci * metadata (struct kmemleak_object) for the allocated memory blocks. 2062306a36Sopenharmony_ci * The object_tree_root and object_phys_tree_root are red 2162306a36Sopenharmony_ci * black trees used to look-up metadata based on a pointer to the 2262306a36Sopenharmony_ci * corresponding memory block. The object_phys_tree_root is for objects 2362306a36Sopenharmony_ci * allocated with physical address. The kmemleak_object structures are 2462306a36Sopenharmony_ci * added to the object_list and object_tree_root (or object_phys_tree_root) 2562306a36Sopenharmony_ci * in the create_object() function called from the kmemleak_alloc() (or 2662306a36Sopenharmony_ci * kmemleak_alloc_phys()) callback and removed in delete_object() called from 2762306a36Sopenharmony_ci * the kmemleak_free() callback 2862306a36Sopenharmony_ci * - kmemleak_object.lock (raw_spinlock_t): protects a kmemleak_object. 2962306a36Sopenharmony_ci * Accesses to the metadata (e.g. count) are protected by this lock. Note 3062306a36Sopenharmony_ci * that some members of this structure may be protected by other means 3162306a36Sopenharmony_ci * (atomic or kmemleak_lock). This lock is also held when scanning the 3262306a36Sopenharmony_ci * corresponding memory block to avoid the kernel freeing it via the 3362306a36Sopenharmony_ci * kmemleak_free() callback. This is less heavyweight than holding a global 3462306a36Sopenharmony_ci * lock like kmemleak_lock during scanning. 3562306a36Sopenharmony_ci * - scan_mutex (mutex): ensures that only one thread may scan the memory for 3662306a36Sopenharmony_ci * unreferenced objects at a time. The gray_list contains the objects which 3762306a36Sopenharmony_ci * are already referenced or marked as false positives and need to be 3862306a36Sopenharmony_ci * scanned. This list is only modified during a scanning episode when the 3962306a36Sopenharmony_ci * scan_mutex is held. At the end of a scan, the gray_list is always empty. 4062306a36Sopenharmony_ci * Note that the kmemleak_object.use_count is incremented when an object is 4162306a36Sopenharmony_ci * added to the gray_list and therefore cannot be freed. This mutex also 4262306a36Sopenharmony_ci * prevents multiple users of the "kmemleak" debugfs file together with 4362306a36Sopenharmony_ci * modifications to the memory scanning parameters including the scan_thread 4462306a36Sopenharmony_ci * pointer 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * Locks and mutexes are acquired/nested in the following order: 4762306a36Sopenharmony_ci * 4862306a36Sopenharmony_ci * scan_mutex [-> object->lock] -> kmemleak_lock -> other_object->lock (SINGLE_DEPTH_NESTING) 4962306a36Sopenharmony_ci * 5062306a36Sopenharmony_ci * No kmemleak_lock and object->lock nesting is allowed outside scan_mutex 5162306a36Sopenharmony_ci * regions. 5262306a36Sopenharmony_ci * 5362306a36Sopenharmony_ci * The kmemleak_object structures have a use_count incremented or decremented 5462306a36Sopenharmony_ci * using the get_object()/put_object() functions. When the use_count becomes 5562306a36Sopenharmony_ci * 0, this count can no longer be incremented and put_object() schedules the 5662306a36Sopenharmony_ci * kmemleak_object freeing via an RCU callback. All calls to the get_object() 5762306a36Sopenharmony_ci * function must be protected by rcu_read_lock() to avoid accessing a freed 5862306a36Sopenharmony_ci * structure. 5962306a36Sopenharmony_ci */ 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci#include <linux/init.h> 6462306a36Sopenharmony_ci#include <linux/kernel.h> 6562306a36Sopenharmony_ci#include <linux/list.h> 6662306a36Sopenharmony_ci#include <linux/sched/signal.h> 6762306a36Sopenharmony_ci#include <linux/sched/task.h> 6862306a36Sopenharmony_ci#include <linux/sched/task_stack.h> 6962306a36Sopenharmony_ci#include <linux/jiffies.h> 7062306a36Sopenharmony_ci#include <linux/delay.h> 7162306a36Sopenharmony_ci#include <linux/export.h> 7262306a36Sopenharmony_ci#include <linux/kthread.h> 7362306a36Sopenharmony_ci#include <linux/rbtree.h> 7462306a36Sopenharmony_ci#include <linux/fs.h> 7562306a36Sopenharmony_ci#include <linux/debugfs.h> 7662306a36Sopenharmony_ci#include <linux/seq_file.h> 7762306a36Sopenharmony_ci#include <linux/cpumask.h> 7862306a36Sopenharmony_ci#include <linux/spinlock.h> 7962306a36Sopenharmony_ci#include <linux/module.h> 8062306a36Sopenharmony_ci#include <linux/mutex.h> 8162306a36Sopenharmony_ci#include <linux/rcupdate.h> 8262306a36Sopenharmony_ci#include <linux/stacktrace.h> 8362306a36Sopenharmony_ci#include <linux/stackdepot.h> 8462306a36Sopenharmony_ci#include <linux/cache.h> 8562306a36Sopenharmony_ci#include <linux/percpu.h> 8662306a36Sopenharmony_ci#include <linux/memblock.h> 8762306a36Sopenharmony_ci#include <linux/pfn.h> 8862306a36Sopenharmony_ci#include <linux/mmzone.h> 8962306a36Sopenharmony_ci#include <linux/slab.h> 9062306a36Sopenharmony_ci#include <linux/thread_info.h> 9162306a36Sopenharmony_ci#include <linux/err.h> 9262306a36Sopenharmony_ci#include <linux/uaccess.h> 9362306a36Sopenharmony_ci#include <linux/string.h> 9462306a36Sopenharmony_ci#include <linux/nodemask.h> 9562306a36Sopenharmony_ci#include <linux/mm.h> 9662306a36Sopenharmony_ci#include <linux/workqueue.h> 9762306a36Sopenharmony_ci#include <linux/crc32.h> 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci#include <asm/sections.h> 10062306a36Sopenharmony_ci#include <asm/processor.h> 10162306a36Sopenharmony_ci#include <linux/atomic.h> 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci#include <linux/kasan.h> 10462306a36Sopenharmony_ci#include <linux/kfence.h> 10562306a36Sopenharmony_ci#include <linux/kmemleak.h> 10662306a36Sopenharmony_ci#include <linux/memory_hotplug.h> 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci/* 10962306a36Sopenharmony_ci * Kmemleak configuration and common defines. 11062306a36Sopenharmony_ci */ 11162306a36Sopenharmony_ci#define MAX_TRACE 16 /* stack trace length */ 11262306a36Sopenharmony_ci#define MSECS_MIN_AGE 5000 /* minimum object age for reporting */ 11362306a36Sopenharmony_ci#define SECS_FIRST_SCAN 60 /* delay before the first scan */ 11462306a36Sopenharmony_ci#define SECS_SCAN_WAIT 600 /* subsequent auto scanning delay */ 11562306a36Sopenharmony_ci#define MAX_SCAN_SIZE 4096 /* maximum size of a scanned block */ 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci#define BYTES_PER_POINTER sizeof(void *) 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci/* GFP bitmask for kmemleak internal allocations */ 12062306a36Sopenharmony_ci#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC | \ 12162306a36Sopenharmony_ci __GFP_NOLOCKDEP)) | \ 12262306a36Sopenharmony_ci __GFP_NORETRY | __GFP_NOMEMALLOC | \ 12362306a36Sopenharmony_ci __GFP_NOWARN) 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci/* scanning area inside a memory block */ 12662306a36Sopenharmony_cistruct kmemleak_scan_area { 12762306a36Sopenharmony_ci struct hlist_node node; 12862306a36Sopenharmony_ci unsigned long start; 12962306a36Sopenharmony_ci size_t size; 13062306a36Sopenharmony_ci}; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci#define KMEMLEAK_GREY 0 13362306a36Sopenharmony_ci#define KMEMLEAK_BLACK -1 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci/* 13662306a36Sopenharmony_ci * Structure holding the metadata for each allocated memory block. 13762306a36Sopenharmony_ci * Modifications to such objects should be made while holding the 13862306a36Sopenharmony_ci * object->lock. Insertions or deletions from object_list, gray_list or 13962306a36Sopenharmony_ci * rb_node are already protected by the corresponding locks or mutex (see 14062306a36Sopenharmony_ci * the notes on locking above). These objects are reference-counted 14162306a36Sopenharmony_ci * (use_count) and freed using the RCU mechanism. 14262306a36Sopenharmony_ci */ 14362306a36Sopenharmony_cistruct kmemleak_object { 14462306a36Sopenharmony_ci raw_spinlock_t lock; 14562306a36Sopenharmony_ci unsigned int flags; /* object status flags */ 14662306a36Sopenharmony_ci struct list_head object_list; 14762306a36Sopenharmony_ci struct list_head gray_list; 14862306a36Sopenharmony_ci struct rb_node rb_node; 14962306a36Sopenharmony_ci struct rcu_head rcu; /* object_list lockless traversal */ 15062306a36Sopenharmony_ci /* object usage count; object freed when use_count == 0 */ 15162306a36Sopenharmony_ci atomic_t use_count; 15262306a36Sopenharmony_ci unsigned int del_state; /* deletion state */ 15362306a36Sopenharmony_ci unsigned long pointer; 15462306a36Sopenharmony_ci size_t size; 15562306a36Sopenharmony_ci /* pass surplus references to this pointer */ 15662306a36Sopenharmony_ci unsigned long excess_ref; 15762306a36Sopenharmony_ci /* minimum number of a pointers found before it is considered leak */ 15862306a36Sopenharmony_ci int min_count; 15962306a36Sopenharmony_ci /* the total number of pointers found pointing to this object */ 16062306a36Sopenharmony_ci int count; 16162306a36Sopenharmony_ci /* checksum for detecting modified objects */ 16262306a36Sopenharmony_ci u32 checksum; 16362306a36Sopenharmony_ci /* memory ranges to be scanned inside an object (empty for all) */ 16462306a36Sopenharmony_ci struct hlist_head area_list; 16562306a36Sopenharmony_ci depot_stack_handle_t trace_handle; 16662306a36Sopenharmony_ci unsigned long jiffies; /* creation timestamp */ 16762306a36Sopenharmony_ci pid_t pid; /* pid of the current task */ 16862306a36Sopenharmony_ci char comm[TASK_COMM_LEN]; /* executable name */ 16962306a36Sopenharmony_ci}; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci/* flag representing the memory block allocation status */ 17262306a36Sopenharmony_ci#define OBJECT_ALLOCATED (1 << 0) 17362306a36Sopenharmony_ci/* flag set after the first reporting of an unreference object */ 17462306a36Sopenharmony_ci#define OBJECT_REPORTED (1 << 1) 17562306a36Sopenharmony_ci/* flag set to not scan the object */ 17662306a36Sopenharmony_ci#define OBJECT_NO_SCAN (1 << 2) 17762306a36Sopenharmony_ci/* flag set to fully scan the object when scan_area allocation failed */ 17862306a36Sopenharmony_ci#define OBJECT_FULL_SCAN (1 << 3) 17962306a36Sopenharmony_ci/* flag set for object allocated with physical address */ 18062306a36Sopenharmony_ci#define OBJECT_PHYS (1 << 4) 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci/* set when __remove_object() called */ 18362306a36Sopenharmony_ci#define DELSTATE_REMOVED (1 << 0) 18462306a36Sopenharmony_ci/* set to temporarily prevent deletion from object_list */ 18562306a36Sopenharmony_ci#define DELSTATE_NO_DELETE (1 << 1) 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci#define HEX_PREFIX " " 18862306a36Sopenharmony_ci/* number of bytes to print per line; must be 16 or 32 */ 18962306a36Sopenharmony_ci#define HEX_ROW_SIZE 16 19062306a36Sopenharmony_ci/* number of bytes to print at a time (1, 2, 4, 8) */ 19162306a36Sopenharmony_ci#define HEX_GROUP_SIZE 1 19262306a36Sopenharmony_ci/* include ASCII after the hex output */ 19362306a36Sopenharmony_ci#define HEX_ASCII 1 19462306a36Sopenharmony_ci/* max number of lines to be printed */ 19562306a36Sopenharmony_ci#define HEX_MAX_LINES 2 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci/* the list of all allocated objects */ 19862306a36Sopenharmony_cistatic LIST_HEAD(object_list); 19962306a36Sopenharmony_ci/* the list of gray-colored objects (see color_gray comment below) */ 20062306a36Sopenharmony_cistatic LIST_HEAD(gray_list); 20162306a36Sopenharmony_ci/* memory pool allocation */ 20262306a36Sopenharmony_cistatic struct kmemleak_object mem_pool[CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE]; 20362306a36Sopenharmony_cistatic int mem_pool_free_count = ARRAY_SIZE(mem_pool); 20462306a36Sopenharmony_cistatic LIST_HEAD(mem_pool_free_list); 20562306a36Sopenharmony_ci/* search tree for object boundaries */ 20662306a36Sopenharmony_cistatic struct rb_root object_tree_root = RB_ROOT; 20762306a36Sopenharmony_ci/* search tree for object (with OBJECT_PHYS flag) boundaries */ 20862306a36Sopenharmony_cistatic struct rb_root object_phys_tree_root = RB_ROOT; 20962306a36Sopenharmony_ci/* protecting the access to object_list, object_tree_root (or object_phys_tree_root) */ 21062306a36Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(kmemleak_lock); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci/* allocation caches for kmemleak internal data */ 21362306a36Sopenharmony_cistatic struct kmem_cache *object_cache; 21462306a36Sopenharmony_cistatic struct kmem_cache *scan_area_cache; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci/* set if tracing memory operations is enabled */ 21762306a36Sopenharmony_cistatic int kmemleak_enabled = 1; 21862306a36Sopenharmony_ci/* same as above but only for the kmemleak_free() callback */ 21962306a36Sopenharmony_cistatic int kmemleak_free_enabled = 1; 22062306a36Sopenharmony_ci/* set in the late_initcall if there were no errors */ 22162306a36Sopenharmony_cistatic int kmemleak_late_initialized; 22262306a36Sopenharmony_ci/* set if a kmemleak warning was issued */ 22362306a36Sopenharmony_cistatic int kmemleak_warning; 22462306a36Sopenharmony_ci/* set if a fatal kmemleak error has occurred */ 22562306a36Sopenharmony_cistatic int kmemleak_error; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci/* minimum and maximum address that may be valid pointers */ 22862306a36Sopenharmony_cistatic unsigned long min_addr = ULONG_MAX; 22962306a36Sopenharmony_cistatic unsigned long max_addr; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cistatic struct task_struct *scan_thread; 23262306a36Sopenharmony_ci/* used to avoid reporting of recently allocated objects */ 23362306a36Sopenharmony_cistatic unsigned long jiffies_min_age; 23462306a36Sopenharmony_cistatic unsigned long jiffies_last_scan; 23562306a36Sopenharmony_ci/* delay between automatic memory scannings */ 23662306a36Sopenharmony_cistatic unsigned long jiffies_scan_wait; 23762306a36Sopenharmony_ci/* enables or disables the task stacks scanning */ 23862306a36Sopenharmony_cistatic int kmemleak_stack_scan = 1; 23962306a36Sopenharmony_ci/* protects the memory scanning, parameters and debug/kmemleak file access */ 24062306a36Sopenharmony_cistatic DEFINE_MUTEX(scan_mutex); 24162306a36Sopenharmony_ci/* setting kmemleak=on, will set this var, skipping the disable */ 24262306a36Sopenharmony_cistatic int kmemleak_skip_disable; 24362306a36Sopenharmony_ci/* If there are leaks that can be reported */ 24462306a36Sopenharmony_cistatic bool kmemleak_found_leaks; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_cistatic bool kmemleak_verbose; 24762306a36Sopenharmony_cimodule_param_named(verbose, kmemleak_verbose, bool, 0600); 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_cistatic void kmemleak_disable(void); 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci/* 25262306a36Sopenharmony_ci * Print a warning and dump the stack trace. 25362306a36Sopenharmony_ci */ 25462306a36Sopenharmony_ci#define kmemleak_warn(x...) do { \ 25562306a36Sopenharmony_ci pr_warn(x); \ 25662306a36Sopenharmony_ci dump_stack(); \ 25762306a36Sopenharmony_ci kmemleak_warning = 1; \ 25862306a36Sopenharmony_ci} while (0) 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci/* 26162306a36Sopenharmony_ci * Macro invoked when a serious kmemleak condition occurred and cannot be 26262306a36Sopenharmony_ci * recovered from. Kmemleak will be disabled and further allocation/freeing 26362306a36Sopenharmony_ci * tracing no longer available. 26462306a36Sopenharmony_ci */ 26562306a36Sopenharmony_ci#define kmemleak_stop(x...) do { \ 26662306a36Sopenharmony_ci kmemleak_warn(x); \ 26762306a36Sopenharmony_ci kmemleak_disable(); \ 26862306a36Sopenharmony_ci} while (0) 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci#define warn_or_seq_printf(seq, fmt, ...) do { \ 27162306a36Sopenharmony_ci if (seq) \ 27262306a36Sopenharmony_ci seq_printf(seq, fmt, ##__VA_ARGS__); \ 27362306a36Sopenharmony_ci else \ 27462306a36Sopenharmony_ci pr_warn(fmt, ##__VA_ARGS__); \ 27562306a36Sopenharmony_ci} while (0) 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_cistatic void warn_or_seq_hex_dump(struct seq_file *seq, int prefix_type, 27862306a36Sopenharmony_ci int rowsize, int groupsize, const void *buf, 27962306a36Sopenharmony_ci size_t len, bool ascii) 28062306a36Sopenharmony_ci{ 28162306a36Sopenharmony_ci if (seq) 28262306a36Sopenharmony_ci seq_hex_dump(seq, HEX_PREFIX, prefix_type, rowsize, groupsize, 28362306a36Sopenharmony_ci buf, len, ascii); 28462306a36Sopenharmony_ci else 28562306a36Sopenharmony_ci print_hex_dump(KERN_WARNING, pr_fmt(HEX_PREFIX), prefix_type, 28662306a36Sopenharmony_ci rowsize, groupsize, buf, len, ascii); 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci/* 29062306a36Sopenharmony_ci * Printing of the objects hex dump to the seq file. The number of lines to be 29162306a36Sopenharmony_ci * printed is limited to HEX_MAX_LINES to prevent seq file spamming. The 29262306a36Sopenharmony_ci * actual number of printed bytes depends on HEX_ROW_SIZE. It must be called 29362306a36Sopenharmony_ci * with the object->lock held. 29462306a36Sopenharmony_ci */ 29562306a36Sopenharmony_cistatic void hex_dump_object(struct seq_file *seq, 29662306a36Sopenharmony_ci struct kmemleak_object *object) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci const u8 *ptr = (const u8 *)object->pointer; 29962306a36Sopenharmony_ci size_t len; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci if (WARN_ON_ONCE(object->flags & OBJECT_PHYS)) 30262306a36Sopenharmony_ci return; 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci /* limit the number of lines to HEX_MAX_LINES */ 30562306a36Sopenharmony_ci len = min_t(size_t, object->size, HEX_MAX_LINES * HEX_ROW_SIZE); 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci warn_or_seq_printf(seq, " hex dump (first %zu bytes):\n", len); 30862306a36Sopenharmony_ci kasan_disable_current(); 30962306a36Sopenharmony_ci warn_or_seq_hex_dump(seq, DUMP_PREFIX_NONE, HEX_ROW_SIZE, 31062306a36Sopenharmony_ci HEX_GROUP_SIZE, kasan_reset_tag((void *)ptr), len, HEX_ASCII); 31162306a36Sopenharmony_ci kasan_enable_current(); 31262306a36Sopenharmony_ci} 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci/* 31562306a36Sopenharmony_ci * Object colors, encoded with count and min_count: 31662306a36Sopenharmony_ci * - white - orphan object, not enough references to it (count < min_count) 31762306a36Sopenharmony_ci * - gray - not orphan, not marked as false positive (min_count == 0) or 31862306a36Sopenharmony_ci * sufficient references to it (count >= min_count) 31962306a36Sopenharmony_ci * - black - ignore, it doesn't contain references (e.g. text section) 32062306a36Sopenharmony_ci * (min_count == -1). No function defined for this color. 32162306a36Sopenharmony_ci * Newly created objects don't have any color assigned (object->count == -1) 32262306a36Sopenharmony_ci * before the next memory scan when they become white. 32362306a36Sopenharmony_ci */ 32462306a36Sopenharmony_cistatic bool color_white(const struct kmemleak_object *object) 32562306a36Sopenharmony_ci{ 32662306a36Sopenharmony_ci return object->count != KMEMLEAK_BLACK && 32762306a36Sopenharmony_ci object->count < object->min_count; 32862306a36Sopenharmony_ci} 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_cistatic bool color_gray(const struct kmemleak_object *object) 33162306a36Sopenharmony_ci{ 33262306a36Sopenharmony_ci return object->min_count != KMEMLEAK_BLACK && 33362306a36Sopenharmony_ci object->count >= object->min_count; 33462306a36Sopenharmony_ci} 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci/* 33762306a36Sopenharmony_ci * Objects are considered unreferenced only if their color is white, they have 33862306a36Sopenharmony_ci * not be deleted and have a minimum age to avoid false positives caused by 33962306a36Sopenharmony_ci * pointers temporarily stored in CPU registers. 34062306a36Sopenharmony_ci */ 34162306a36Sopenharmony_cistatic bool unreferenced_object(struct kmemleak_object *object) 34262306a36Sopenharmony_ci{ 34362306a36Sopenharmony_ci return (color_white(object) && object->flags & OBJECT_ALLOCATED) && 34462306a36Sopenharmony_ci time_before_eq(object->jiffies + jiffies_min_age, 34562306a36Sopenharmony_ci jiffies_last_scan); 34662306a36Sopenharmony_ci} 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci/* 34962306a36Sopenharmony_ci * Printing of the unreferenced objects information to the seq file. The 35062306a36Sopenharmony_ci * print_unreferenced function must be called with the object->lock held. 35162306a36Sopenharmony_ci */ 35262306a36Sopenharmony_cistatic void print_unreferenced(struct seq_file *seq, 35362306a36Sopenharmony_ci struct kmemleak_object *object) 35462306a36Sopenharmony_ci{ 35562306a36Sopenharmony_ci int i; 35662306a36Sopenharmony_ci unsigned long *entries; 35762306a36Sopenharmony_ci unsigned int nr_entries; 35862306a36Sopenharmony_ci unsigned int msecs_age = jiffies_to_msecs(jiffies - object->jiffies); 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci nr_entries = stack_depot_fetch(object->trace_handle, &entries); 36162306a36Sopenharmony_ci warn_or_seq_printf(seq, "unreferenced object 0x%08lx (size %zu):\n", 36262306a36Sopenharmony_ci object->pointer, object->size); 36362306a36Sopenharmony_ci warn_or_seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu (age %d.%03ds)\n", 36462306a36Sopenharmony_ci object->comm, object->pid, object->jiffies, 36562306a36Sopenharmony_ci msecs_age / 1000, msecs_age % 1000); 36662306a36Sopenharmony_ci hex_dump_object(seq, object); 36762306a36Sopenharmony_ci warn_or_seq_printf(seq, " backtrace:\n"); 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci for (i = 0; i < nr_entries; i++) { 37062306a36Sopenharmony_ci void *ptr = (void *)entries[i]; 37162306a36Sopenharmony_ci warn_or_seq_printf(seq, " [<%pK>] %pS\n", ptr, ptr); 37262306a36Sopenharmony_ci } 37362306a36Sopenharmony_ci} 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci/* 37662306a36Sopenharmony_ci * Print the kmemleak_object information. This function is used mainly for 37762306a36Sopenharmony_ci * debugging special cases when kmemleak operations. It must be called with 37862306a36Sopenharmony_ci * the object->lock held. 37962306a36Sopenharmony_ci */ 38062306a36Sopenharmony_cistatic void dump_object_info(struct kmemleak_object *object) 38162306a36Sopenharmony_ci{ 38262306a36Sopenharmony_ci pr_notice("Object 0x%08lx (size %zu):\n", 38362306a36Sopenharmony_ci object->pointer, object->size); 38462306a36Sopenharmony_ci pr_notice(" comm \"%s\", pid %d, jiffies %lu\n", 38562306a36Sopenharmony_ci object->comm, object->pid, object->jiffies); 38662306a36Sopenharmony_ci pr_notice(" min_count = %d\n", object->min_count); 38762306a36Sopenharmony_ci pr_notice(" count = %d\n", object->count); 38862306a36Sopenharmony_ci pr_notice(" flags = 0x%x\n", object->flags); 38962306a36Sopenharmony_ci pr_notice(" checksum = %u\n", object->checksum); 39062306a36Sopenharmony_ci pr_notice(" backtrace:\n"); 39162306a36Sopenharmony_ci if (object->trace_handle) 39262306a36Sopenharmony_ci stack_depot_print(object->trace_handle); 39362306a36Sopenharmony_ci} 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci/* 39662306a36Sopenharmony_ci * Look-up a memory block metadata (kmemleak_object) in the object search 39762306a36Sopenharmony_ci * tree based on a pointer value. If alias is 0, only values pointing to the 39862306a36Sopenharmony_ci * beginning of the memory block are allowed. The kmemleak_lock must be held 39962306a36Sopenharmony_ci * when calling this function. 40062306a36Sopenharmony_ci */ 40162306a36Sopenharmony_cistatic struct kmemleak_object *__lookup_object(unsigned long ptr, int alias, 40262306a36Sopenharmony_ci bool is_phys) 40362306a36Sopenharmony_ci{ 40462306a36Sopenharmony_ci struct rb_node *rb = is_phys ? object_phys_tree_root.rb_node : 40562306a36Sopenharmony_ci object_tree_root.rb_node; 40662306a36Sopenharmony_ci unsigned long untagged_ptr = (unsigned long)kasan_reset_tag((void *)ptr); 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci while (rb) { 40962306a36Sopenharmony_ci struct kmemleak_object *object; 41062306a36Sopenharmony_ci unsigned long untagged_objp; 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci object = rb_entry(rb, struct kmemleak_object, rb_node); 41362306a36Sopenharmony_ci untagged_objp = (unsigned long)kasan_reset_tag((void *)object->pointer); 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci if (untagged_ptr < untagged_objp) 41662306a36Sopenharmony_ci rb = object->rb_node.rb_left; 41762306a36Sopenharmony_ci else if (untagged_objp + object->size <= untagged_ptr) 41862306a36Sopenharmony_ci rb = object->rb_node.rb_right; 41962306a36Sopenharmony_ci else if (untagged_objp == untagged_ptr || alias) 42062306a36Sopenharmony_ci return object; 42162306a36Sopenharmony_ci else { 42262306a36Sopenharmony_ci kmemleak_warn("Found object by alias at 0x%08lx\n", 42362306a36Sopenharmony_ci ptr); 42462306a36Sopenharmony_ci dump_object_info(object); 42562306a36Sopenharmony_ci break; 42662306a36Sopenharmony_ci } 42762306a36Sopenharmony_ci } 42862306a36Sopenharmony_ci return NULL; 42962306a36Sopenharmony_ci} 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci/* Look-up a kmemleak object which allocated with virtual address. */ 43262306a36Sopenharmony_cistatic struct kmemleak_object *lookup_object(unsigned long ptr, int alias) 43362306a36Sopenharmony_ci{ 43462306a36Sopenharmony_ci return __lookup_object(ptr, alias, false); 43562306a36Sopenharmony_ci} 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci/* 43862306a36Sopenharmony_ci * Increment the object use_count. Return 1 if successful or 0 otherwise. Note 43962306a36Sopenharmony_ci * that once an object's use_count reached 0, the RCU freeing was already 44062306a36Sopenharmony_ci * registered and the object should no longer be used. This function must be 44162306a36Sopenharmony_ci * called under the protection of rcu_read_lock(). 44262306a36Sopenharmony_ci */ 44362306a36Sopenharmony_cistatic int get_object(struct kmemleak_object *object) 44462306a36Sopenharmony_ci{ 44562306a36Sopenharmony_ci return atomic_inc_not_zero(&object->use_count); 44662306a36Sopenharmony_ci} 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci/* 44962306a36Sopenharmony_ci * Memory pool allocation and freeing. kmemleak_lock must not be held. 45062306a36Sopenharmony_ci */ 45162306a36Sopenharmony_cistatic struct kmemleak_object *mem_pool_alloc(gfp_t gfp) 45262306a36Sopenharmony_ci{ 45362306a36Sopenharmony_ci unsigned long flags; 45462306a36Sopenharmony_ci struct kmemleak_object *object; 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci /* try the slab allocator first */ 45762306a36Sopenharmony_ci if (object_cache) { 45862306a36Sopenharmony_ci object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp)); 45962306a36Sopenharmony_ci if (object) 46062306a36Sopenharmony_ci return object; 46162306a36Sopenharmony_ci } 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci /* slab allocation failed, try the memory pool */ 46462306a36Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 46562306a36Sopenharmony_ci object = list_first_entry_or_null(&mem_pool_free_list, 46662306a36Sopenharmony_ci typeof(*object), object_list); 46762306a36Sopenharmony_ci if (object) 46862306a36Sopenharmony_ci list_del(&object->object_list); 46962306a36Sopenharmony_ci else if (mem_pool_free_count) 47062306a36Sopenharmony_ci object = &mem_pool[--mem_pool_free_count]; 47162306a36Sopenharmony_ci else 47262306a36Sopenharmony_ci pr_warn_once("Memory pool empty, consider increasing CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE\n"); 47362306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci return object; 47662306a36Sopenharmony_ci} 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci/* 47962306a36Sopenharmony_ci * Return the object to either the slab allocator or the memory pool. 48062306a36Sopenharmony_ci */ 48162306a36Sopenharmony_cistatic void mem_pool_free(struct kmemleak_object *object) 48262306a36Sopenharmony_ci{ 48362306a36Sopenharmony_ci unsigned long flags; 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci if (object < mem_pool || object >= mem_pool + ARRAY_SIZE(mem_pool)) { 48662306a36Sopenharmony_ci kmem_cache_free(object_cache, object); 48762306a36Sopenharmony_ci return; 48862306a36Sopenharmony_ci } 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci /* add the object to the memory pool free list */ 49162306a36Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 49262306a36Sopenharmony_ci list_add(&object->object_list, &mem_pool_free_list); 49362306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 49462306a36Sopenharmony_ci} 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci/* 49762306a36Sopenharmony_ci * RCU callback to free a kmemleak_object. 49862306a36Sopenharmony_ci */ 49962306a36Sopenharmony_cistatic void free_object_rcu(struct rcu_head *rcu) 50062306a36Sopenharmony_ci{ 50162306a36Sopenharmony_ci struct hlist_node *tmp; 50262306a36Sopenharmony_ci struct kmemleak_scan_area *area; 50362306a36Sopenharmony_ci struct kmemleak_object *object = 50462306a36Sopenharmony_ci container_of(rcu, struct kmemleak_object, rcu); 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci /* 50762306a36Sopenharmony_ci * Once use_count is 0 (guaranteed by put_object), there is no other 50862306a36Sopenharmony_ci * code accessing this object, hence no need for locking. 50962306a36Sopenharmony_ci */ 51062306a36Sopenharmony_ci hlist_for_each_entry_safe(area, tmp, &object->area_list, node) { 51162306a36Sopenharmony_ci hlist_del(&area->node); 51262306a36Sopenharmony_ci kmem_cache_free(scan_area_cache, area); 51362306a36Sopenharmony_ci } 51462306a36Sopenharmony_ci mem_pool_free(object); 51562306a36Sopenharmony_ci} 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci/* 51862306a36Sopenharmony_ci * Decrement the object use_count. Once the count is 0, free the object using 51962306a36Sopenharmony_ci * an RCU callback. Since put_object() may be called via the kmemleak_free() -> 52062306a36Sopenharmony_ci * delete_object() path, the delayed RCU freeing ensures that there is no 52162306a36Sopenharmony_ci * recursive call to the kernel allocator. Lock-less RCU object_list traversal 52262306a36Sopenharmony_ci * is also possible. 52362306a36Sopenharmony_ci */ 52462306a36Sopenharmony_cistatic void put_object(struct kmemleak_object *object) 52562306a36Sopenharmony_ci{ 52662306a36Sopenharmony_ci if (!atomic_dec_and_test(&object->use_count)) 52762306a36Sopenharmony_ci return; 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci /* should only get here after delete_object was called */ 53062306a36Sopenharmony_ci WARN_ON(object->flags & OBJECT_ALLOCATED); 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci /* 53362306a36Sopenharmony_ci * It may be too early for the RCU callbacks, however, there is no 53462306a36Sopenharmony_ci * concurrent object_list traversal when !object_cache and all objects 53562306a36Sopenharmony_ci * came from the memory pool. Free the object directly. 53662306a36Sopenharmony_ci */ 53762306a36Sopenharmony_ci if (object_cache) 53862306a36Sopenharmony_ci call_rcu(&object->rcu, free_object_rcu); 53962306a36Sopenharmony_ci else 54062306a36Sopenharmony_ci free_object_rcu(&object->rcu); 54162306a36Sopenharmony_ci} 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci/* 54462306a36Sopenharmony_ci * Look up an object in the object search tree and increase its use_count. 54562306a36Sopenharmony_ci */ 54662306a36Sopenharmony_cistatic struct kmemleak_object *__find_and_get_object(unsigned long ptr, int alias, 54762306a36Sopenharmony_ci bool is_phys) 54862306a36Sopenharmony_ci{ 54962306a36Sopenharmony_ci unsigned long flags; 55062306a36Sopenharmony_ci struct kmemleak_object *object; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci rcu_read_lock(); 55362306a36Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 55462306a36Sopenharmony_ci object = __lookup_object(ptr, alias, is_phys); 55562306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci /* check whether the object is still available */ 55862306a36Sopenharmony_ci if (object && !get_object(object)) 55962306a36Sopenharmony_ci object = NULL; 56062306a36Sopenharmony_ci rcu_read_unlock(); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci return object; 56362306a36Sopenharmony_ci} 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci/* Look up and get an object which allocated with virtual address. */ 56662306a36Sopenharmony_cistatic struct kmemleak_object *find_and_get_object(unsigned long ptr, int alias) 56762306a36Sopenharmony_ci{ 56862306a36Sopenharmony_ci return __find_and_get_object(ptr, alias, false); 56962306a36Sopenharmony_ci} 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci/* 57262306a36Sopenharmony_ci * Remove an object from the object_tree_root (or object_phys_tree_root) 57362306a36Sopenharmony_ci * and object_list. Must be called with the kmemleak_lock held _if_ kmemleak 57462306a36Sopenharmony_ci * is still enabled. 57562306a36Sopenharmony_ci */ 57662306a36Sopenharmony_cistatic void __remove_object(struct kmemleak_object *object) 57762306a36Sopenharmony_ci{ 57862306a36Sopenharmony_ci rb_erase(&object->rb_node, object->flags & OBJECT_PHYS ? 57962306a36Sopenharmony_ci &object_phys_tree_root : 58062306a36Sopenharmony_ci &object_tree_root); 58162306a36Sopenharmony_ci if (!(object->del_state & DELSTATE_NO_DELETE)) 58262306a36Sopenharmony_ci list_del_rcu(&object->object_list); 58362306a36Sopenharmony_ci object->del_state |= DELSTATE_REMOVED; 58462306a36Sopenharmony_ci} 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci/* 58762306a36Sopenharmony_ci * Look up an object in the object search tree and remove it from both 58862306a36Sopenharmony_ci * object_tree_root (or object_phys_tree_root) and object_list. The 58962306a36Sopenharmony_ci * returned object's use_count should be at least 1, as initially set 59062306a36Sopenharmony_ci * by create_object(). 59162306a36Sopenharmony_ci */ 59262306a36Sopenharmony_cistatic struct kmemleak_object *find_and_remove_object(unsigned long ptr, int alias, 59362306a36Sopenharmony_ci bool is_phys) 59462306a36Sopenharmony_ci{ 59562306a36Sopenharmony_ci unsigned long flags; 59662306a36Sopenharmony_ci struct kmemleak_object *object; 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 59962306a36Sopenharmony_ci object = __lookup_object(ptr, alias, is_phys); 60062306a36Sopenharmony_ci if (object) 60162306a36Sopenharmony_ci __remove_object(object); 60262306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci return object; 60562306a36Sopenharmony_ci} 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_cistatic noinline depot_stack_handle_t set_track_prepare(void) 60862306a36Sopenharmony_ci{ 60962306a36Sopenharmony_ci depot_stack_handle_t trace_handle; 61062306a36Sopenharmony_ci unsigned long entries[MAX_TRACE]; 61162306a36Sopenharmony_ci unsigned int nr_entries; 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci /* 61462306a36Sopenharmony_ci * Use object_cache to determine whether kmemleak_init() has 61562306a36Sopenharmony_ci * been invoked. stack_depot_early_init() is called before 61662306a36Sopenharmony_ci * kmemleak_init() in mm_core_init(). 61762306a36Sopenharmony_ci */ 61862306a36Sopenharmony_ci if (!object_cache) 61962306a36Sopenharmony_ci return 0; 62062306a36Sopenharmony_ci nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 3); 62162306a36Sopenharmony_ci trace_handle = stack_depot_save(entries, nr_entries, GFP_NOWAIT); 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci return trace_handle; 62462306a36Sopenharmony_ci} 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci/* 62762306a36Sopenharmony_ci * Create the metadata (struct kmemleak_object) corresponding to an allocated 62862306a36Sopenharmony_ci * memory block and add it to the object_list and object_tree_root (or 62962306a36Sopenharmony_ci * object_phys_tree_root). 63062306a36Sopenharmony_ci */ 63162306a36Sopenharmony_cistatic void __create_object(unsigned long ptr, size_t size, 63262306a36Sopenharmony_ci int min_count, gfp_t gfp, bool is_phys) 63362306a36Sopenharmony_ci{ 63462306a36Sopenharmony_ci unsigned long flags; 63562306a36Sopenharmony_ci struct kmemleak_object *object, *parent; 63662306a36Sopenharmony_ci struct rb_node **link, *rb_parent; 63762306a36Sopenharmony_ci unsigned long untagged_ptr; 63862306a36Sopenharmony_ci unsigned long untagged_objp; 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci object = mem_pool_alloc(gfp); 64162306a36Sopenharmony_ci if (!object) { 64262306a36Sopenharmony_ci pr_warn("Cannot allocate a kmemleak_object structure\n"); 64362306a36Sopenharmony_ci kmemleak_disable(); 64462306a36Sopenharmony_ci return; 64562306a36Sopenharmony_ci } 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci INIT_LIST_HEAD(&object->object_list); 64862306a36Sopenharmony_ci INIT_LIST_HEAD(&object->gray_list); 64962306a36Sopenharmony_ci INIT_HLIST_HEAD(&object->area_list); 65062306a36Sopenharmony_ci raw_spin_lock_init(&object->lock); 65162306a36Sopenharmony_ci atomic_set(&object->use_count, 1); 65262306a36Sopenharmony_ci object->flags = OBJECT_ALLOCATED | (is_phys ? OBJECT_PHYS : 0); 65362306a36Sopenharmony_ci object->pointer = ptr; 65462306a36Sopenharmony_ci object->size = kfence_ksize((void *)ptr) ?: size; 65562306a36Sopenharmony_ci object->excess_ref = 0; 65662306a36Sopenharmony_ci object->min_count = min_count; 65762306a36Sopenharmony_ci object->count = 0; /* white color initially */ 65862306a36Sopenharmony_ci object->jiffies = jiffies; 65962306a36Sopenharmony_ci object->checksum = 0; 66062306a36Sopenharmony_ci object->del_state = 0; 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci /* task information */ 66362306a36Sopenharmony_ci if (in_hardirq()) { 66462306a36Sopenharmony_ci object->pid = 0; 66562306a36Sopenharmony_ci strncpy(object->comm, "hardirq", sizeof(object->comm)); 66662306a36Sopenharmony_ci } else if (in_serving_softirq()) { 66762306a36Sopenharmony_ci object->pid = 0; 66862306a36Sopenharmony_ci strncpy(object->comm, "softirq", sizeof(object->comm)); 66962306a36Sopenharmony_ci } else { 67062306a36Sopenharmony_ci object->pid = current->pid; 67162306a36Sopenharmony_ci /* 67262306a36Sopenharmony_ci * There is a small chance of a race with set_task_comm(), 67362306a36Sopenharmony_ci * however using get_task_comm() here may cause locking 67462306a36Sopenharmony_ci * dependency issues with current->alloc_lock. In the worst 67562306a36Sopenharmony_ci * case, the command line is not correct. 67662306a36Sopenharmony_ci */ 67762306a36Sopenharmony_ci strncpy(object->comm, current->comm, sizeof(object->comm)); 67862306a36Sopenharmony_ci } 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci /* kernel backtrace */ 68162306a36Sopenharmony_ci object->trace_handle = set_track_prepare(); 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci untagged_ptr = (unsigned long)kasan_reset_tag((void *)ptr); 68662306a36Sopenharmony_ci /* 68762306a36Sopenharmony_ci * Only update min_addr and max_addr with object 68862306a36Sopenharmony_ci * storing virtual address. 68962306a36Sopenharmony_ci */ 69062306a36Sopenharmony_ci if (!is_phys) { 69162306a36Sopenharmony_ci min_addr = min(min_addr, untagged_ptr); 69262306a36Sopenharmony_ci max_addr = max(max_addr, untagged_ptr + size); 69362306a36Sopenharmony_ci } 69462306a36Sopenharmony_ci link = is_phys ? &object_phys_tree_root.rb_node : 69562306a36Sopenharmony_ci &object_tree_root.rb_node; 69662306a36Sopenharmony_ci rb_parent = NULL; 69762306a36Sopenharmony_ci while (*link) { 69862306a36Sopenharmony_ci rb_parent = *link; 69962306a36Sopenharmony_ci parent = rb_entry(rb_parent, struct kmemleak_object, rb_node); 70062306a36Sopenharmony_ci untagged_objp = (unsigned long)kasan_reset_tag((void *)parent->pointer); 70162306a36Sopenharmony_ci if (untagged_ptr + size <= untagged_objp) 70262306a36Sopenharmony_ci link = &parent->rb_node.rb_left; 70362306a36Sopenharmony_ci else if (untagged_objp + parent->size <= untagged_ptr) 70462306a36Sopenharmony_ci link = &parent->rb_node.rb_right; 70562306a36Sopenharmony_ci else { 70662306a36Sopenharmony_ci kmemleak_stop("Cannot insert 0x%lx into the object search tree (overlaps existing)\n", 70762306a36Sopenharmony_ci ptr); 70862306a36Sopenharmony_ci /* 70962306a36Sopenharmony_ci * No need for parent->lock here since "parent" cannot 71062306a36Sopenharmony_ci * be freed while the kmemleak_lock is held. 71162306a36Sopenharmony_ci */ 71262306a36Sopenharmony_ci dump_object_info(parent); 71362306a36Sopenharmony_ci kmem_cache_free(object_cache, object); 71462306a36Sopenharmony_ci goto out; 71562306a36Sopenharmony_ci } 71662306a36Sopenharmony_ci } 71762306a36Sopenharmony_ci rb_link_node(&object->rb_node, rb_parent, link); 71862306a36Sopenharmony_ci rb_insert_color(&object->rb_node, is_phys ? &object_phys_tree_root : 71962306a36Sopenharmony_ci &object_tree_root); 72062306a36Sopenharmony_ci list_add_tail_rcu(&object->object_list, &object_list); 72162306a36Sopenharmony_ciout: 72262306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 72362306a36Sopenharmony_ci} 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci/* Create kmemleak object which allocated with virtual address. */ 72662306a36Sopenharmony_cistatic void create_object(unsigned long ptr, size_t size, 72762306a36Sopenharmony_ci int min_count, gfp_t gfp) 72862306a36Sopenharmony_ci{ 72962306a36Sopenharmony_ci __create_object(ptr, size, min_count, gfp, false); 73062306a36Sopenharmony_ci} 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_ci/* Create kmemleak object which allocated with physical address. */ 73362306a36Sopenharmony_cistatic void create_object_phys(unsigned long ptr, size_t size, 73462306a36Sopenharmony_ci int min_count, gfp_t gfp) 73562306a36Sopenharmony_ci{ 73662306a36Sopenharmony_ci __create_object(ptr, size, min_count, gfp, true); 73762306a36Sopenharmony_ci} 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_ci/* 74062306a36Sopenharmony_ci * Mark the object as not allocated and schedule RCU freeing via put_object(). 74162306a36Sopenharmony_ci */ 74262306a36Sopenharmony_cistatic void __delete_object(struct kmemleak_object *object) 74362306a36Sopenharmony_ci{ 74462306a36Sopenharmony_ci unsigned long flags; 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci WARN_ON(!(object->flags & OBJECT_ALLOCATED)); 74762306a36Sopenharmony_ci WARN_ON(atomic_read(&object->use_count) < 1); 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_ci /* 75062306a36Sopenharmony_ci * Locking here also ensures that the corresponding memory block 75162306a36Sopenharmony_ci * cannot be freed when it is being scanned. 75262306a36Sopenharmony_ci */ 75362306a36Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 75462306a36Sopenharmony_ci object->flags &= ~OBJECT_ALLOCATED; 75562306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 75662306a36Sopenharmony_ci put_object(object); 75762306a36Sopenharmony_ci} 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci/* 76062306a36Sopenharmony_ci * Look up the metadata (struct kmemleak_object) corresponding to ptr and 76162306a36Sopenharmony_ci * delete it. 76262306a36Sopenharmony_ci */ 76362306a36Sopenharmony_cistatic void delete_object_full(unsigned long ptr) 76462306a36Sopenharmony_ci{ 76562306a36Sopenharmony_ci struct kmemleak_object *object; 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci object = find_and_remove_object(ptr, 0, false); 76862306a36Sopenharmony_ci if (!object) { 76962306a36Sopenharmony_ci#ifdef DEBUG 77062306a36Sopenharmony_ci kmemleak_warn("Freeing unknown object at 0x%08lx\n", 77162306a36Sopenharmony_ci ptr); 77262306a36Sopenharmony_ci#endif 77362306a36Sopenharmony_ci return; 77462306a36Sopenharmony_ci } 77562306a36Sopenharmony_ci __delete_object(object); 77662306a36Sopenharmony_ci} 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ci/* 77962306a36Sopenharmony_ci * Look up the metadata (struct kmemleak_object) corresponding to ptr and 78062306a36Sopenharmony_ci * delete it. If the memory block is partially freed, the function may create 78162306a36Sopenharmony_ci * additional metadata for the remaining parts of the block. 78262306a36Sopenharmony_ci */ 78362306a36Sopenharmony_cistatic void delete_object_part(unsigned long ptr, size_t size, bool is_phys) 78462306a36Sopenharmony_ci{ 78562306a36Sopenharmony_ci struct kmemleak_object *object; 78662306a36Sopenharmony_ci unsigned long start, end; 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci object = find_and_remove_object(ptr, 1, is_phys); 78962306a36Sopenharmony_ci if (!object) { 79062306a36Sopenharmony_ci#ifdef DEBUG 79162306a36Sopenharmony_ci kmemleak_warn("Partially freeing unknown object at 0x%08lx (size %zu)\n", 79262306a36Sopenharmony_ci ptr, size); 79362306a36Sopenharmony_ci#endif 79462306a36Sopenharmony_ci return; 79562306a36Sopenharmony_ci } 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci /* 79862306a36Sopenharmony_ci * Create one or two objects that may result from the memory block 79962306a36Sopenharmony_ci * split. Note that partial freeing is only done by free_bootmem() and 80062306a36Sopenharmony_ci * this happens before kmemleak_init() is called. 80162306a36Sopenharmony_ci */ 80262306a36Sopenharmony_ci start = object->pointer; 80362306a36Sopenharmony_ci end = object->pointer + object->size; 80462306a36Sopenharmony_ci if (ptr > start) 80562306a36Sopenharmony_ci __create_object(start, ptr - start, object->min_count, 80662306a36Sopenharmony_ci GFP_KERNEL, is_phys); 80762306a36Sopenharmony_ci if (ptr + size < end) 80862306a36Sopenharmony_ci __create_object(ptr + size, end - ptr - size, object->min_count, 80962306a36Sopenharmony_ci GFP_KERNEL, is_phys); 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_ci __delete_object(object); 81262306a36Sopenharmony_ci} 81362306a36Sopenharmony_ci 81462306a36Sopenharmony_cistatic void __paint_it(struct kmemleak_object *object, int color) 81562306a36Sopenharmony_ci{ 81662306a36Sopenharmony_ci object->min_count = color; 81762306a36Sopenharmony_ci if (color == KMEMLEAK_BLACK) 81862306a36Sopenharmony_ci object->flags |= OBJECT_NO_SCAN; 81962306a36Sopenharmony_ci} 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_cistatic void paint_it(struct kmemleak_object *object, int color) 82262306a36Sopenharmony_ci{ 82362306a36Sopenharmony_ci unsigned long flags; 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 82662306a36Sopenharmony_ci __paint_it(object, color); 82762306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 82862306a36Sopenharmony_ci} 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_cistatic void paint_ptr(unsigned long ptr, int color, bool is_phys) 83162306a36Sopenharmony_ci{ 83262306a36Sopenharmony_ci struct kmemleak_object *object; 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_ci object = __find_and_get_object(ptr, 0, is_phys); 83562306a36Sopenharmony_ci if (!object) { 83662306a36Sopenharmony_ci kmemleak_warn("Trying to color unknown object at 0x%08lx as %s\n", 83762306a36Sopenharmony_ci ptr, 83862306a36Sopenharmony_ci (color == KMEMLEAK_GREY) ? "Grey" : 83962306a36Sopenharmony_ci (color == KMEMLEAK_BLACK) ? "Black" : "Unknown"); 84062306a36Sopenharmony_ci return; 84162306a36Sopenharmony_ci } 84262306a36Sopenharmony_ci paint_it(object, color); 84362306a36Sopenharmony_ci put_object(object); 84462306a36Sopenharmony_ci} 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci/* 84762306a36Sopenharmony_ci * Mark an object permanently as gray-colored so that it can no longer be 84862306a36Sopenharmony_ci * reported as a leak. This is used in general to mark a false positive. 84962306a36Sopenharmony_ci */ 85062306a36Sopenharmony_cistatic void make_gray_object(unsigned long ptr) 85162306a36Sopenharmony_ci{ 85262306a36Sopenharmony_ci paint_ptr(ptr, KMEMLEAK_GREY, false); 85362306a36Sopenharmony_ci} 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci/* 85662306a36Sopenharmony_ci * Mark the object as black-colored so that it is ignored from scans and 85762306a36Sopenharmony_ci * reporting. 85862306a36Sopenharmony_ci */ 85962306a36Sopenharmony_cistatic void make_black_object(unsigned long ptr, bool is_phys) 86062306a36Sopenharmony_ci{ 86162306a36Sopenharmony_ci paint_ptr(ptr, KMEMLEAK_BLACK, is_phys); 86262306a36Sopenharmony_ci} 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci/* 86562306a36Sopenharmony_ci * Add a scanning area to the object. If at least one such area is added, 86662306a36Sopenharmony_ci * kmemleak will only scan these ranges rather than the whole memory block. 86762306a36Sopenharmony_ci */ 86862306a36Sopenharmony_cistatic void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) 86962306a36Sopenharmony_ci{ 87062306a36Sopenharmony_ci unsigned long flags; 87162306a36Sopenharmony_ci struct kmemleak_object *object; 87262306a36Sopenharmony_ci struct kmemleak_scan_area *area = NULL; 87362306a36Sopenharmony_ci unsigned long untagged_ptr; 87462306a36Sopenharmony_ci unsigned long untagged_objp; 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_ci object = find_and_get_object(ptr, 1); 87762306a36Sopenharmony_ci if (!object) { 87862306a36Sopenharmony_ci kmemleak_warn("Adding scan area to unknown object at 0x%08lx\n", 87962306a36Sopenharmony_ci ptr); 88062306a36Sopenharmony_ci return; 88162306a36Sopenharmony_ci } 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci untagged_ptr = (unsigned long)kasan_reset_tag((void *)ptr); 88462306a36Sopenharmony_ci untagged_objp = (unsigned long)kasan_reset_tag((void *)object->pointer); 88562306a36Sopenharmony_ci 88662306a36Sopenharmony_ci if (scan_area_cache) 88762306a36Sopenharmony_ci area = kmem_cache_alloc(scan_area_cache, gfp_kmemleak_mask(gfp)); 88862306a36Sopenharmony_ci 88962306a36Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 89062306a36Sopenharmony_ci if (!area) { 89162306a36Sopenharmony_ci pr_warn_once("Cannot allocate a scan area, scanning the full object\n"); 89262306a36Sopenharmony_ci /* mark the object for full scan to avoid false positives */ 89362306a36Sopenharmony_ci object->flags |= OBJECT_FULL_SCAN; 89462306a36Sopenharmony_ci goto out_unlock; 89562306a36Sopenharmony_ci } 89662306a36Sopenharmony_ci if (size == SIZE_MAX) { 89762306a36Sopenharmony_ci size = untagged_objp + object->size - untagged_ptr; 89862306a36Sopenharmony_ci } else if (untagged_ptr + size > untagged_objp + object->size) { 89962306a36Sopenharmony_ci kmemleak_warn("Scan area larger than object 0x%08lx\n", ptr); 90062306a36Sopenharmony_ci dump_object_info(object); 90162306a36Sopenharmony_ci kmem_cache_free(scan_area_cache, area); 90262306a36Sopenharmony_ci goto out_unlock; 90362306a36Sopenharmony_ci } 90462306a36Sopenharmony_ci 90562306a36Sopenharmony_ci INIT_HLIST_NODE(&area->node); 90662306a36Sopenharmony_ci area->start = ptr; 90762306a36Sopenharmony_ci area->size = size; 90862306a36Sopenharmony_ci 90962306a36Sopenharmony_ci hlist_add_head(&area->node, &object->area_list); 91062306a36Sopenharmony_ciout_unlock: 91162306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 91262306a36Sopenharmony_ci put_object(object); 91362306a36Sopenharmony_ci} 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_ci/* 91662306a36Sopenharmony_ci * Any surplus references (object already gray) to 'ptr' are passed to 91762306a36Sopenharmony_ci * 'excess_ref'. This is used in the vmalloc() case where a pointer to 91862306a36Sopenharmony_ci * vm_struct may be used as an alternative reference to the vmalloc'ed object 91962306a36Sopenharmony_ci * (see free_thread_stack()). 92062306a36Sopenharmony_ci */ 92162306a36Sopenharmony_cistatic void object_set_excess_ref(unsigned long ptr, unsigned long excess_ref) 92262306a36Sopenharmony_ci{ 92362306a36Sopenharmony_ci unsigned long flags; 92462306a36Sopenharmony_ci struct kmemleak_object *object; 92562306a36Sopenharmony_ci 92662306a36Sopenharmony_ci object = find_and_get_object(ptr, 0); 92762306a36Sopenharmony_ci if (!object) { 92862306a36Sopenharmony_ci kmemleak_warn("Setting excess_ref on unknown object at 0x%08lx\n", 92962306a36Sopenharmony_ci ptr); 93062306a36Sopenharmony_ci return; 93162306a36Sopenharmony_ci } 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 93462306a36Sopenharmony_ci object->excess_ref = excess_ref; 93562306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 93662306a36Sopenharmony_ci put_object(object); 93762306a36Sopenharmony_ci} 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_ci/* 94062306a36Sopenharmony_ci * Set the OBJECT_NO_SCAN flag for the object corresponding to the give 94162306a36Sopenharmony_ci * pointer. Such object will not be scanned by kmemleak but references to it 94262306a36Sopenharmony_ci * are searched. 94362306a36Sopenharmony_ci */ 94462306a36Sopenharmony_cistatic void object_no_scan(unsigned long ptr) 94562306a36Sopenharmony_ci{ 94662306a36Sopenharmony_ci unsigned long flags; 94762306a36Sopenharmony_ci struct kmemleak_object *object; 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci object = find_and_get_object(ptr, 0); 95062306a36Sopenharmony_ci if (!object) { 95162306a36Sopenharmony_ci kmemleak_warn("Not scanning unknown object at 0x%08lx\n", ptr); 95262306a36Sopenharmony_ci return; 95362306a36Sopenharmony_ci } 95462306a36Sopenharmony_ci 95562306a36Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 95662306a36Sopenharmony_ci object->flags |= OBJECT_NO_SCAN; 95762306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 95862306a36Sopenharmony_ci put_object(object); 95962306a36Sopenharmony_ci} 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci/** 96262306a36Sopenharmony_ci * kmemleak_alloc - register a newly allocated object 96362306a36Sopenharmony_ci * @ptr: pointer to beginning of the object 96462306a36Sopenharmony_ci * @size: size of the object 96562306a36Sopenharmony_ci * @min_count: minimum number of references to this object. If during memory 96662306a36Sopenharmony_ci * scanning a number of references less than @min_count is found, 96762306a36Sopenharmony_ci * the object is reported as a memory leak. If @min_count is 0, 96862306a36Sopenharmony_ci * the object is never reported as a leak. If @min_count is -1, 96962306a36Sopenharmony_ci * the object is ignored (not scanned and not reported as a leak) 97062306a36Sopenharmony_ci * @gfp: kmalloc() flags used for kmemleak internal memory allocations 97162306a36Sopenharmony_ci * 97262306a36Sopenharmony_ci * This function is called from the kernel allocators when a new object 97362306a36Sopenharmony_ci * (memory block) is allocated (kmem_cache_alloc, kmalloc etc.). 97462306a36Sopenharmony_ci */ 97562306a36Sopenharmony_civoid __ref kmemleak_alloc(const void *ptr, size_t size, int min_count, 97662306a36Sopenharmony_ci gfp_t gfp) 97762306a36Sopenharmony_ci{ 97862306a36Sopenharmony_ci pr_debug("%s(0x%p, %zu, %d)\n", __func__, ptr, size, min_count); 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 98162306a36Sopenharmony_ci create_object((unsigned long)ptr, size, min_count, gfp); 98262306a36Sopenharmony_ci} 98362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_alloc); 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ci/** 98662306a36Sopenharmony_ci * kmemleak_alloc_percpu - register a newly allocated __percpu object 98762306a36Sopenharmony_ci * @ptr: __percpu pointer to beginning of the object 98862306a36Sopenharmony_ci * @size: size of the object 98962306a36Sopenharmony_ci * @gfp: flags used for kmemleak internal memory allocations 99062306a36Sopenharmony_ci * 99162306a36Sopenharmony_ci * This function is called from the kernel percpu allocator when a new object 99262306a36Sopenharmony_ci * (memory block) is allocated (alloc_percpu). 99362306a36Sopenharmony_ci */ 99462306a36Sopenharmony_civoid __ref kmemleak_alloc_percpu(const void __percpu *ptr, size_t size, 99562306a36Sopenharmony_ci gfp_t gfp) 99662306a36Sopenharmony_ci{ 99762306a36Sopenharmony_ci unsigned int cpu; 99862306a36Sopenharmony_ci 99962306a36Sopenharmony_ci pr_debug("%s(0x%p, %zu)\n", __func__, ptr, size); 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_ci /* 100262306a36Sopenharmony_ci * Percpu allocations are only scanned and not reported as leaks 100362306a36Sopenharmony_ci * (min_count is set to 0). 100462306a36Sopenharmony_ci */ 100562306a36Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 100662306a36Sopenharmony_ci for_each_possible_cpu(cpu) 100762306a36Sopenharmony_ci create_object((unsigned long)per_cpu_ptr(ptr, cpu), 100862306a36Sopenharmony_ci size, 0, gfp); 100962306a36Sopenharmony_ci} 101062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_alloc_percpu); 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ci/** 101362306a36Sopenharmony_ci * kmemleak_vmalloc - register a newly vmalloc'ed object 101462306a36Sopenharmony_ci * @area: pointer to vm_struct 101562306a36Sopenharmony_ci * @size: size of the object 101662306a36Sopenharmony_ci * @gfp: __vmalloc() flags used for kmemleak internal memory allocations 101762306a36Sopenharmony_ci * 101862306a36Sopenharmony_ci * This function is called from the vmalloc() kernel allocator when a new 101962306a36Sopenharmony_ci * object (memory block) is allocated. 102062306a36Sopenharmony_ci */ 102162306a36Sopenharmony_civoid __ref kmemleak_vmalloc(const struct vm_struct *area, size_t size, gfp_t gfp) 102262306a36Sopenharmony_ci{ 102362306a36Sopenharmony_ci pr_debug("%s(0x%p, %zu)\n", __func__, area, size); 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_ci /* 102662306a36Sopenharmony_ci * A min_count = 2 is needed because vm_struct contains a reference to 102762306a36Sopenharmony_ci * the virtual address of the vmalloc'ed block. 102862306a36Sopenharmony_ci */ 102962306a36Sopenharmony_ci if (kmemleak_enabled) { 103062306a36Sopenharmony_ci create_object((unsigned long)area->addr, size, 2, gfp); 103162306a36Sopenharmony_ci object_set_excess_ref((unsigned long)area, 103262306a36Sopenharmony_ci (unsigned long)area->addr); 103362306a36Sopenharmony_ci } 103462306a36Sopenharmony_ci} 103562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_vmalloc); 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ci/** 103862306a36Sopenharmony_ci * kmemleak_free - unregister a previously registered object 103962306a36Sopenharmony_ci * @ptr: pointer to beginning of the object 104062306a36Sopenharmony_ci * 104162306a36Sopenharmony_ci * This function is called from the kernel allocators when an object (memory 104262306a36Sopenharmony_ci * block) is freed (kmem_cache_free, kfree, vfree etc.). 104362306a36Sopenharmony_ci */ 104462306a36Sopenharmony_civoid __ref kmemleak_free(const void *ptr) 104562306a36Sopenharmony_ci{ 104662306a36Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 104762306a36Sopenharmony_ci 104862306a36Sopenharmony_ci if (kmemleak_free_enabled && ptr && !IS_ERR(ptr)) 104962306a36Sopenharmony_ci delete_object_full((unsigned long)ptr); 105062306a36Sopenharmony_ci} 105162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_free); 105262306a36Sopenharmony_ci 105362306a36Sopenharmony_ci/** 105462306a36Sopenharmony_ci * kmemleak_free_part - partially unregister a previously registered object 105562306a36Sopenharmony_ci * @ptr: pointer to the beginning or inside the object. This also 105662306a36Sopenharmony_ci * represents the start of the range to be freed 105762306a36Sopenharmony_ci * @size: size to be unregistered 105862306a36Sopenharmony_ci * 105962306a36Sopenharmony_ci * This function is called when only a part of a memory block is freed 106062306a36Sopenharmony_ci * (usually from the bootmem allocator). 106162306a36Sopenharmony_ci */ 106262306a36Sopenharmony_civoid __ref kmemleak_free_part(const void *ptr, size_t size) 106362306a36Sopenharmony_ci{ 106462306a36Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 106562306a36Sopenharmony_ci 106662306a36Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 106762306a36Sopenharmony_ci delete_object_part((unsigned long)ptr, size, false); 106862306a36Sopenharmony_ci} 106962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_free_part); 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci/** 107262306a36Sopenharmony_ci * kmemleak_free_percpu - unregister a previously registered __percpu object 107362306a36Sopenharmony_ci * @ptr: __percpu pointer to beginning of the object 107462306a36Sopenharmony_ci * 107562306a36Sopenharmony_ci * This function is called from the kernel percpu allocator when an object 107662306a36Sopenharmony_ci * (memory block) is freed (free_percpu). 107762306a36Sopenharmony_ci */ 107862306a36Sopenharmony_civoid __ref kmemleak_free_percpu(const void __percpu *ptr) 107962306a36Sopenharmony_ci{ 108062306a36Sopenharmony_ci unsigned int cpu; 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_ci if (kmemleak_free_enabled && ptr && !IS_ERR(ptr)) 108562306a36Sopenharmony_ci for_each_possible_cpu(cpu) 108662306a36Sopenharmony_ci delete_object_full((unsigned long)per_cpu_ptr(ptr, 108762306a36Sopenharmony_ci cpu)); 108862306a36Sopenharmony_ci} 108962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(kmemleak_free_percpu); 109062306a36Sopenharmony_ci 109162306a36Sopenharmony_ci/** 109262306a36Sopenharmony_ci * kmemleak_update_trace - update object allocation stack trace 109362306a36Sopenharmony_ci * @ptr: pointer to beginning of the object 109462306a36Sopenharmony_ci * 109562306a36Sopenharmony_ci * Override the object allocation stack trace for cases where the actual 109662306a36Sopenharmony_ci * allocation place is not always useful. 109762306a36Sopenharmony_ci */ 109862306a36Sopenharmony_civoid __ref kmemleak_update_trace(const void *ptr) 109962306a36Sopenharmony_ci{ 110062306a36Sopenharmony_ci struct kmemleak_object *object; 110162306a36Sopenharmony_ci unsigned long flags; 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 110462306a36Sopenharmony_ci 110562306a36Sopenharmony_ci if (!kmemleak_enabled || IS_ERR_OR_NULL(ptr)) 110662306a36Sopenharmony_ci return; 110762306a36Sopenharmony_ci 110862306a36Sopenharmony_ci object = find_and_get_object((unsigned long)ptr, 1); 110962306a36Sopenharmony_ci if (!object) { 111062306a36Sopenharmony_ci#ifdef DEBUG 111162306a36Sopenharmony_ci kmemleak_warn("Updating stack trace for unknown object at %p\n", 111262306a36Sopenharmony_ci ptr); 111362306a36Sopenharmony_ci#endif 111462306a36Sopenharmony_ci return; 111562306a36Sopenharmony_ci } 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 111862306a36Sopenharmony_ci object->trace_handle = set_track_prepare(); 111962306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 112062306a36Sopenharmony_ci 112162306a36Sopenharmony_ci put_object(object); 112262306a36Sopenharmony_ci} 112362306a36Sopenharmony_ciEXPORT_SYMBOL(kmemleak_update_trace); 112462306a36Sopenharmony_ci 112562306a36Sopenharmony_ci/** 112662306a36Sopenharmony_ci * kmemleak_not_leak - mark an allocated object as false positive 112762306a36Sopenharmony_ci * @ptr: pointer to beginning of the object 112862306a36Sopenharmony_ci * 112962306a36Sopenharmony_ci * Calling this function on an object will cause the memory block to no longer 113062306a36Sopenharmony_ci * be reported as leak and always be scanned. 113162306a36Sopenharmony_ci */ 113262306a36Sopenharmony_civoid __ref kmemleak_not_leak(const void *ptr) 113362306a36Sopenharmony_ci{ 113462306a36Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 113562306a36Sopenharmony_ci 113662306a36Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 113762306a36Sopenharmony_ci make_gray_object((unsigned long)ptr); 113862306a36Sopenharmony_ci} 113962306a36Sopenharmony_ciEXPORT_SYMBOL(kmemleak_not_leak); 114062306a36Sopenharmony_ci 114162306a36Sopenharmony_ci/** 114262306a36Sopenharmony_ci * kmemleak_ignore - ignore an allocated object 114362306a36Sopenharmony_ci * @ptr: pointer to beginning of the object 114462306a36Sopenharmony_ci * 114562306a36Sopenharmony_ci * Calling this function on an object will cause the memory block to be 114662306a36Sopenharmony_ci * ignored (not scanned and not reported as a leak). This is usually done when 114762306a36Sopenharmony_ci * it is known that the corresponding block is not a leak and does not contain 114862306a36Sopenharmony_ci * any references to other allocated memory blocks. 114962306a36Sopenharmony_ci */ 115062306a36Sopenharmony_civoid __ref kmemleak_ignore(const void *ptr) 115162306a36Sopenharmony_ci{ 115262306a36Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 115362306a36Sopenharmony_ci 115462306a36Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 115562306a36Sopenharmony_ci make_black_object((unsigned long)ptr, false); 115662306a36Sopenharmony_ci} 115762306a36Sopenharmony_ciEXPORT_SYMBOL(kmemleak_ignore); 115862306a36Sopenharmony_ci 115962306a36Sopenharmony_ci/** 116062306a36Sopenharmony_ci * kmemleak_scan_area - limit the range to be scanned in an allocated object 116162306a36Sopenharmony_ci * @ptr: pointer to beginning or inside the object. This also 116262306a36Sopenharmony_ci * represents the start of the scan area 116362306a36Sopenharmony_ci * @size: size of the scan area 116462306a36Sopenharmony_ci * @gfp: kmalloc() flags used for kmemleak internal memory allocations 116562306a36Sopenharmony_ci * 116662306a36Sopenharmony_ci * This function is used when it is known that only certain parts of an object 116762306a36Sopenharmony_ci * contain references to other objects. Kmemleak will only scan these areas 116862306a36Sopenharmony_ci * reducing the number false negatives. 116962306a36Sopenharmony_ci */ 117062306a36Sopenharmony_civoid __ref kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) 117162306a36Sopenharmony_ci{ 117262306a36Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 117362306a36Sopenharmony_ci 117462306a36Sopenharmony_ci if (kmemleak_enabled && ptr && size && !IS_ERR(ptr)) 117562306a36Sopenharmony_ci add_scan_area((unsigned long)ptr, size, gfp); 117662306a36Sopenharmony_ci} 117762306a36Sopenharmony_ciEXPORT_SYMBOL(kmemleak_scan_area); 117862306a36Sopenharmony_ci 117962306a36Sopenharmony_ci/** 118062306a36Sopenharmony_ci * kmemleak_no_scan - do not scan an allocated object 118162306a36Sopenharmony_ci * @ptr: pointer to beginning of the object 118262306a36Sopenharmony_ci * 118362306a36Sopenharmony_ci * This function notifies kmemleak not to scan the given memory block. Useful 118462306a36Sopenharmony_ci * in situations where it is known that the given object does not contain any 118562306a36Sopenharmony_ci * references to other objects. Kmemleak will not scan such objects reducing 118662306a36Sopenharmony_ci * the number of false negatives. 118762306a36Sopenharmony_ci */ 118862306a36Sopenharmony_civoid __ref kmemleak_no_scan(const void *ptr) 118962306a36Sopenharmony_ci{ 119062306a36Sopenharmony_ci pr_debug("%s(0x%p)\n", __func__, ptr); 119162306a36Sopenharmony_ci 119262306a36Sopenharmony_ci if (kmemleak_enabled && ptr && !IS_ERR(ptr)) 119362306a36Sopenharmony_ci object_no_scan((unsigned long)ptr); 119462306a36Sopenharmony_ci} 119562306a36Sopenharmony_ciEXPORT_SYMBOL(kmemleak_no_scan); 119662306a36Sopenharmony_ci 119762306a36Sopenharmony_ci/** 119862306a36Sopenharmony_ci * kmemleak_alloc_phys - similar to kmemleak_alloc but taking a physical 119962306a36Sopenharmony_ci * address argument 120062306a36Sopenharmony_ci * @phys: physical address of the object 120162306a36Sopenharmony_ci * @size: size of the object 120262306a36Sopenharmony_ci * @gfp: kmalloc() flags used for kmemleak internal memory allocations 120362306a36Sopenharmony_ci */ 120462306a36Sopenharmony_civoid __ref kmemleak_alloc_phys(phys_addr_t phys, size_t size, gfp_t gfp) 120562306a36Sopenharmony_ci{ 120662306a36Sopenharmony_ci pr_debug("%s(0x%pa, %zu)\n", __func__, &phys, size); 120762306a36Sopenharmony_ci 120862306a36Sopenharmony_ci if (kmemleak_enabled) 120962306a36Sopenharmony_ci /* 121062306a36Sopenharmony_ci * Create object with OBJECT_PHYS flag and 121162306a36Sopenharmony_ci * assume min_count 0. 121262306a36Sopenharmony_ci */ 121362306a36Sopenharmony_ci create_object_phys((unsigned long)phys, size, 0, gfp); 121462306a36Sopenharmony_ci} 121562306a36Sopenharmony_ciEXPORT_SYMBOL(kmemleak_alloc_phys); 121662306a36Sopenharmony_ci 121762306a36Sopenharmony_ci/** 121862306a36Sopenharmony_ci * kmemleak_free_part_phys - similar to kmemleak_free_part but taking a 121962306a36Sopenharmony_ci * physical address argument 122062306a36Sopenharmony_ci * @phys: physical address if the beginning or inside an object. This 122162306a36Sopenharmony_ci * also represents the start of the range to be freed 122262306a36Sopenharmony_ci * @size: size to be unregistered 122362306a36Sopenharmony_ci */ 122462306a36Sopenharmony_civoid __ref kmemleak_free_part_phys(phys_addr_t phys, size_t size) 122562306a36Sopenharmony_ci{ 122662306a36Sopenharmony_ci pr_debug("%s(0x%pa)\n", __func__, &phys); 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_ci if (kmemleak_enabled) 122962306a36Sopenharmony_ci delete_object_part((unsigned long)phys, size, true); 123062306a36Sopenharmony_ci} 123162306a36Sopenharmony_ciEXPORT_SYMBOL(kmemleak_free_part_phys); 123262306a36Sopenharmony_ci 123362306a36Sopenharmony_ci/** 123462306a36Sopenharmony_ci * kmemleak_ignore_phys - similar to kmemleak_ignore but taking a physical 123562306a36Sopenharmony_ci * address argument 123662306a36Sopenharmony_ci * @phys: physical address of the object 123762306a36Sopenharmony_ci */ 123862306a36Sopenharmony_civoid __ref kmemleak_ignore_phys(phys_addr_t phys) 123962306a36Sopenharmony_ci{ 124062306a36Sopenharmony_ci pr_debug("%s(0x%pa)\n", __func__, &phys); 124162306a36Sopenharmony_ci 124262306a36Sopenharmony_ci if (kmemleak_enabled) 124362306a36Sopenharmony_ci make_black_object((unsigned long)phys, true); 124462306a36Sopenharmony_ci} 124562306a36Sopenharmony_ciEXPORT_SYMBOL(kmemleak_ignore_phys); 124662306a36Sopenharmony_ci 124762306a36Sopenharmony_ci/* 124862306a36Sopenharmony_ci * Update an object's checksum and return true if it was modified. 124962306a36Sopenharmony_ci */ 125062306a36Sopenharmony_cistatic bool update_checksum(struct kmemleak_object *object) 125162306a36Sopenharmony_ci{ 125262306a36Sopenharmony_ci u32 old_csum = object->checksum; 125362306a36Sopenharmony_ci 125462306a36Sopenharmony_ci if (WARN_ON_ONCE(object->flags & OBJECT_PHYS)) 125562306a36Sopenharmony_ci return false; 125662306a36Sopenharmony_ci 125762306a36Sopenharmony_ci kasan_disable_current(); 125862306a36Sopenharmony_ci kcsan_disable_current(); 125962306a36Sopenharmony_ci object->checksum = crc32(0, kasan_reset_tag((void *)object->pointer), object->size); 126062306a36Sopenharmony_ci kasan_enable_current(); 126162306a36Sopenharmony_ci kcsan_enable_current(); 126262306a36Sopenharmony_ci 126362306a36Sopenharmony_ci return object->checksum != old_csum; 126462306a36Sopenharmony_ci} 126562306a36Sopenharmony_ci 126662306a36Sopenharmony_ci/* 126762306a36Sopenharmony_ci * Update an object's references. object->lock must be held by the caller. 126862306a36Sopenharmony_ci */ 126962306a36Sopenharmony_cistatic void update_refs(struct kmemleak_object *object) 127062306a36Sopenharmony_ci{ 127162306a36Sopenharmony_ci if (!color_white(object)) { 127262306a36Sopenharmony_ci /* non-orphan, ignored or new */ 127362306a36Sopenharmony_ci return; 127462306a36Sopenharmony_ci } 127562306a36Sopenharmony_ci 127662306a36Sopenharmony_ci /* 127762306a36Sopenharmony_ci * Increase the object's reference count (number of pointers to the 127862306a36Sopenharmony_ci * memory block). If this count reaches the required minimum, the 127962306a36Sopenharmony_ci * object's color will become gray and it will be added to the 128062306a36Sopenharmony_ci * gray_list. 128162306a36Sopenharmony_ci */ 128262306a36Sopenharmony_ci object->count++; 128362306a36Sopenharmony_ci if (color_gray(object)) { 128462306a36Sopenharmony_ci /* put_object() called when removing from gray_list */ 128562306a36Sopenharmony_ci WARN_ON(!get_object(object)); 128662306a36Sopenharmony_ci list_add_tail(&object->gray_list, &gray_list); 128762306a36Sopenharmony_ci } 128862306a36Sopenharmony_ci} 128962306a36Sopenharmony_ci 129062306a36Sopenharmony_ci/* 129162306a36Sopenharmony_ci * Memory scanning is a long process and it needs to be interruptible. This 129262306a36Sopenharmony_ci * function checks whether such interrupt condition occurred. 129362306a36Sopenharmony_ci */ 129462306a36Sopenharmony_cistatic int scan_should_stop(void) 129562306a36Sopenharmony_ci{ 129662306a36Sopenharmony_ci if (!kmemleak_enabled) 129762306a36Sopenharmony_ci return 1; 129862306a36Sopenharmony_ci 129962306a36Sopenharmony_ci /* 130062306a36Sopenharmony_ci * This function may be called from either process or kthread context, 130162306a36Sopenharmony_ci * hence the need to check for both stop conditions. 130262306a36Sopenharmony_ci */ 130362306a36Sopenharmony_ci if (current->mm) 130462306a36Sopenharmony_ci return signal_pending(current); 130562306a36Sopenharmony_ci else 130662306a36Sopenharmony_ci return kthread_should_stop(); 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_ci return 0; 130962306a36Sopenharmony_ci} 131062306a36Sopenharmony_ci 131162306a36Sopenharmony_ci/* 131262306a36Sopenharmony_ci * Scan a memory block (exclusive range) for valid pointers and add those 131362306a36Sopenharmony_ci * found to the gray list. 131462306a36Sopenharmony_ci */ 131562306a36Sopenharmony_cistatic void scan_block(void *_start, void *_end, 131662306a36Sopenharmony_ci struct kmemleak_object *scanned) 131762306a36Sopenharmony_ci{ 131862306a36Sopenharmony_ci unsigned long *ptr; 131962306a36Sopenharmony_ci unsigned long *start = PTR_ALIGN(_start, BYTES_PER_POINTER); 132062306a36Sopenharmony_ci unsigned long *end = _end - (BYTES_PER_POINTER - 1); 132162306a36Sopenharmony_ci unsigned long flags; 132262306a36Sopenharmony_ci unsigned long untagged_ptr; 132362306a36Sopenharmony_ci 132462306a36Sopenharmony_ci raw_spin_lock_irqsave(&kmemleak_lock, flags); 132562306a36Sopenharmony_ci for (ptr = start; ptr < end; ptr++) { 132662306a36Sopenharmony_ci struct kmemleak_object *object; 132762306a36Sopenharmony_ci unsigned long pointer; 132862306a36Sopenharmony_ci unsigned long excess_ref; 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci if (scan_should_stop()) 133162306a36Sopenharmony_ci break; 133262306a36Sopenharmony_ci 133362306a36Sopenharmony_ci kasan_disable_current(); 133462306a36Sopenharmony_ci pointer = *(unsigned long *)kasan_reset_tag((void *)ptr); 133562306a36Sopenharmony_ci kasan_enable_current(); 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_ci untagged_ptr = (unsigned long)kasan_reset_tag((void *)pointer); 133862306a36Sopenharmony_ci if (untagged_ptr < min_addr || untagged_ptr >= max_addr) 133962306a36Sopenharmony_ci continue; 134062306a36Sopenharmony_ci 134162306a36Sopenharmony_ci /* 134262306a36Sopenharmony_ci * No need for get_object() here since we hold kmemleak_lock. 134362306a36Sopenharmony_ci * object->use_count cannot be dropped to 0 while the object 134462306a36Sopenharmony_ci * is still present in object_tree_root and object_list 134562306a36Sopenharmony_ci * (with updates protected by kmemleak_lock). 134662306a36Sopenharmony_ci */ 134762306a36Sopenharmony_ci object = lookup_object(pointer, 1); 134862306a36Sopenharmony_ci if (!object) 134962306a36Sopenharmony_ci continue; 135062306a36Sopenharmony_ci if (object == scanned) 135162306a36Sopenharmony_ci /* self referenced, ignore */ 135262306a36Sopenharmony_ci continue; 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci /* 135562306a36Sopenharmony_ci * Avoid the lockdep recursive warning on object->lock being 135662306a36Sopenharmony_ci * previously acquired in scan_object(). These locks are 135762306a36Sopenharmony_ci * enclosed by scan_mutex. 135862306a36Sopenharmony_ci */ 135962306a36Sopenharmony_ci raw_spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); 136062306a36Sopenharmony_ci /* only pass surplus references (object already gray) */ 136162306a36Sopenharmony_ci if (color_gray(object)) { 136262306a36Sopenharmony_ci excess_ref = object->excess_ref; 136362306a36Sopenharmony_ci /* no need for update_refs() if object already gray */ 136462306a36Sopenharmony_ci } else { 136562306a36Sopenharmony_ci excess_ref = 0; 136662306a36Sopenharmony_ci update_refs(object); 136762306a36Sopenharmony_ci } 136862306a36Sopenharmony_ci raw_spin_unlock(&object->lock); 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci if (excess_ref) { 137162306a36Sopenharmony_ci object = lookup_object(excess_ref, 0); 137262306a36Sopenharmony_ci if (!object) 137362306a36Sopenharmony_ci continue; 137462306a36Sopenharmony_ci if (object == scanned) 137562306a36Sopenharmony_ci /* circular reference, ignore */ 137662306a36Sopenharmony_ci continue; 137762306a36Sopenharmony_ci raw_spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); 137862306a36Sopenharmony_ci update_refs(object); 137962306a36Sopenharmony_ci raw_spin_unlock(&object->lock); 138062306a36Sopenharmony_ci } 138162306a36Sopenharmony_ci } 138262306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&kmemleak_lock, flags); 138362306a36Sopenharmony_ci} 138462306a36Sopenharmony_ci 138562306a36Sopenharmony_ci/* 138662306a36Sopenharmony_ci * Scan a large memory block in MAX_SCAN_SIZE chunks to reduce the latency. 138762306a36Sopenharmony_ci */ 138862306a36Sopenharmony_ci#ifdef CONFIG_SMP 138962306a36Sopenharmony_cistatic void scan_large_block(void *start, void *end) 139062306a36Sopenharmony_ci{ 139162306a36Sopenharmony_ci void *next; 139262306a36Sopenharmony_ci 139362306a36Sopenharmony_ci while (start < end) { 139462306a36Sopenharmony_ci next = min(start + MAX_SCAN_SIZE, end); 139562306a36Sopenharmony_ci scan_block(start, next, NULL); 139662306a36Sopenharmony_ci start = next; 139762306a36Sopenharmony_ci cond_resched(); 139862306a36Sopenharmony_ci } 139962306a36Sopenharmony_ci} 140062306a36Sopenharmony_ci#endif 140162306a36Sopenharmony_ci 140262306a36Sopenharmony_ci/* 140362306a36Sopenharmony_ci * Scan a memory block corresponding to a kmemleak_object. A condition is 140462306a36Sopenharmony_ci * that object->use_count >= 1. 140562306a36Sopenharmony_ci */ 140662306a36Sopenharmony_cistatic void scan_object(struct kmemleak_object *object) 140762306a36Sopenharmony_ci{ 140862306a36Sopenharmony_ci struct kmemleak_scan_area *area; 140962306a36Sopenharmony_ci unsigned long flags; 141062306a36Sopenharmony_ci void *obj_ptr; 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci /* 141362306a36Sopenharmony_ci * Once the object->lock is acquired, the corresponding memory block 141462306a36Sopenharmony_ci * cannot be freed (the same lock is acquired in delete_object). 141562306a36Sopenharmony_ci */ 141662306a36Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 141762306a36Sopenharmony_ci if (object->flags & OBJECT_NO_SCAN) 141862306a36Sopenharmony_ci goto out; 141962306a36Sopenharmony_ci if (!(object->flags & OBJECT_ALLOCATED)) 142062306a36Sopenharmony_ci /* already freed object */ 142162306a36Sopenharmony_ci goto out; 142262306a36Sopenharmony_ci 142362306a36Sopenharmony_ci obj_ptr = object->flags & OBJECT_PHYS ? 142462306a36Sopenharmony_ci __va((phys_addr_t)object->pointer) : 142562306a36Sopenharmony_ci (void *)object->pointer; 142662306a36Sopenharmony_ci 142762306a36Sopenharmony_ci if (hlist_empty(&object->area_list) || 142862306a36Sopenharmony_ci object->flags & OBJECT_FULL_SCAN) { 142962306a36Sopenharmony_ci void *start = obj_ptr; 143062306a36Sopenharmony_ci void *end = obj_ptr + object->size; 143162306a36Sopenharmony_ci void *next; 143262306a36Sopenharmony_ci 143362306a36Sopenharmony_ci do { 143462306a36Sopenharmony_ci next = min(start + MAX_SCAN_SIZE, end); 143562306a36Sopenharmony_ci scan_block(start, next, object); 143662306a36Sopenharmony_ci 143762306a36Sopenharmony_ci start = next; 143862306a36Sopenharmony_ci if (start >= end) 143962306a36Sopenharmony_ci break; 144062306a36Sopenharmony_ci 144162306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 144262306a36Sopenharmony_ci cond_resched(); 144362306a36Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 144462306a36Sopenharmony_ci } while (object->flags & OBJECT_ALLOCATED); 144562306a36Sopenharmony_ci } else 144662306a36Sopenharmony_ci hlist_for_each_entry(area, &object->area_list, node) 144762306a36Sopenharmony_ci scan_block((void *)area->start, 144862306a36Sopenharmony_ci (void *)(area->start + area->size), 144962306a36Sopenharmony_ci object); 145062306a36Sopenharmony_ciout: 145162306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 145262306a36Sopenharmony_ci} 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_ci/* 145562306a36Sopenharmony_ci * Scan the objects already referenced (gray objects). More objects will be 145662306a36Sopenharmony_ci * referenced and, if there are no memory leaks, all the objects are scanned. 145762306a36Sopenharmony_ci */ 145862306a36Sopenharmony_cistatic void scan_gray_list(void) 145962306a36Sopenharmony_ci{ 146062306a36Sopenharmony_ci struct kmemleak_object *object, *tmp; 146162306a36Sopenharmony_ci 146262306a36Sopenharmony_ci /* 146362306a36Sopenharmony_ci * The list traversal is safe for both tail additions and removals 146462306a36Sopenharmony_ci * from inside the loop. The kmemleak objects cannot be freed from 146562306a36Sopenharmony_ci * outside the loop because their use_count was incremented. 146662306a36Sopenharmony_ci */ 146762306a36Sopenharmony_ci object = list_entry(gray_list.next, typeof(*object), gray_list); 146862306a36Sopenharmony_ci while (&object->gray_list != &gray_list) { 146962306a36Sopenharmony_ci cond_resched(); 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci /* may add new objects to the list */ 147262306a36Sopenharmony_ci if (!scan_should_stop()) 147362306a36Sopenharmony_ci scan_object(object); 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci tmp = list_entry(object->gray_list.next, typeof(*object), 147662306a36Sopenharmony_ci gray_list); 147762306a36Sopenharmony_ci 147862306a36Sopenharmony_ci /* remove the object from the list and release it */ 147962306a36Sopenharmony_ci list_del(&object->gray_list); 148062306a36Sopenharmony_ci put_object(object); 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci object = tmp; 148362306a36Sopenharmony_ci } 148462306a36Sopenharmony_ci WARN_ON(!list_empty(&gray_list)); 148562306a36Sopenharmony_ci} 148662306a36Sopenharmony_ci 148762306a36Sopenharmony_ci/* 148862306a36Sopenharmony_ci * Conditionally call resched() in an object iteration loop while making sure 148962306a36Sopenharmony_ci * that the given object won't go away without RCU read lock by performing a 149062306a36Sopenharmony_ci * get_object() if necessaary. 149162306a36Sopenharmony_ci */ 149262306a36Sopenharmony_cistatic void kmemleak_cond_resched(struct kmemleak_object *object) 149362306a36Sopenharmony_ci{ 149462306a36Sopenharmony_ci if (!get_object(object)) 149562306a36Sopenharmony_ci return; /* Try next object */ 149662306a36Sopenharmony_ci 149762306a36Sopenharmony_ci raw_spin_lock_irq(&kmemleak_lock); 149862306a36Sopenharmony_ci if (object->del_state & DELSTATE_REMOVED) 149962306a36Sopenharmony_ci goto unlock_put; /* Object removed */ 150062306a36Sopenharmony_ci object->del_state |= DELSTATE_NO_DELETE; 150162306a36Sopenharmony_ci raw_spin_unlock_irq(&kmemleak_lock); 150262306a36Sopenharmony_ci 150362306a36Sopenharmony_ci rcu_read_unlock(); 150462306a36Sopenharmony_ci cond_resched(); 150562306a36Sopenharmony_ci rcu_read_lock(); 150662306a36Sopenharmony_ci 150762306a36Sopenharmony_ci raw_spin_lock_irq(&kmemleak_lock); 150862306a36Sopenharmony_ci if (object->del_state & DELSTATE_REMOVED) 150962306a36Sopenharmony_ci list_del_rcu(&object->object_list); 151062306a36Sopenharmony_ci object->del_state &= ~DELSTATE_NO_DELETE; 151162306a36Sopenharmony_ciunlock_put: 151262306a36Sopenharmony_ci raw_spin_unlock_irq(&kmemleak_lock); 151362306a36Sopenharmony_ci put_object(object); 151462306a36Sopenharmony_ci} 151562306a36Sopenharmony_ci 151662306a36Sopenharmony_ci/* 151762306a36Sopenharmony_ci * Scan data sections and all the referenced memory blocks allocated via the 151862306a36Sopenharmony_ci * kernel's standard allocators. This function must be called with the 151962306a36Sopenharmony_ci * scan_mutex held. 152062306a36Sopenharmony_ci */ 152162306a36Sopenharmony_cistatic void kmemleak_scan(void) 152262306a36Sopenharmony_ci{ 152362306a36Sopenharmony_ci struct kmemleak_object *object; 152462306a36Sopenharmony_ci struct zone *zone; 152562306a36Sopenharmony_ci int __maybe_unused i; 152662306a36Sopenharmony_ci int new_leaks = 0; 152762306a36Sopenharmony_ci 152862306a36Sopenharmony_ci jiffies_last_scan = jiffies; 152962306a36Sopenharmony_ci 153062306a36Sopenharmony_ci /* prepare the kmemleak_object's */ 153162306a36Sopenharmony_ci rcu_read_lock(); 153262306a36Sopenharmony_ci list_for_each_entry_rcu(object, &object_list, object_list) { 153362306a36Sopenharmony_ci raw_spin_lock_irq(&object->lock); 153462306a36Sopenharmony_ci#ifdef DEBUG 153562306a36Sopenharmony_ci /* 153662306a36Sopenharmony_ci * With a few exceptions there should be a maximum of 153762306a36Sopenharmony_ci * 1 reference to any object at this point. 153862306a36Sopenharmony_ci */ 153962306a36Sopenharmony_ci if (atomic_read(&object->use_count) > 1) { 154062306a36Sopenharmony_ci pr_debug("object->use_count = %d\n", 154162306a36Sopenharmony_ci atomic_read(&object->use_count)); 154262306a36Sopenharmony_ci dump_object_info(object); 154362306a36Sopenharmony_ci } 154462306a36Sopenharmony_ci#endif 154562306a36Sopenharmony_ci 154662306a36Sopenharmony_ci /* ignore objects outside lowmem (paint them black) */ 154762306a36Sopenharmony_ci if ((object->flags & OBJECT_PHYS) && 154862306a36Sopenharmony_ci !(object->flags & OBJECT_NO_SCAN)) { 154962306a36Sopenharmony_ci unsigned long phys = object->pointer; 155062306a36Sopenharmony_ci 155162306a36Sopenharmony_ci if (PHYS_PFN(phys) < min_low_pfn || 155262306a36Sopenharmony_ci PHYS_PFN(phys + object->size) >= max_low_pfn) 155362306a36Sopenharmony_ci __paint_it(object, KMEMLEAK_BLACK); 155462306a36Sopenharmony_ci } 155562306a36Sopenharmony_ci 155662306a36Sopenharmony_ci /* reset the reference count (whiten the object) */ 155762306a36Sopenharmony_ci object->count = 0; 155862306a36Sopenharmony_ci if (color_gray(object) && get_object(object)) 155962306a36Sopenharmony_ci list_add_tail(&object->gray_list, &gray_list); 156062306a36Sopenharmony_ci 156162306a36Sopenharmony_ci raw_spin_unlock_irq(&object->lock); 156262306a36Sopenharmony_ci 156362306a36Sopenharmony_ci if (need_resched()) 156462306a36Sopenharmony_ci kmemleak_cond_resched(object); 156562306a36Sopenharmony_ci } 156662306a36Sopenharmony_ci rcu_read_unlock(); 156762306a36Sopenharmony_ci 156862306a36Sopenharmony_ci#ifdef CONFIG_SMP 156962306a36Sopenharmony_ci /* per-cpu sections scanning */ 157062306a36Sopenharmony_ci for_each_possible_cpu(i) 157162306a36Sopenharmony_ci scan_large_block(__per_cpu_start + per_cpu_offset(i), 157262306a36Sopenharmony_ci __per_cpu_end + per_cpu_offset(i)); 157362306a36Sopenharmony_ci#endif 157462306a36Sopenharmony_ci 157562306a36Sopenharmony_ci /* 157662306a36Sopenharmony_ci * Struct page scanning for each node. 157762306a36Sopenharmony_ci */ 157862306a36Sopenharmony_ci get_online_mems(); 157962306a36Sopenharmony_ci for_each_populated_zone(zone) { 158062306a36Sopenharmony_ci unsigned long start_pfn = zone->zone_start_pfn; 158162306a36Sopenharmony_ci unsigned long end_pfn = zone_end_pfn(zone); 158262306a36Sopenharmony_ci unsigned long pfn; 158362306a36Sopenharmony_ci 158462306a36Sopenharmony_ci for (pfn = start_pfn; pfn < end_pfn; pfn++) { 158562306a36Sopenharmony_ci struct page *page = pfn_to_online_page(pfn); 158662306a36Sopenharmony_ci 158762306a36Sopenharmony_ci if (!(pfn & 63)) 158862306a36Sopenharmony_ci cond_resched(); 158962306a36Sopenharmony_ci 159062306a36Sopenharmony_ci if (!page) 159162306a36Sopenharmony_ci continue; 159262306a36Sopenharmony_ci 159362306a36Sopenharmony_ci /* only scan pages belonging to this zone */ 159462306a36Sopenharmony_ci if (page_zone(page) != zone) 159562306a36Sopenharmony_ci continue; 159662306a36Sopenharmony_ci /* only scan if page is in use */ 159762306a36Sopenharmony_ci if (page_count(page) == 0) 159862306a36Sopenharmony_ci continue; 159962306a36Sopenharmony_ci scan_block(page, page + 1, NULL); 160062306a36Sopenharmony_ci } 160162306a36Sopenharmony_ci } 160262306a36Sopenharmony_ci put_online_mems(); 160362306a36Sopenharmony_ci 160462306a36Sopenharmony_ci /* 160562306a36Sopenharmony_ci * Scanning the task stacks (may introduce false negatives). 160662306a36Sopenharmony_ci */ 160762306a36Sopenharmony_ci if (kmemleak_stack_scan) { 160862306a36Sopenharmony_ci struct task_struct *p, *g; 160962306a36Sopenharmony_ci 161062306a36Sopenharmony_ci rcu_read_lock(); 161162306a36Sopenharmony_ci for_each_process_thread(g, p) { 161262306a36Sopenharmony_ci void *stack = try_get_task_stack(p); 161362306a36Sopenharmony_ci if (stack) { 161462306a36Sopenharmony_ci scan_block(stack, stack + THREAD_SIZE, NULL); 161562306a36Sopenharmony_ci put_task_stack(p); 161662306a36Sopenharmony_ci } 161762306a36Sopenharmony_ci } 161862306a36Sopenharmony_ci rcu_read_unlock(); 161962306a36Sopenharmony_ci } 162062306a36Sopenharmony_ci 162162306a36Sopenharmony_ci /* 162262306a36Sopenharmony_ci * Scan the objects already referenced from the sections scanned 162362306a36Sopenharmony_ci * above. 162462306a36Sopenharmony_ci */ 162562306a36Sopenharmony_ci scan_gray_list(); 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci /* 162862306a36Sopenharmony_ci * Check for new or unreferenced objects modified since the previous 162962306a36Sopenharmony_ci * scan and color them gray until the next scan. 163062306a36Sopenharmony_ci */ 163162306a36Sopenharmony_ci rcu_read_lock(); 163262306a36Sopenharmony_ci list_for_each_entry_rcu(object, &object_list, object_list) { 163362306a36Sopenharmony_ci if (need_resched()) 163462306a36Sopenharmony_ci kmemleak_cond_resched(object); 163562306a36Sopenharmony_ci 163662306a36Sopenharmony_ci /* 163762306a36Sopenharmony_ci * This is racy but we can save the overhead of lock/unlock 163862306a36Sopenharmony_ci * calls. The missed objects, if any, should be caught in 163962306a36Sopenharmony_ci * the next scan. 164062306a36Sopenharmony_ci */ 164162306a36Sopenharmony_ci if (!color_white(object)) 164262306a36Sopenharmony_ci continue; 164362306a36Sopenharmony_ci raw_spin_lock_irq(&object->lock); 164462306a36Sopenharmony_ci if (color_white(object) && (object->flags & OBJECT_ALLOCATED) 164562306a36Sopenharmony_ci && update_checksum(object) && get_object(object)) { 164662306a36Sopenharmony_ci /* color it gray temporarily */ 164762306a36Sopenharmony_ci object->count = object->min_count; 164862306a36Sopenharmony_ci list_add_tail(&object->gray_list, &gray_list); 164962306a36Sopenharmony_ci } 165062306a36Sopenharmony_ci raw_spin_unlock_irq(&object->lock); 165162306a36Sopenharmony_ci } 165262306a36Sopenharmony_ci rcu_read_unlock(); 165362306a36Sopenharmony_ci 165462306a36Sopenharmony_ci /* 165562306a36Sopenharmony_ci * Re-scan the gray list for modified unreferenced objects. 165662306a36Sopenharmony_ci */ 165762306a36Sopenharmony_ci scan_gray_list(); 165862306a36Sopenharmony_ci 165962306a36Sopenharmony_ci /* 166062306a36Sopenharmony_ci * If scanning was stopped do not report any new unreferenced objects. 166162306a36Sopenharmony_ci */ 166262306a36Sopenharmony_ci if (scan_should_stop()) 166362306a36Sopenharmony_ci return; 166462306a36Sopenharmony_ci 166562306a36Sopenharmony_ci /* 166662306a36Sopenharmony_ci * Scanning result reporting. 166762306a36Sopenharmony_ci */ 166862306a36Sopenharmony_ci rcu_read_lock(); 166962306a36Sopenharmony_ci list_for_each_entry_rcu(object, &object_list, object_list) { 167062306a36Sopenharmony_ci if (need_resched()) 167162306a36Sopenharmony_ci kmemleak_cond_resched(object); 167262306a36Sopenharmony_ci 167362306a36Sopenharmony_ci /* 167462306a36Sopenharmony_ci * This is racy but we can save the overhead of lock/unlock 167562306a36Sopenharmony_ci * calls. The missed objects, if any, should be caught in 167662306a36Sopenharmony_ci * the next scan. 167762306a36Sopenharmony_ci */ 167862306a36Sopenharmony_ci if (!color_white(object)) 167962306a36Sopenharmony_ci continue; 168062306a36Sopenharmony_ci raw_spin_lock_irq(&object->lock); 168162306a36Sopenharmony_ci if (unreferenced_object(object) && 168262306a36Sopenharmony_ci !(object->flags & OBJECT_REPORTED)) { 168362306a36Sopenharmony_ci object->flags |= OBJECT_REPORTED; 168462306a36Sopenharmony_ci 168562306a36Sopenharmony_ci if (kmemleak_verbose) 168662306a36Sopenharmony_ci print_unreferenced(NULL, object); 168762306a36Sopenharmony_ci 168862306a36Sopenharmony_ci new_leaks++; 168962306a36Sopenharmony_ci } 169062306a36Sopenharmony_ci raw_spin_unlock_irq(&object->lock); 169162306a36Sopenharmony_ci } 169262306a36Sopenharmony_ci rcu_read_unlock(); 169362306a36Sopenharmony_ci 169462306a36Sopenharmony_ci if (new_leaks) { 169562306a36Sopenharmony_ci kmemleak_found_leaks = true; 169662306a36Sopenharmony_ci 169762306a36Sopenharmony_ci pr_info("%d new suspected memory leaks (see /sys/kernel/debug/kmemleak)\n", 169862306a36Sopenharmony_ci new_leaks); 169962306a36Sopenharmony_ci } 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_ci} 170262306a36Sopenharmony_ci 170362306a36Sopenharmony_ci/* 170462306a36Sopenharmony_ci * Thread function performing automatic memory scanning. Unreferenced objects 170562306a36Sopenharmony_ci * at the end of a memory scan are reported but only the first time. 170662306a36Sopenharmony_ci */ 170762306a36Sopenharmony_cistatic int kmemleak_scan_thread(void *arg) 170862306a36Sopenharmony_ci{ 170962306a36Sopenharmony_ci static int first_run = IS_ENABLED(CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN); 171062306a36Sopenharmony_ci 171162306a36Sopenharmony_ci pr_info("Automatic memory scanning thread started\n"); 171262306a36Sopenharmony_ci set_user_nice(current, 10); 171362306a36Sopenharmony_ci 171462306a36Sopenharmony_ci /* 171562306a36Sopenharmony_ci * Wait before the first scan to allow the system to fully initialize. 171662306a36Sopenharmony_ci */ 171762306a36Sopenharmony_ci if (first_run) { 171862306a36Sopenharmony_ci signed long timeout = msecs_to_jiffies(SECS_FIRST_SCAN * 1000); 171962306a36Sopenharmony_ci first_run = 0; 172062306a36Sopenharmony_ci while (timeout && !kthread_should_stop()) 172162306a36Sopenharmony_ci timeout = schedule_timeout_interruptible(timeout); 172262306a36Sopenharmony_ci } 172362306a36Sopenharmony_ci 172462306a36Sopenharmony_ci while (!kthread_should_stop()) { 172562306a36Sopenharmony_ci signed long timeout = READ_ONCE(jiffies_scan_wait); 172662306a36Sopenharmony_ci 172762306a36Sopenharmony_ci mutex_lock(&scan_mutex); 172862306a36Sopenharmony_ci kmemleak_scan(); 172962306a36Sopenharmony_ci mutex_unlock(&scan_mutex); 173062306a36Sopenharmony_ci 173162306a36Sopenharmony_ci /* wait before the next scan */ 173262306a36Sopenharmony_ci while (timeout && !kthread_should_stop()) 173362306a36Sopenharmony_ci timeout = schedule_timeout_interruptible(timeout); 173462306a36Sopenharmony_ci } 173562306a36Sopenharmony_ci 173662306a36Sopenharmony_ci pr_info("Automatic memory scanning thread ended\n"); 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci return 0; 173962306a36Sopenharmony_ci} 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci/* 174262306a36Sopenharmony_ci * Start the automatic memory scanning thread. This function must be called 174362306a36Sopenharmony_ci * with the scan_mutex held. 174462306a36Sopenharmony_ci */ 174562306a36Sopenharmony_cistatic void start_scan_thread(void) 174662306a36Sopenharmony_ci{ 174762306a36Sopenharmony_ci if (scan_thread) 174862306a36Sopenharmony_ci return; 174962306a36Sopenharmony_ci scan_thread = kthread_run(kmemleak_scan_thread, NULL, "kmemleak"); 175062306a36Sopenharmony_ci if (IS_ERR(scan_thread)) { 175162306a36Sopenharmony_ci pr_warn("Failed to create the scan thread\n"); 175262306a36Sopenharmony_ci scan_thread = NULL; 175362306a36Sopenharmony_ci } 175462306a36Sopenharmony_ci} 175562306a36Sopenharmony_ci 175662306a36Sopenharmony_ci/* 175762306a36Sopenharmony_ci * Stop the automatic memory scanning thread. 175862306a36Sopenharmony_ci */ 175962306a36Sopenharmony_cistatic void stop_scan_thread(void) 176062306a36Sopenharmony_ci{ 176162306a36Sopenharmony_ci if (scan_thread) { 176262306a36Sopenharmony_ci kthread_stop(scan_thread); 176362306a36Sopenharmony_ci scan_thread = NULL; 176462306a36Sopenharmony_ci } 176562306a36Sopenharmony_ci} 176662306a36Sopenharmony_ci 176762306a36Sopenharmony_ci/* 176862306a36Sopenharmony_ci * Iterate over the object_list and return the first valid object at or after 176962306a36Sopenharmony_ci * the required position with its use_count incremented. The function triggers 177062306a36Sopenharmony_ci * a memory scanning when the pos argument points to the first position. 177162306a36Sopenharmony_ci */ 177262306a36Sopenharmony_cistatic void *kmemleak_seq_start(struct seq_file *seq, loff_t *pos) 177362306a36Sopenharmony_ci{ 177462306a36Sopenharmony_ci struct kmemleak_object *object; 177562306a36Sopenharmony_ci loff_t n = *pos; 177662306a36Sopenharmony_ci int err; 177762306a36Sopenharmony_ci 177862306a36Sopenharmony_ci err = mutex_lock_interruptible(&scan_mutex); 177962306a36Sopenharmony_ci if (err < 0) 178062306a36Sopenharmony_ci return ERR_PTR(err); 178162306a36Sopenharmony_ci 178262306a36Sopenharmony_ci rcu_read_lock(); 178362306a36Sopenharmony_ci list_for_each_entry_rcu(object, &object_list, object_list) { 178462306a36Sopenharmony_ci if (n-- > 0) 178562306a36Sopenharmony_ci continue; 178662306a36Sopenharmony_ci if (get_object(object)) 178762306a36Sopenharmony_ci goto out; 178862306a36Sopenharmony_ci } 178962306a36Sopenharmony_ci object = NULL; 179062306a36Sopenharmony_ciout: 179162306a36Sopenharmony_ci return object; 179262306a36Sopenharmony_ci} 179362306a36Sopenharmony_ci 179462306a36Sopenharmony_ci/* 179562306a36Sopenharmony_ci * Return the next object in the object_list. The function decrements the 179662306a36Sopenharmony_ci * use_count of the previous object and increases that of the next one. 179762306a36Sopenharmony_ci */ 179862306a36Sopenharmony_cistatic void *kmemleak_seq_next(struct seq_file *seq, void *v, loff_t *pos) 179962306a36Sopenharmony_ci{ 180062306a36Sopenharmony_ci struct kmemleak_object *prev_obj = v; 180162306a36Sopenharmony_ci struct kmemleak_object *next_obj = NULL; 180262306a36Sopenharmony_ci struct kmemleak_object *obj = prev_obj; 180362306a36Sopenharmony_ci 180462306a36Sopenharmony_ci ++(*pos); 180562306a36Sopenharmony_ci 180662306a36Sopenharmony_ci list_for_each_entry_continue_rcu(obj, &object_list, object_list) { 180762306a36Sopenharmony_ci if (get_object(obj)) { 180862306a36Sopenharmony_ci next_obj = obj; 180962306a36Sopenharmony_ci break; 181062306a36Sopenharmony_ci } 181162306a36Sopenharmony_ci } 181262306a36Sopenharmony_ci 181362306a36Sopenharmony_ci put_object(prev_obj); 181462306a36Sopenharmony_ci return next_obj; 181562306a36Sopenharmony_ci} 181662306a36Sopenharmony_ci 181762306a36Sopenharmony_ci/* 181862306a36Sopenharmony_ci * Decrement the use_count of the last object required, if any. 181962306a36Sopenharmony_ci */ 182062306a36Sopenharmony_cistatic void kmemleak_seq_stop(struct seq_file *seq, void *v) 182162306a36Sopenharmony_ci{ 182262306a36Sopenharmony_ci if (!IS_ERR(v)) { 182362306a36Sopenharmony_ci /* 182462306a36Sopenharmony_ci * kmemleak_seq_start may return ERR_PTR if the scan_mutex 182562306a36Sopenharmony_ci * waiting was interrupted, so only release it if !IS_ERR. 182662306a36Sopenharmony_ci */ 182762306a36Sopenharmony_ci rcu_read_unlock(); 182862306a36Sopenharmony_ci mutex_unlock(&scan_mutex); 182962306a36Sopenharmony_ci if (v) 183062306a36Sopenharmony_ci put_object(v); 183162306a36Sopenharmony_ci } 183262306a36Sopenharmony_ci} 183362306a36Sopenharmony_ci 183462306a36Sopenharmony_ci/* 183562306a36Sopenharmony_ci * Print the information for an unreferenced object to the seq file. 183662306a36Sopenharmony_ci */ 183762306a36Sopenharmony_cistatic int kmemleak_seq_show(struct seq_file *seq, void *v) 183862306a36Sopenharmony_ci{ 183962306a36Sopenharmony_ci struct kmemleak_object *object = v; 184062306a36Sopenharmony_ci unsigned long flags; 184162306a36Sopenharmony_ci 184262306a36Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 184362306a36Sopenharmony_ci if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) 184462306a36Sopenharmony_ci print_unreferenced(seq, object); 184562306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 184662306a36Sopenharmony_ci return 0; 184762306a36Sopenharmony_ci} 184862306a36Sopenharmony_ci 184962306a36Sopenharmony_cistatic const struct seq_operations kmemleak_seq_ops = { 185062306a36Sopenharmony_ci .start = kmemleak_seq_start, 185162306a36Sopenharmony_ci .next = kmemleak_seq_next, 185262306a36Sopenharmony_ci .stop = kmemleak_seq_stop, 185362306a36Sopenharmony_ci .show = kmemleak_seq_show, 185462306a36Sopenharmony_ci}; 185562306a36Sopenharmony_ci 185662306a36Sopenharmony_cistatic int kmemleak_open(struct inode *inode, struct file *file) 185762306a36Sopenharmony_ci{ 185862306a36Sopenharmony_ci return seq_open(file, &kmemleak_seq_ops); 185962306a36Sopenharmony_ci} 186062306a36Sopenharmony_ci 186162306a36Sopenharmony_cistatic int dump_str_object_info(const char *str) 186262306a36Sopenharmony_ci{ 186362306a36Sopenharmony_ci unsigned long flags; 186462306a36Sopenharmony_ci struct kmemleak_object *object; 186562306a36Sopenharmony_ci unsigned long addr; 186662306a36Sopenharmony_ci 186762306a36Sopenharmony_ci if (kstrtoul(str, 0, &addr)) 186862306a36Sopenharmony_ci return -EINVAL; 186962306a36Sopenharmony_ci object = find_and_get_object(addr, 0); 187062306a36Sopenharmony_ci if (!object) { 187162306a36Sopenharmony_ci pr_info("Unknown object at 0x%08lx\n", addr); 187262306a36Sopenharmony_ci return -EINVAL; 187362306a36Sopenharmony_ci } 187462306a36Sopenharmony_ci 187562306a36Sopenharmony_ci raw_spin_lock_irqsave(&object->lock, flags); 187662306a36Sopenharmony_ci dump_object_info(object); 187762306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&object->lock, flags); 187862306a36Sopenharmony_ci 187962306a36Sopenharmony_ci put_object(object); 188062306a36Sopenharmony_ci return 0; 188162306a36Sopenharmony_ci} 188262306a36Sopenharmony_ci 188362306a36Sopenharmony_ci/* 188462306a36Sopenharmony_ci * We use grey instead of black to ensure we can do future scans on the same 188562306a36Sopenharmony_ci * objects. If we did not do future scans these black objects could 188662306a36Sopenharmony_ci * potentially contain references to newly allocated objects in the future and 188762306a36Sopenharmony_ci * we'd end up with false positives. 188862306a36Sopenharmony_ci */ 188962306a36Sopenharmony_cistatic void kmemleak_clear(void) 189062306a36Sopenharmony_ci{ 189162306a36Sopenharmony_ci struct kmemleak_object *object; 189262306a36Sopenharmony_ci 189362306a36Sopenharmony_ci rcu_read_lock(); 189462306a36Sopenharmony_ci list_for_each_entry_rcu(object, &object_list, object_list) { 189562306a36Sopenharmony_ci raw_spin_lock_irq(&object->lock); 189662306a36Sopenharmony_ci if ((object->flags & OBJECT_REPORTED) && 189762306a36Sopenharmony_ci unreferenced_object(object)) 189862306a36Sopenharmony_ci __paint_it(object, KMEMLEAK_GREY); 189962306a36Sopenharmony_ci raw_spin_unlock_irq(&object->lock); 190062306a36Sopenharmony_ci } 190162306a36Sopenharmony_ci rcu_read_unlock(); 190262306a36Sopenharmony_ci 190362306a36Sopenharmony_ci kmemleak_found_leaks = false; 190462306a36Sopenharmony_ci} 190562306a36Sopenharmony_ci 190662306a36Sopenharmony_cistatic void __kmemleak_do_cleanup(void); 190762306a36Sopenharmony_ci 190862306a36Sopenharmony_ci/* 190962306a36Sopenharmony_ci * File write operation to configure kmemleak at run-time. The following 191062306a36Sopenharmony_ci * commands can be written to the /sys/kernel/debug/kmemleak file: 191162306a36Sopenharmony_ci * off - disable kmemleak (irreversible) 191262306a36Sopenharmony_ci * stack=on - enable the task stacks scanning 191362306a36Sopenharmony_ci * stack=off - disable the tasks stacks scanning 191462306a36Sopenharmony_ci * scan=on - start the automatic memory scanning thread 191562306a36Sopenharmony_ci * scan=off - stop the automatic memory scanning thread 191662306a36Sopenharmony_ci * scan=... - set the automatic memory scanning period in seconds (0 to 191762306a36Sopenharmony_ci * disable it) 191862306a36Sopenharmony_ci * scan - trigger a memory scan 191962306a36Sopenharmony_ci * clear - mark all current reported unreferenced kmemleak objects as 192062306a36Sopenharmony_ci * grey to ignore printing them, or free all kmemleak objects 192162306a36Sopenharmony_ci * if kmemleak has been disabled. 192262306a36Sopenharmony_ci * dump=... - dump information about the object found at the given address 192362306a36Sopenharmony_ci */ 192462306a36Sopenharmony_cistatic ssize_t kmemleak_write(struct file *file, const char __user *user_buf, 192562306a36Sopenharmony_ci size_t size, loff_t *ppos) 192662306a36Sopenharmony_ci{ 192762306a36Sopenharmony_ci char buf[64]; 192862306a36Sopenharmony_ci int buf_size; 192962306a36Sopenharmony_ci int ret; 193062306a36Sopenharmony_ci 193162306a36Sopenharmony_ci buf_size = min(size, (sizeof(buf) - 1)); 193262306a36Sopenharmony_ci if (strncpy_from_user(buf, user_buf, buf_size) < 0) 193362306a36Sopenharmony_ci return -EFAULT; 193462306a36Sopenharmony_ci buf[buf_size] = 0; 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_ci ret = mutex_lock_interruptible(&scan_mutex); 193762306a36Sopenharmony_ci if (ret < 0) 193862306a36Sopenharmony_ci return ret; 193962306a36Sopenharmony_ci 194062306a36Sopenharmony_ci if (strncmp(buf, "clear", 5) == 0) { 194162306a36Sopenharmony_ci if (kmemleak_enabled) 194262306a36Sopenharmony_ci kmemleak_clear(); 194362306a36Sopenharmony_ci else 194462306a36Sopenharmony_ci __kmemleak_do_cleanup(); 194562306a36Sopenharmony_ci goto out; 194662306a36Sopenharmony_ci } 194762306a36Sopenharmony_ci 194862306a36Sopenharmony_ci if (!kmemleak_enabled) { 194962306a36Sopenharmony_ci ret = -EPERM; 195062306a36Sopenharmony_ci goto out; 195162306a36Sopenharmony_ci } 195262306a36Sopenharmony_ci 195362306a36Sopenharmony_ci if (strncmp(buf, "off", 3) == 0) 195462306a36Sopenharmony_ci kmemleak_disable(); 195562306a36Sopenharmony_ci else if (strncmp(buf, "stack=on", 8) == 0) 195662306a36Sopenharmony_ci kmemleak_stack_scan = 1; 195762306a36Sopenharmony_ci else if (strncmp(buf, "stack=off", 9) == 0) 195862306a36Sopenharmony_ci kmemleak_stack_scan = 0; 195962306a36Sopenharmony_ci else if (strncmp(buf, "scan=on", 7) == 0) 196062306a36Sopenharmony_ci start_scan_thread(); 196162306a36Sopenharmony_ci else if (strncmp(buf, "scan=off", 8) == 0) 196262306a36Sopenharmony_ci stop_scan_thread(); 196362306a36Sopenharmony_ci else if (strncmp(buf, "scan=", 5) == 0) { 196462306a36Sopenharmony_ci unsigned secs; 196562306a36Sopenharmony_ci unsigned long msecs; 196662306a36Sopenharmony_ci 196762306a36Sopenharmony_ci ret = kstrtouint(buf + 5, 0, &secs); 196862306a36Sopenharmony_ci if (ret < 0) 196962306a36Sopenharmony_ci goto out; 197062306a36Sopenharmony_ci 197162306a36Sopenharmony_ci msecs = secs * MSEC_PER_SEC; 197262306a36Sopenharmony_ci if (msecs > UINT_MAX) 197362306a36Sopenharmony_ci msecs = UINT_MAX; 197462306a36Sopenharmony_ci 197562306a36Sopenharmony_ci stop_scan_thread(); 197662306a36Sopenharmony_ci if (msecs) { 197762306a36Sopenharmony_ci WRITE_ONCE(jiffies_scan_wait, msecs_to_jiffies(msecs)); 197862306a36Sopenharmony_ci start_scan_thread(); 197962306a36Sopenharmony_ci } 198062306a36Sopenharmony_ci } else if (strncmp(buf, "scan", 4) == 0) 198162306a36Sopenharmony_ci kmemleak_scan(); 198262306a36Sopenharmony_ci else if (strncmp(buf, "dump=", 5) == 0) 198362306a36Sopenharmony_ci ret = dump_str_object_info(buf + 5); 198462306a36Sopenharmony_ci else 198562306a36Sopenharmony_ci ret = -EINVAL; 198662306a36Sopenharmony_ci 198762306a36Sopenharmony_ciout: 198862306a36Sopenharmony_ci mutex_unlock(&scan_mutex); 198962306a36Sopenharmony_ci if (ret < 0) 199062306a36Sopenharmony_ci return ret; 199162306a36Sopenharmony_ci 199262306a36Sopenharmony_ci /* ignore the rest of the buffer, only one command at a time */ 199362306a36Sopenharmony_ci *ppos += size; 199462306a36Sopenharmony_ci return size; 199562306a36Sopenharmony_ci} 199662306a36Sopenharmony_ci 199762306a36Sopenharmony_cistatic const struct file_operations kmemleak_fops = { 199862306a36Sopenharmony_ci .owner = THIS_MODULE, 199962306a36Sopenharmony_ci .open = kmemleak_open, 200062306a36Sopenharmony_ci .read = seq_read, 200162306a36Sopenharmony_ci .write = kmemleak_write, 200262306a36Sopenharmony_ci .llseek = seq_lseek, 200362306a36Sopenharmony_ci .release = seq_release, 200462306a36Sopenharmony_ci}; 200562306a36Sopenharmony_ci 200662306a36Sopenharmony_cistatic void __kmemleak_do_cleanup(void) 200762306a36Sopenharmony_ci{ 200862306a36Sopenharmony_ci struct kmemleak_object *object, *tmp; 200962306a36Sopenharmony_ci 201062306a36Sopenharmony_ci /* 201162306a36Sopenharmony_ci * Kmemleak has already been disabled, no need for RCU list traversal 201262306a36Sopenharmony_ci * or kmemleak_lock held. 201362306a36Sopenharmony_ci */ 201462306a36Sopenharmony_ci list_for_each_entry_safe(object, tmp, &object_list, object_list) { 201562306a36Sopenharmony_ci __remove_object(object); 201662306a36Sopenharmony_ci __delete_object(object); 201762306a36Sopenharmony_ci } 201862306a36Sopenharmony_ci} 201962306a36Sopenharmony_ci 202062306a36Sopenharmony_ci/* 202162306a36Sopenharmony_ci * Stop the memory scanning thread and free the kmemleak internal objects if 202262306a36Sopenharmony_ci * no previous scan thread (otherwise, kmemleak may still have some useful 202362306a36Sopenharmony_ci * information on memory leaks). 202462306a36Sopenharmony_ci */ 202562306a36Sopenharmony_cistatic void kmemleak_do_cleanup(struct work_struct *work) 202662306a36Sopenharmony_ci{ 202762306a36Sopenharmony_ci stop_scan_thread(); 202862306a36Sopenharmony_ci 202962306a36Sopenharmony_ci mutex_lock(&scan_mutex); 203062306a36Sopenharmony_ci /* 203162306a36Sopenharmony_ci * Once it is made sure that kmemleak_scan has stopped, it is safe to no 203262306a36Sopenharmony_ci * longer track object freeing. Ordering of the scan thread stopping and 203362306a36Sopenharmony_ci * the memory accesses below is guaranteed by the kthread_stop() 203462306a36Sopenharmony_ci * function. 203562306a36Sopenharmony_ci */ 203662306a36Sopenharmony_ci kmemleak_free_enabled = 0; 203762306a36Sopenharmony_ci mutex_unlock(&scan_mutex); 203862306a36Sopenharmony_ci 203962306a36Sopenharmony_ci if (!kmemleak_found_leaks) 204062306a36Sopenharmony_ci __kmemleak_do_cleanup(); 204162306a36Sopenharmony_ci else 204262306a36Sopenharmony_ci pr_info("Kmemleak disabled without freeing internal data. Reclaim the memory with \"echo clear > /sys/kernel/debug/kmemleak\".\n"); 204362306a36Sopenharmony_ci} 204462306a36Sopenharmony_ci 204562306a36Sopenharmony_cistatic DECLARE_WORK(cleanup_work, kmemleak_do_cleanup); 204662306a36Sopenharmony_ci 204762306a36Sopenharmony_ci/* 204862306a36Sopenharmony_ci * Disable kmemleak. No memory allocation/freeing will be traced once this 204962306a36Sopenharmony_ci * function is called. Disabling kmemleak is an irreversible operation. 205062306a36Sopenharmony_ci */ 205162306a36Sopenharmony_cistatic void kmemleak_disable(void) 205262306a36Sopenharmony_ci{ 205362306a36Sopenharmony_ci /* atomically check whether it was already invoked */ 205462306a36Sopenharmony_ci if (cmpxchg(&kmemleak_error, 0, 1)) 205562306a36Sopenharmony_ci return; 205662306a36Sopenharmony_ci 205762306a36Sopenharmony_ci /* stop any memory operation tracing */ 205862306a36Sopenharmony_ci kmemleak_enabled = 0; 205962306a36Sopenharmony_ci 206062306a36Sopenharmony_ci /* check whether it is too early for a kernel thread */ 206162306a36Sopenharmony_ci if (kmemleak_late_initialized) 206262306a36Sopenharmony_ci schedule_work(&cleanup_work); 206362306a36Sopenharmony_ci else 206462306a36Sopenharmony_ci kmemleak_free_enabled = 0; 206562306a36Sopenharmony_ci 206662306a36Sopenharmony_ci pr_info("Kernel memory leak detector disabled\n"); 206762306a36Sopenharmony_ci} 206862306a36Sopenharmony_ci 206962306a36Sopenharmony_ci/* 207062306a36Sopenharmony_ci * Allow boot-time kmemleak disabling (enabled by default). 207162306a36Sopenharmony_ci */ 207262306a36Sopenharmony_cistatic int __init kmemleak_boot_config(char *str) 207362306a36Sopenharmony_ci{ 207462306a36Sopenharmony_ci if (!str) 207562306a36Sopenharmony_ci return -EINVAL; 207662306a36Sopenharmony_ci if (strcmp(str, "off") == 0) 207762306a36Sopenharmony_ci kmemleak_disable(); 207862306a36Sopenharmony_ci else if (strcmp(str, "on") == 0) { 207962306a36Sopenharmony_ci kmemleak_skip_disable = 1; 208062306a36Sopenharmony_ci stack_depot_request_early_init(); 208162306a36Sopenharmony_ci } 208262306a36Sopenharmony_ci else 208362306a36Sopenharmony_ci return -EINVAL; 208462306a36Sopenharmony_ci return 0; 208562306a36Sopenharmony_ci} 208662306a36Sopenharmony_ciearly_param("kmemleak", kmemleak_boot_config); 208762306a36Sopenharmony_ci 208862306a36Sopenharmony_ci/* 208962306a36Sopenharmony_ci * Kmemleak initialization. 209062306a36Sopenharmony_ci */ 209162306a36Sopenharmony_civoid __init kmemleak_init(void) 209262306a36Sopenharmony_ci{ 209362306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF 209462306a36Sopenharmony_ci if (!kmemleak_skip_disable) { 209562306a36Sopenharmony_ci kmemleak_disable(); 209662306a36Sopenharmony_ci return; 209762306a36Sopenharmony_ci } 209862306a36Sopenharmony_ci#endif 209962306a36Sopenharmony_ci 210062306a36Sopenharmony_ci if (kmemleak_error) 210162306a36Sopenharmony_ci return; 210262306a36Sopenharmony_ci 210362306a36Sopenharmony_ci jiffies_min_age = msecs_to_jiffies(MSECS_MIN_AGE); 210462306a36Sopenharmony_ci jiffies_scan_wait = msecs_to_jiffies(SECS_SCAN_WAIT * 1000); 210562306a36Sopenharmony_ci 210662306a36Sopenharmony_ci object_cache = KMEM_CACHE(kmemleak_object, SLAB_NOLEAKTRACE); 210762306a36Sopenharmony_ci scan_area_cache = KMEM_CACHE(kmemleak_scan_area, SLAB_NOLEAKTRACE); 210862306a36Sopenharmony_ci 210962306a36Sopenharmony_ci /* register the data/bss sections */ 211062306a36Sopenharmony_ci create_object((unsigned long)_sdata, _edata - _sdata, 211162306a36Sopenharmony_ci KMEMLEAK_GREY, GFP_ATOMIC); 211262306a36Sopenharmony_ci create_object((unsigned long)__bss_start, __bss_stop - __bss_start, 211362306a36Sopenharmony_ci KMEMLEAK_GREY, GFP_ATOMIC); 211462306a36Sopenharmony_ci /* only register .data..ro_after_init if not within .data */ 211562306a36Sopenharmony_ci if (&__start_ro_after_init < &_sdata || &__end_ro_after_init > &_edata) 211662306a36Sopenharmony_ci create_object((unsigned long)__start_ro_after_init, 211762306a36Sopenharmony_ci __end_ro_after_init - __start_ro_after_init, 211862306a36Sopenharmony_ci KMEMLEAK_GREY, GFP_ATOMIC); 211962306a36Sopenharmony_ci} 212062306a36Sopenharmony_ci 212162306a36Sopenharmony_ci/* 212262306a36Sopenharmony_ci * Late initialization function. 212362306a36Sopenharmony_ci */ 212462306a36Sopenharmony_cistatic int __init kmemleak_late_init(void) 212562306a36Sopenharmony_ci{ 212662306a36Sopenharmony_ci kmemleak_late_initialized = 1; 212762306a36Sopenharmony_ci 212862306a36Sopenharmony_ci debugfs_create_file("kmemleak", 0644, NULL, NULL, &kmemleak_fops); 212962306a36Sopenharmony_ci 213062306a36Sopenharmony_ci if (kmemleak_error) { 213162306a36Sopenharmony_ci /* 213262306a36Sopenharmony_ci * Some error occurred and kmemleak was disabled. There is a 213362306a36Sopenharmony_ci * small chance that kmemleak_disable() was called immediately 213462306a36Sopenharmony_ci * after setting kmemleak_late_initialized and we may end up with 213562306a36Sopenharmony_ci * two clean-up threads but serialized by scan_mutex. 213662306a36Sopenharmony_ci */ 213762306a36Sopenharmony_ci schedule_work(&cleanup_work); 213862306a36Sopenharmony_ci return -ENOMEM; 213962306a36Sopenharmony_ci } 214062306a36Sopenharmony_ci 214162306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN)) { 214262306a36Sopenharmony_ci mutex_lock(&scan_mutex); 214362306a36Sopenharmony_ci start_scan_thread(); 214462306a36Sopenharmony_ci mutex_unlock(&scan_mutex); 214562306a36Sopenharmony_ci } 214662306a36Sopenharmony_ci 214762306a36Sopenharmony_ci pr_info("Kernel memory leak detector initialized (mem pool available: %d)\n", 214862306a36Sopenharmony_ci mem_pool_free_count); 214962306a36Sopenharmony_ci 215062306a36Sopenharmony_ci return 0; 215162306a36Sopenharmony_ci} 215262306a36Sopenharmony_cilate_initcall(kmemleak_late_init); 2153