/
usr
/
src
/
file_protector-1.1-1507
/
syscall_hooks
/
File Upload :
llllll
Current File: //usr/src/file_protector-1.1-1507/syscall_hooks/syscall_utils.h
/** @file @brief syscall utils @details Copyright (c) 2022 Acronis International GmbH @author Mikhail Krivtsov (mikhail.krivtsov@acronis.com) @since $Id: $ */ #pragma once #include <linux/syscalls.h> // Syscall hook may either decide to call to the original function 'fn' or return value 'ret'. // If 'fn' is not NULL, syscall hook trampoline will jump to this function. // If 'fn' is NULL, syscall hook trampoline will return 'ret'. typedef struct { long fn; long ret; } syscall_hook_ret_t; #define MAP0(m,...) #define MAP1(m,t,a,...) m(t,a) #define MAP2(m,t,a,...) m(t,a), MAP1(m,__VA_ARGS__) #define MAP3(m,t,a,...) m(t,a), MAP2(m,__VA_ARGS__) #define MAP4(m,t,a,...) m(t,a), MAP3(m,__VA_ARGS__) #define MAP5(m,t,a,...) m(t,a), MAP4(m,__VA_ARGS__) #define MAP6(m,t,a,...) m(t,a), MAP5(m,__VA_ARGS__) #define MAP7(m,t,a,...) m(t,a), MAP6(m,__VA_ARGS__) #define MAP8(m,t,a,...) m(t,a), MAP7(m,__VA_ARGS__) #define MAP9(m,t,a,...) m(t,a), MAP8(m,__VA_ARGS__) #define MAP10(m,t,a,...) m(t,a), MAP9(m,__VA_ARGS__) #define MAP11(m,t,a,...) m(t,a), MAP10(m,__VA_ARGS__) #define MAP(n,...) MAP##n(__VA_ARGS__) #define SC_DECL(t, a) t a #define TYPE_AS(t, v) __same_type((__force t)0, v) #define TYPE_IS_L(t) (TYPE_AS(t, 0L)) #define TYPE_IS_UL(t) (TYPE_AS(t, 0UL)) #define TYPE_IS_LL(t) (TYPE_AS(t, 0LL) || TYPE_AS(t, 0ULL)) #define SC_LONG(t, a) __typeof(__builtin_choose_expr(TYPE_IS_LL(t), 0LL, 0L)) a #define SC_CAST(t, a) (__force t) a #define SC_ARGS(t, a) a #define SC_DELOUSE(t,v) ((__force t)(unsigned long)(v)) #define SYSCALL_HOOK_ID(abi, tag) abi##_##tag##_hook_id #define COMPAT_SYSCALL_HOOK_ID SYSCALL_HOOK_ID #define SYSCALL_HOOK_TRAMPOLINE(abi, tag) abi##_##tag##_trampoline #define SYSCALL_HOOK_NAME(abi, tag) abi##_##tag##_hook #define COMPAT_SYSCALL_HOOK_NAME SYSCALL_HOOK_NAME #define SYSCALL_HOOK_TYPE_NAME(abi, tag) abi##_##tag##_hook_func_t #define SYSCALL_ORIG_TYPE_NAME(abi, tag) abi##_##tag##_orig_func_t #if defined CONFIG_ARCH_HAS_SYSCALL_WRAPPER #define SYSCALL_HOOK_IMPL_NAME(abi, tag) \ sc_##abi##_##tag##_hook_impl #define COMPAT_SYSCALL_HOOK_IMPL_NAME SYSCALL_HOOK_IMPL_NAME #define SYSCALL_HOOK_SE_NAME(abi, tag) \ sc_##abi##_##tag##_hook_se #define COMPAT_SYSCALL_HOOK_SE_NAME SYSCALL_HOOK_SE_NAME /* Mapping of registers to parameters for syscalls on x86-64 and x32 */ // #define SC_X86_64_REGS_TO_ARGS(x, ...) #define SC_sys_REGS_TO_ARGS SC_X86_64_REGS_TO_ARGS /* Mapping of registers to parameters for syscalls on i386 */ // #define SC_IA32_REGS_TO_ARGS(x, ...) #define SC_ia32_sys_REGS_TO_ARGS SC_IA32_REGS_TO_ARGS #define SC_compat_sys_REGS_TO_ARGS SC_IA32_REGS_TO_ARGS #define DEFINE_SYSCALL_HOOK_TYPE(abi, tag, args_cnt, ...) \ typedef asmlinkage syscall_hook_ret_t (*SYSCALL_HOOK_TYPE_NAME(abi, tag))(const struct pt_regs *regs) #define DEFINE_SYSCALL_ORIG_TYPE(abi, tag, args_cnt, ...) \ typedef asmlinkage long (*SYSCALL_ORIG_TYPE_NAME(abi, tag))(const struct pt_regs *regs) #define DECLARE_SYSCALL_HOOK(abi, tag, args_cnt, ...) \ asmlinkage syscall_hook_ret_t SYSCALL_HOOK_NAME(abi, tag)(const struct pt_regs *regs) #define DEFINE_SYSCALL_HOOK(abi, tag, args_cnt, ...) \ static inline \ asmlinkage syscall_hook_ret_t SYSCALL_HOOK_SE_NAME(abi, tag)(const struct pt_regs *regs, MAP(args_cnt, SC_LONG,__VA_ARGS__)); \ \ asmlinkage syscall_hook_ret_t SYSCALL_HOOK_NAME(abi, tag)(const struct pt_regs *regs) \ { \ return SYSCALL_HOOK_SE_NAME(abi, tag)(regs, SC_##abi##_REGS_TO_ARGS(args_cnt, SYSCALL_ARG)); \ } \ \ static inline \ asmlinkage syscall_hook_ret_t SYSCALL_HOOK_IMPL_NAME(abi, tag)(const struct pt_regs *regs, MAP(args_cnt, SC_DECL, __VA_ARGS__)); \ \ static inline \ asmlinkage syscall_hook_ret_t SYSCALL_HOOK_SE_NAME(abi, tag)(const struct pt_regs *regs, MAP(args_cnt, SC_LONG,__VA_ARGS__)) \ { \ return SYSCALL_HOOK_IMPL_NAME(abi, tag)(regs, MAP(args_cnt, SC_CAST,__VA_ARGS__)); \ } \ static inline \ asmlinkage syscall_hook_ret_t SYSCALL_HOOK_IMPL_NAME(abi, tag)(const struct pt_regs *regs, MAP(args_cnt, SC_DECL, __VA_ARGS__)) #define DECLARE_COMPAT_SYSCALL_HOOK(abi, tag, args_cnt, ...) \ asmlinkage syscall_hook_ret_t COMPAT_SYSCALL_HOOK_NAME(abi, tag)(const struct pt_regs *regs) #define DEFINE_COMPAT_SYSCALL_HOOK(abi, tag, args_cnt, ...) \ static inline \ asmlinkage syscall_hook_ret_t COMPAT_SYSCALL_HOOK_SE_NAME(abi, tag)(const struct pt_regs *regs, MAP(args_cnt, SC_LONG,__VA_ARGS__)); \ \ asmlinkage syscall_hook_ret_t COMPAT_SYSCALL_HOOK_NAME(abi, tag)(const struct pt_regs *regs) \ { \ return COMPAT_SYSCALL_HOOK_SE_NAME(abi, tag)(regs, SC_##abi##_REGS_TO_ARGS(args_cnt, SYSCALL_ARG)); \ } \ \ static inline \ asmlinkage syscall_hook_ret_t COMPAT_SYSCALL_HOOK_IMPL_NAME(abi, tag)(const struct pt_regs *regs, MAP(args_cnt, SC_DECL, __VA_ARGS__)); \ \ static inline \ asmlinkage syscall_hook_ret_t COMPAT_SYSCALL_HOOK_SE_NAME(abi, tag)(const struct pt_regs *regs, MAP(args_cnt, SC_LONG,__VA_ARGS__)) \ { \ return COMPAT_SYSCALL_HOOK_IMPL_NAME(abi, tag)(regs, MAP(args_cnt, SC_DELOUSE,__VA_ARGS__)); \ } \ static inline \ asmlinkage syscall_hook_ret_t COMPAT_SYSCALL_HOOK_IMPL_NAME(abi, tag)(const struct pt_regs *regs, MAP(args_cnt, SC_DECL, __VA_ARGS__)) #else #define DEFINE_SYSCALL_HOOK_TYPE(abi, tag, args_cnt, ...) \ typedef asmlinkage syscall_hook_ret_t (*SYSCALL_HOOK_TYPE_NAME(abi, tag))(MAP(args_cnt, SC_DECL, __VA_ARGS__)) #define DEFINE_SYSCALL_ORIG_TYPE(abi, tag, args_cnt, ...) \ typedef asmlinkage long (*SYSCALL_ORIG_TYPE_NAME(abi, tag))(MAP(args_cnt, SC_DECL, __VA_ARGS__)) #define DECLARE_SYSCALL_HOOK(abi, tag, args_cnt, ...) \ asmlinkage syscall_hook_ret_t SYSCALL_HOOK_NAME(abi, tag)(MAP(args_cnt, SC_DECL, __VA_ARGS__)) #define DEFINE_SYSCALL_HOOK DECLARE_SYSCALL_HOOK #define DEFINE_COMPAT_SYSCALL_HOOK DEFINE_SYSCALL_HOOK #define DECLARE_COMPAT_SYSCALL_HOOK DECLARE_SYSCALL_HOOK #endif #define DEFINE_COMPAT_SYSCALL_HOOK_TYPE DEFINE_SYSCALL_HOOK_TYPE #define DEFINE_COMPAT_SYSCALL_ORIG_TYPE DEFINE_SYSCALL_ORIG_TYPE // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #if 0 For example, the following: DEFINE_SYSCALL_HOOK(sys, creat, 2, const char __user *, pathname, umode_t, mode) { ... } will expand into: static inline __attribute__((unused)) __attribute__((no_instrument_function)) syscall_hook_ret_t sc_sys_creat_hook_se( const struct pt_regs *regs, typeof(0LL) pathname, typeof(0L) mode); syscall_hook_ret_t sys_creat_hook(const struct pt_regs *regs) { return sc_sys_creat_hook_se(regs, regs->di, regs->si); } static inline __attribute__((unused)) __attribute__((no_instrument_function)) syscall_hook_ret_t sc_sys_creat_hook_impl(const struct pt_regs *regs, const char * pathname, umode_t mode); static inline __attribute__((unused)) __attribute__((no_instrument_function)) syscall_hook_ret_t sc_sys_creat_hook_se( const struct pt_regs *regs, typeof(0LL) pathname, typeof(0L) mode) { return sc_sys_creat_hook_impl(regs, ( const char *) pathname, ( umode_t) mode); } static inline __attribute__((unused)) __attribute__((no_instrument_function)) syscall_hook_ret_t sc_sys_creat_hook_impl(const struct pt_regs *regs, const char * pathname, umode_t mode) { ... } #endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #if defined CONFIG_ARCH_HAS_SYSCALL_WRAPPER #define DEFINE_CALL_ORIGINAL_SYSCALL_HANDLER(tag, args_cnt, ...) \ static \ inline \ long call_original_sc_##tag##_handler( \ const enum tag##_hook_type hook_type, \ const struct pt_regs *regs \ ) #else #define DEFINE_CALL_ORIGINAL_SYSCALL_HANDLER(tag, args_cnt, ...) \ static \ inline \ long call_original_sc_##tag##_handler( \ const enum tag##_hook_type hook_type, \ MAP(args_cnt, SC_DECL, __VA_ARGS__) \ ) #endif #define DEFINE_GET_ORIGINAL_SYSCALL_HANDLER(tag) \ static \ inline \ long get_original_sc_##tag##_handler( \ const enum tag##_hook_type hook_type \ ) #if defined CONFIG_ARCH_HAS_SYSCALL_WRAPPER #define CALL_ORIGINAL_SYSCALL_HANDLER_PTR(original_syscall_ptr, ...) \ original_syscall_ptr(regs) #else #define CALL_ORIGINAL_SYSCALL_HANDLER_PTR(original_syscall_ptr, ...) \ original_syscall_ptr(__VA_ARGS__) #endif #define SET_ORIGINAL_SYSCALL_HANDLER(tag, hook_type) \ do{ syscall_hook_ret.fn = get_original_sc_##tag##_handler(hook_type); syscall_hook_ret.ret = 0; }while(0) #define SET_HOOK_RETURN(err) do{ syscall_hook_ret.fn = 0; syscall_hook_ret.ret = err; }while(0) #if defined CONFIG_ARCH_HAS_SYSCALL_WRAPPER #define CALL_ORIGINAL_SYSCALL_HANDLER(tag, hook_type, ...) \ do{ ret = call_original_sc_##tag##_handler( \ hook_type, \ regs \ ); SET_HOOK_RETURN(ret); }while(0) #else #define CALL_ORIGINAL_SYSCALL_HANDLER(tag, hook_type, ...) \ do{ ret = call_original_sc_##tag##_handler( \ hook_type, \ __VA_ARGS__ \ ); SET_HOOK_RETURN(ret); }while(0) #endif #if defined CONFIG_ARCH_HAS_SYSCALL_WRAPPER #define DEFINE_SYSCALL_HANDLER(tag, args_cnt, ...) \ static \ inline \ syscall_hook_ret_t sc_##tag##_handler( \ const struct pt_regs *regs, \ const enum tag##_hook_type hook_type, \ MAP(args_cnt, SC_DECL, __VA_ARGS__) \ ) #else #define DEFINE_SYSCALL_HANDLER(tag, args_cnt, ...) \ static \ inline \ syscall_hook_ret_t sc_##tag##_handler( \ const enum tag##_hook_type hook_type, \ MAP(args_cnt, SC_DECL, __VA_ARGS__) \ ) #endif #if defined CONFIG_ARCH_HAS_SYSCALL_WRAPPER #define CALL_SYSCALL_HANDLER(tag, hook_type, ...) \ sc_##tag##_handler( \ regs, \ hook_type, \ __VA_ARGS__ \ ) #else #define CALL_SYSCALL_HANDLER(tag, hook_type, ...) \ sc_##tag##_handler( \ hook_type, \ __VA_ARGS__ \ ) #endif
Copyright ©2k19 -
Hexid
|
Tex7ure