cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rethook.h (3153B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Return hooking with list-based shadow stack.
      4 */
      5#ifndef _LINUX_RETHOOK_H
      6#define _LINUX_RETHOOK_H
      7
      8#include <linux/compiler.h>
      9#include <linux/freelist.h>
     10#include <linux/kallsyms.h>
     11#include <linux/llist.h>
     12#include <linux/rcupdate.h>
     13#include <linux/refcount.h>
     14
     15struct rethook_node;
     16
     17typedef void (*rethook_handler_t) (struct rethook_node *, void *, struct pt_regs *);
     18
     19/**
     20 * struct rethook - The rethook management data structure.
     21 * @data: The user-defined data storage.
     22 * @handler: The user-defined return hook handler.
     23 * @pool: The pool of struct rethook_node.
     24 * @ref: The reference counter.
     25 * @rcu: The rcu_head for deferred freeing.
     26 *
     27 * Don't embed to another data structure, because this is a self-destructive
     28 * data structure when all rethook_node are freed.
     29 */
     30struct rethook {
     31	void			*data;
     32	rethook_handler_t	handler;
     33	struct freelist_head	pool;
     34	refcount_t		ref;
     35	struct rcu_head		rcu;
     36};
     37
     38/**
     39 * struct rethook_node - The rethook shadow-stack entry node.
     40 * @freelist: The freelist, linked to struct rethook::pool.
     41 * @rcu: The rcu_head for deferred freeing.
     42 * @llist: The llist, linked to a struct task_struct::rethooks.
     43 * @rethook: The pointer to the struct rethook.
     44 * @ret_addr: The storage for the real return address.
     45 * @frame: The storage for the frame pointer.
     46 *
     47 * You can embed this to your extended data structure to store any data
     48 * on each entry of the shadow stack.
     49 */
     50struct rethook_node {
     51	union {
     52		struct freelist_node freelist;
     53		struct rcu_head      rcu;
     54	};
     55	struct llist_node	llist;
     56	struct rethook		*rethook;
     57	unsigned long		ret_addr;
     58	unsigned long		frame;
     59};
     60
     61struct rethook *rethook_alloc(void *data, rethook_handler_t handler);
     62void rethook_free(struct rethook *rh);
     63void rethook_add_node(struct rethook *rh, struct rethook_node *node);
     64struct rethook_node *rethook_try_get(struct rethook *rh);
     65void rethook_recycle(struct rethook_node *node);
     66void rethook_hook(struct rethook_node *node, struct pt_regs *regs, bool mcount);
     67unsigned long rethook_find_ret_addr(struct task_struct *tsk, unsigned long frame,
     68				    struct llist_node **cur);
     69
     70/* Arch dependent code must implement arch_* and trampoline code */
     71void arch_rethook_prepare(struct rethook_node *node, struct pt_regs *regs, bool mcount);
     72void arch_rethook_trampoline(void);
     73
     74/**
     75 * is_rethook_trampoline() - Check whether the address is rethook trampoline
     76 * @addr: The address to be checked
     77 *
     78 * Return true if the @addr is the rethook trampoline address.
     79 */
     80static inline bool is_rethook_trampoline(unsigned long addr)
     81{
     82	return addr == (unsigned long)dereference_symbol_descriptor(arch_rethook_trampoline);
     83}
     84
     85/* If the architecture needs to fixup the return address, implement it. */
     86void arch_rethook_fixup_return(struct pt_regs *regs,
     87			       unsigned long correct_ret_addr);
     88
     89/* Generic trampoline handler, arch code must prepare asm stub */
     90unsigned long rethook_trampoline_handler(struct pt_regs *regs,
     91					 unsigned long frame);
     92
     93#ifdef CONFIG_RETHOOK
     94void rethook_flush_task(struct task_struct *tk);
     95#else
     96#define rethook_flush_task(tsk)	do { } while (0)
     97#endif
     98
     99#endif
    100