diff --git a/drivers/hck/Kconfig b/drivers/hck/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..1028c52a384064dff3fbf1dae5eb601261feb3fd --- /dev/null +++ b/drivers/hck/Kconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-only +menu "Hck" + +config HCK + bool "Hck Drivers" + help + Enable support for various drivers needed on the OpenHarmony Common Kernel + +if HCK + +config HCK_VENDOR_HOOKS + bool "Hck Vendor Hooks" + help + Enable vendor hooks implemented as tracepoints + + Allow vendor modules to attach to tracepoint "hooks" defined via + DECLARE_HCK_HOOK DECLARE_HCK_RESTRICTED_HOOK + +endif # if HCK + +endmenu diff --git a/drivers/hck/Makefile b/drivers/hck/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..93dc6acc727a0423daf616107c48072013799a4b --- /dev/null +++ b/drivers/hck/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only +ccflags-y += -I$(src) + +obj-$(CONFIG_HCK_VENDOR_HOOKS) += vendor_hooks.o \ No newline at end of file diff --git a/drivers/hck/vendor_hooks.c b/drivers/hck/vendor_hooks.c new file mode 100644 index 0000000000000000000000000000000000000000..6dce54016ef64da7cbf04bc8cb4edad5bb89d47a --- /dev/null +++ b/drivers/hck/vendor_hooks.c @@ -0,0 +1,17 @@ +//SPDX-License-Identifier: GPL-2.0-only +/*vendor_hooks.c + * + *OpenHarmony Common Kernel Vendor Hook Support + * + */ + +/* lite vendor hook */ +#define CREATE_LITE_VENDOR_HOOK +/* add your lite vendor hook header file here */ +#include +#include +#include +#include +#include +#include +#include diff --git a/include/linux/hck/lite_hck_ced.h b/include/linux/hck/lite_hck_ced.h new file mode 100644 index 0000000000000000000000000000000000000000..9d1ffb7ccef360504d458c47962ad4b71b112d5a --- /dev/null +++ b/include/linux/hck/lite_hck_ced.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + */ + +#ifndef _LITE_HCK_CED_H +#define _LITE_HCK_CED_H + +#include +#include +#include + +#ifndef CONFIG_HCK +#undef CALL_HCK_LITE_HOOK +#define CALL_HCK_LITE_HOOK(name, args...) +#undef REGISTER_HCK_LITE_HOOK +#define REGISTER_HCK_LITE_HOOK(name, probe) +#undef REGISTER_HCK_LITE_DATA_HOOK +#define REGISTER_HCK_LITE_DATA_HOOK(name, probe, data) +#else +DECLARE_HCK_LITE_HOOK(ced_setattr_insert_lhck, + TP_PROTO(struct task_struct *task), + TP_ARGS(task)); + +DECLARE_HCK_LITE_HOOK(ced_switch_task_namespaces_lhck, + TP_PROTO(const struct nsproxy *new), + TP_ARGS(new)); + +DECLARE_HCK_LITE_HOOK(ced_detection_lhck, + TP_PROTO(struct task_struct *task), + TP_ARGS(task)); + +DECLARE_HCK_LITE_HOOK(ced_exit_lhck, + TP_PROTO(struct task_struct *task), + TP_ARGS(task)); + +DECLARE_HCK_LITE_HOOK(ced_kernel_clone_lhck, + TP_PROTO(struct task_struct *task), + TP_ARGS(task)); + +DECLARE_HCK_LITE_HOOK(ced_commit_creds_lhck, + TP_PROTO(const struct cred *new), + TP_ARGS(new)); + +DECLARE_HCK_LITE_HOOK(ced_switch_task_namespaces_permission_lhck, + TP_PROTO(const struct nsproxy *new, int *ret), + TP_ARGS(new, ret)); +#endif /* CONFIG_HCK */ + +#endif /* _LITE_HCK_CED_H */ diff --git a/include/linux/hck/lite_hck_code_sign.h b/include/linux/hck/lite_hck_code_sign.h new file mode 100644 index 0000000000000000000000000000000000000000..d479babbf5cb45ba85bdad2f04e2076c550dd7f5 --- /dev/null +++ b/include/linux/hck/lite_hck_code_sign.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + */ + +#ifndef LITE_HCK_CODE_SIGN_H +#define LITE_HCK_CODE_SIGN_H + +#include + +#ifndef CONFIG_HCK + +#define CALL_HCK_LITE_HOOK(name, args...) +#define REGISTER_HCK_LITE_HOOK(name, probe) +#define REGISTER_HCK_LITE_DATA_HOOK(name, probe, data) + +#else + +DECLARE_HCK_LITE_HOOK(code_sign_verify_certchain_lhck, + TP_PROTO(const void *raw_pkcs7, size_t pkcs7_len, struct cs_info *cs_info, + int *ret), + TP_ARGS(raw_pkcs7, pkcs7_len, cs_info, ret)); + +DECLARE_HCK_LITE_HOOK(code_sign_check_descriptor_lhck, + TP_PROTO(const struct inode *inode, const void *desc, int *ret), + TP_ARGS(inode, desc, ret)); + +DECLARE_HCK_LITE_HOOK(code_sign_before_measurement_lhck, + TP_PROTO(void *desc, int *ret), + TP_ARGS(desc, ret)); + +DECLARE_HCK_LITE_HOOK(code_sign_after_measurement_lhck, + TP_PROTO(void *desc, int version), + TP_ARGS(desc, version)); + +#endif /* CONFIG_HCK */ + +#endif /* LITE_HCK_CODE_SIGN_H */ diff --git a/include/linux/hck/lite_hck_hideaddr.h b/include/linux/hck/lite_hck_hideaddr.h new file mode 100644 index 0000000000000000000000000000000000000000..e7dbf9695b5538341ebceaab9a5c2093ac4ada50 --- /dev/null +++ b/include/linux/hck/lite_hck_hideaddr.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + */ + +#ifndef _LITE_HCK_HIDEADDR_H +#define _LITE_HCK_HIDEADDR_H + +#include "linux/seq_file.h" +#include "linux/mm_types.h" +#include + +#ifndef CONFIG_HCK +#define CALL_HCK_LITE_HOOK(name, args...) +#define REGISTER_HCK_LITE_HOOK(name, probe) +#define REGISTER_HCK_LITE_DATA_HOOK(name, probe, data) +#else + + +DECLARE_HCK_LITE_HOOK(hideaddr_header_prefix_lhck, + TP_PROTO(unsigned long *start, unsigned long *end, vm_flags_t *flags, struct seq_file *m, struct vm_area_struct *vma), + TP_ARGS(start, end, flags, m, vma)); + +#endif /* CONFIG_HCK */ +#endif /* _LITE_HCK_HIDEADDR_H */ diff --git a/include/linux/hck/lite_hck_inet.h b/include/linux/hck/lite_hck_inet.h new file mode 100644 index 0000000000000000000000000000000000000000..5dd1ecd837fe17ab62067c1ffcacb64f04530ada --- /dev/null +++ b/include/linux/hck/lite_hck_inet.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + */ + +#ifndef LITE_HCK_INET_H +#define LITE_HCK_INET_H + +#include + +#ifndef CONFIG_HCK +#undef CALL_HCK_LITE_HOOK +#define CALL_HCK_LITE_HOOK(name, args...) +#undef REGISTER_HCK_LITE_HOOK +#define REGISTER_HCK_LITE_HOOK(name, probe) +#undef REGISTER_HCK_LITE_DATA_HOOK +#define REGISTER_HCK_LITE_DATA_HOOK(name, probe, data) +#else + +DECLARE_HCK_LITE_HOOK(nip_ninet_ehashfn_lhck, + TP_PROTO(const struct sock *sk, u32 *ret), + TP_ARGS(sk, ret)); + +#endif /* CONFIG_HCK */ + +#endif /* LITE_HCK_INET_H */ diff --git a/include/linux/hck/lite_hck_jit_memory.h b/include/linux/hck/lite_hck_jit_memory.h new file mode 100644 index 0000000000000000000000000000000000000000..dbce24a4379b666aa00dbc0a0604dc56e3d5807e --- /dev/null +++ b/include/linux/hck/lite_hck_jit_memory.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +*/ + +#ifndef LITE_HCK_JIT_MEMORY_H +#define LITE_HCK_JIT_MEMORY_H + +#include +#include + +#ifndef CONFIG_HCK +#undef CALL_HCK_LITE_HOOK +#define CALL_HCK_LITE_HOOK(name, args...) +#undef REGISTER_HCK_LITE_HOOK +#define REGISTER_HCK_LITE_HOOK(name, probe) +#undef REGISTER_HCK_LITE_DATA_HOOK +#define REGISTER_HCK_LITE_DATA_HOOK(name, probe, data) + +#else + +DECLARE_HCK_LITE_HOOK(find_jit_memory_lhck, + TP_PROTO(struct task_struct *task, unsigned long start, unsigned long size, int *err), + TP_ARGS(task, start, size, err)); + +DECLARE_HCK_LITE_HOOK(check_jit_memory_lhck, + TP_PROTO(struct task_struct *task, unsigned long cookie, unsigned long prot, + unsigned long flag, unsigned long size, unsigned long *err), + TP_ARGS(task, cookie, prot, flag, size, err)); + +DECLARE_HCK_LITE_HOOK(delete_jit_memory_lhck, + TP_PROTO(struct task_struct *task, unsigned long start, unsigned long size, int *err), + TP_ARGS(task, start, size, err)); + +DECLARE_HCK_LITE_HOOK(exit_jit_memory_lhck, + TP_PROTO(struct task_struct *task), + TP_ARGS(task)); + +#endif /* CONFIG_HCK */ + +#endif /* LITE_HCK_JIT_MEMORY_H */ diff --git a/include/linux/hck/lite_hck_sample.h b/include/linux/hck/lite_hck_sample.h new file mode 100644 index 0000000000000000000000000000000000000000..f29dec41a6265618e2d8a1504b2b2f15390cf640 --- /dev/null +++ b/include/linux/hck/lite_hck_sample.h @@ -0,0 +1,36 @@ +//SPDX-License-Identifier: GPL-2.0-only +/*lite_hck_sample.h + * + *OpenHarmony Common Kernel Vendor Hook Smaple + * + */ + +#ifndef LITE_HCK_SAMPLE_H +#define LITE_HCK_SAMPLE_H + +#include + + +struct sample_hck_data { + int stat; + char* name; +}; + +/* + * Follwing tracepoints are not exported in trace and provide a + * mechanism for vendor modules to hok and extend functionality + */ +#ifndef CONFIG_HCK + +#define CALL_HCK_LITE_HOOK(name, args...) +#define REGISTER_HCK_LITE_HOOK(name, probe) +#define REGISTER_HCK_LITE_DATA_HOOK(name, probe, data) + +#else + +DECLARE_HCK_LITE_HOOK(get_boot_config_lhck, TP_PROTO(int* s), TP_ARGS(s)); +DECLARE_HCK_LITE_HOOK(set_boot_stat_lhck, TP_PROTO(int m), TP_ARGS(m)); + +#endif + +#endif /* LITE_HCK_SAMPLE_H */ diff --git a/include/linux/hck/lite_hck_xpm.h b/include/linux/hck/lite_hck_xpm.h new file mode 100644 index 0000000000000000000000000000000000000000..0ec0063d34004ca750b102c48ad9e2544060a245 --- /dev/null +++ b/include/linux/hck/lite_hck_xpm.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + */ + +#ifndef _LITE_HCK_XPM_H +#define _LITE_HCK_XPM_H + +#include +#include +#include + +#ifndef CONFIG_HCK +#undef CALL_HCK_LITE_HOOK +#define CALL_HCK_LITE_HOOK(name, args...) +#undef REGISTER_HCK_LITE_HOOK +#define REGISTER_HCK_LITE_HOOK(name, probe) +#undef REGISTER_HCK_LITE_DATA_HOOK +#define REGISTER_HCK_LITE_DATA_HOOK(name, probe, data) +#else +DECLARE_HCK_LITE_HOOK(xpm_delete_cache_node_lhck, + TP_PROTO(struct inode *file_node), + TP_ARGS(file_node)); + +DECLARE_HCK_LITE_HOOK(xpm_region_outer_lhck, + TP_PROTO(unsigned long addr_start, unsigned long addr_end, + unsigned long flags, bool *ret), + TP_ARGS(addr_start, addr_end, flags, ret)); + +DECLARE_HCK_LITE_HOOK(xpm_get_unmapped_area_lhck, + TP_PROTO(unsigned long addr, unsigned long len, unsigned long map_flags, + unsigned long unmapped_flags, unsigned long *ret), + TP_ARGS(addr, len, map_flags, unmapped_flags, ret)); + +DECLARE_HCK_LITE_HOOK(xpm_integrity_equal_lhck, + TP_PROTO(struct page *page, struct page *kpage, bool *ret), + TP_ARGS(page, kpage, ret)); + +DECLARE_HCK_LITE_HOOK(xpm_integrity_check_lhck, + TP_PROTO(struct vm_area_struct *vma, unsigned int vflags, + unsigned long addr, struct page *page, vm_fault_t *ret), + TP_ARGS(vma, vflags, addr, page, ret)); + +DECLARE_HCK_LITE_HOOK(xpm_integrity_validate_lhck, + TP_PROTO(struct vm_area_struct *vma, unsigned int vflags, + unsigned long addr, struct page *page, vm_fault_t *ret), + TP_ARGS(vma, vflags, addr, page, ret)); + +DECLARE_HCK_LITE_HOOK(xpm_integrity_update_lhck, + TP_PROTO(struct vm_area_struct *vma, unsigned int vflags, + struct page *page), + TP_ARGS(vma, vflags, page)); +#endif /* CONFIG_HCK */ + +#endif /* _LITE_HCK_XPM_H */ diff --git a/include/linux/hck/lite_vendor_hooks.h b/include/linux/hck/lite_vendor_hooks.h new file mode 100644 index 0000000000000000000000000000000000000000..4b0f30f6c49363ef586aee6bcd7d8e0e09af5fb8 --- /dev/null +++ b/include/linux/hck/lite_vendor_hooks.h @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * OpenHarmony Common Kernel Vendor Hook Support + * Based on include/trace/hooks/lite_vendor_hooks.h + * + */ + +#ifndef LITE_VENDOR_HOOK_H +#define LITE_VENDOR_HOOK_H + +#include +#include +#include +#include +#include +#include + +struct __lvh_func { + void *func; + void *data; + bool has_data; +}; + +struct lite_vendor_hook { + struct mutex mutex; + struct __lvh_func *funcs; +}; +#endif // LITE_VENDOR_HOOK_H + +#ifdef CREATE_LITE_VENDOR_HOOK + +#define DEFINE_HCK_LITE_HOOK(name, proto, args) \ + struct lite_vendor_hook __lvh_##name __used \ + __section("__vendor_hooks") = { \ + .mutex = __MUTEX_INITIALIZER(__lvh_##name.mutex), \ + .funcs = NULL }; \ + EXPORT_SYMBOL(__lvh_##name); \ + void lvh_probe_##name(proto) { return; } \ + void lvh_probe_data_##name(void *lvh_data, proto) { return; } + +#undef DECLARE_HCK_LITE_HOOK +#define DECLARE_HCK_LITE_HOOK(name, proto, args) \ + DEFINE_HCK_LITE_HOOK(name, PARAMS(proto), PARAMS(args)) + +#else // #ifndef CREATE_LITE_VENDOR_HOOK + +#define REGISTER_HCK_LITE_HOOK(name, probe) \ + extern typeof(lvh_probe_##name) (probe); \ + do { \ + if (register_lvh_##name(probe)) \ + WARN_ONCE(1, "LVH register failed!\n"); \ + } while (0) + +#define REGISTER_HCK_LITE_DATA_HOOK(name, probe, data) \ + extern typeof(lvh_probe_data_##name) (probe); \ + do { \ + if (register_lvh_data_##name(probe, data)) \ + WARN_ONCE(1, "LVH register failed!\n"); \ + } while (0) + +#define CALL_HCK_LITE_HOOK(name, args...) \ + call_lvh_##name(args) + +#define __DECLARE_HCK_LITE_HOOK(name, proto, args) \ + extern struct lite_vendor_hook __lvh_##name; \ + extern void lvh_probe_##name(proto); \ + extern void lvh_probe_data_##name(void *lvh_data, proto); \ + static inline void \ + call_lvh_##name(proto) \ + { \ + struct __lvh_func *funcs = (&__lvh_##name)->funcs; \ + if (funcs && funcs->func) { \ + if (funcs->has_data) \ + ((void(*)(void *, proto))funcs->func)(funcs->data, args); \ + else \ + ((void(*)(proto))funcs->func)(args); \ + } \ + } \ + static inline int \ + __register_lvh_##name(void *probe, void *data, bool has_data) \ + { \ + int err = 0; \ + struct __lvh_func *funcs; \ + struct module *mod; \ + mutex_lock(&__lvh_##name.mutex); \ + funcs = (&__lvh_##name)->funcs; \ + if (funcs) { \ + if (funcs->func != probe || funcs->data != data) \ + err = -EBUSY; \ + goto out; \ + } \ + \ + funcs = (struct __lvh_func*)kmalloc(sizeof(struct __lvh_func), GFP_KERNEL); \ + if (!funcs) { \ + err = -ENOMEM; \ + goto out; \ + } \ + \ + funcs->func = probe; \ + funcs->data = data; \ + funcs->has_data = has_data; \ + mod = __module_address((uintptr_t)probe); \ + if (mod) \ + (void)try_module_get(mod); \ + (&__lvh_##name)->funcs = funcs; \ + out: \ + mutex_unlock(&__lvh_##name.mutex); \ + return err; \ + } \ + static inline int \ + register_lvh_##name(void (*probe)(proto)) \ + { \ + return __register_lvh_##name((void *)probe, NULL, false); \ + } \ + static inline int \ + register_lvh_data_##name(void (*probe)(void *lvh_data, proto), void *data) \ + { \ + return __register_lvh_##name((void *)probe, data, true); \ + } + +#undef DECLARE_HCK_LITE_HOOK +#define DECLARE_HCK_LITE_HOOK(name, proto, args) \ + __DECLARE_HCK_LITE_HOOK(name, PARAMS(proto), PARAMS(args)) + +#endif // CREATE_LITE_VENDOR_HOOK