Files
linux/include/linux/codetag.h
David Wang b0da7709c2 alloc_tag: add sequence number for module and iterator
Codetag iterator use <id,address> pair to guarantee the validness.  But
both id and address can be reused, there is theoretical possibility when
module inserted right after another module removed, kmalloc returns an
address same as the address kfree by previous module and IDR key reuses
the key recently removed.

Add a sequence number to codetag_module and code_iterator, the sequence
number is strickly incremented whenever a module is loaded.  An iterator
is valid if and only if its sequence number match codetag_module's.

Link: https://lkml.kernel.org/r/20250609064200.112639-1-00107082@163.com
Signed-off-by: David Wang <00107082@163.com>
Acked-by: Suren Baghdasaryan <surenb@google.com>
Cc: Kent Overstreet <kent.overstreet@linux.dev>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2025-07-09 22:42:06 -07:00

113 lines
3.4 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* code tagging framework
*/
#ifndef _LINUX_CODETAG_H
#define _LINUX_CODETAG_H
#include <linux/types.h>
struct codetag_iterator;
struct codetag_type;
struct codetag_module;
struct seq_buf;
struct module;
#define CODETAG_SECTION_START_PREFIX "__start_"
#define CODETAG_SECTION_STOP_PREFIX "__stop_"
/*
* An instance of this structure is created in a special ELF section at every
* code location being tagged. At runtime, the special section is treated as
* an array of these.
*/
struct codetag {
unsigned int flags; /* used in later patches */
unsigned int lineno;
const char *modname;
const char *function;
const char *filename;
} __aligned(8);
union codetag_ref {
struct codetag *ct;
};
struct codetag_type_desc {
const char *section;
size_t tag_size;
int (*module_load)(struct module *mod,
struct codetag *start, struct codetag *end);
void (*module_unload)(struct module *mod,
struct codetag *start, struct codetag *end);
#ifdef CONFIG_MODULES
void (*module_replaced)(struct module *mod, struct module *new_mod);
bool (*needs_section_mem)(struct module *mod, unsigned long size);
void *(*alloc_section_mem)(struct module *mod, unsigned long size,
unsigned int prepend, unsigned long align);
void (*free_section_mem)(struct module *mod, bool used);
#endif
};
struct codetag_iterator {
struct codetag_type *cttype;
struct codetag_module *cmod;
unsigned long mod_id;
struct codetag *ct;
unsigned long mod_seq;
};
#ifdef MODULE
#define CT_MODULE_NAME KBUILD_MODNAME
#else
#define CT_MODULE_NAME NULL
#endif
#define CODE_TAG_INIT { \
.modname = CT_MODULE_NAME, \
.function = __func__, \
.filename = __FILE__, \
.lineno = __LINE__, \
.flags = 0, \
}
void codetag_lock_module_list(struct codetag_type *cttype, bool lock);
bool codetag_trylock_module_list(struct codetag_type *cttype);
struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype);
struct codetag *codetag_next_ct(struct codetag_iterator *iter);
void codetag_to_text(struct seq_buf *out, struct codetag *ct);
struct codetag_type *
codetag_register_type(const struct codetag_type_desc *desc);
#if defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES)
bool codetag_needs_module_section(struct module *mod, const char *name,
unsigned long size);
void *codetag_alloc_module_section(struct module *mod, const char *name,
unsigned long size, unsigned int prepend,
unsigned long align);
void codetag_free_module_sections(struct module *mod);
void codetag_module_replaced(struct module *mod, struct module *new_mod);
int codetag_load_module(struct module *mod);
void codetag_unload_module(struct module *mod);
#else /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */
static inline bool
codetag_needs_module_section(struct module *mod, const char *name,
unsigned long size) { return false; }
static inline void *
codetag_alloc_module_section(struct module *mod, const char *name,
unsigned long size, unsigned int prepend,
unsigned long align) { return NULL; }
static inline void codetag_free_module_sections(struct module *mod) {}
static inline void codetag_module_replaced(struct module *mod, struct module *new_mod) {}
static inline int codetag_load_module(struct module *mod) { return 0; }
static inline void codetag_unload_module(struct module *mod) {}
#endif /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */
#endif /* _LINUX_CODETAG_H */