diff --git a/drivers/Kconfig b/drivers/Kconfig index 826b2b19d0b8608a6423e84ca8cfe262f9139b57..3584901f12527cee26a7f8b9a23e5b820e225393 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -239,4 +239,7 @@ source "drivers/counter/Kconfig" source "drivers/most/Kconfig" source "drivers/accesstokenid/Kconfig" + +source "drivers/hooks/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index ecc494918773a322108b6bc095ceae518e1fee2a..f13d70df6557a7568cb1234b8ef7e6cb04e6c208 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -193,3 +193,4 @@ obj-$(CONFIG_INTERCONNECT) += interconnect/ obj-$(CONFIG_COUNTER) += counter/ obj-$(CONFIG_MOST) += most/ obj-$(CONFIG_ACCESS_TOKENID) += accesstokenid/ +obj-$(CONFIG_VENDOR_HOOKS) += hooks/ diff --git a/drivers/hooks/Kconfig b/drivers/hooks/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..547933c5975f32a1479df5e8ba6a1d15b125aa19 --- /dev/null +++ b/drivers/hooks/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 +menu "Vendor Hooks" + +config VENDOR_HOOKS + bool "Vendor Hooks" + depends on TRACEPOINTS + help + Enable vendor hooks implemented as tracepoints + + Allow vendor modules to attach to tracepoint "hooks" defined via + DECLARE_TRACE or DECLARE_HOOK + +endmenu diff --git a/drivers/hooks/Makefile b/drivers/hooks/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..533f270e09204415b03ca91c6d00bc1bb7a72aa7 --- /dev/null +++ b/drivers/hooks/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +ccflags-y += -I$(src) # needed for trace events + +obj-$(CONFIG_VENDOR_HOOKS) += vendor_hooks.o diff --git a/drivers/hooks/vendor_hooks.c b/drivers/hooks/vendor_hooks.c new file mode 100644 index 0000000000000000000000000000000000000000..939146da879cf3fcd9576cb7a7d227773b096513 --- /dev/null +++ b/drivers/hooks/vendor_hooks.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* vendor_hooks.c + * + * Vendor Hook Support + * + * Copyright (C) 2020 Google, Inc. + * Copyright (C) 2022 Huawei Technologies Co., Ltd. + */ + +#define CREATE_TRACE_POINTS +#include +#include + +/* + * Export tracepoints that act as a bare tracehook(ie: have no trace event + * associated with them) to allow external modules to probe them. + * + * For example: + * EXPORT_TRACEPOINT_SYMBOL_GPL(vendor_foo); + */ + +EXPORT_TRACEPOINT_SYMBOL_GPL(vendor_do_mmap); +EXPORT_TRACEPOINT_SYMBOL_GPL(vendor_do_mprotect_pkey); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h new file mode 100644 index 0000000000000000000000000000000000000000..dbe41923041b038664f0dbabdc520844ff32d66d --- /dev/null +++ b/include/trace/hooks/mm.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mm + +#define TRACE_INCLUDE_PATH trace/hooks +#if !defined(_TRACE_HOOKS_MM_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOKS_MM_H + +#include +#include + +DECLARE_HOOK(vendor_do_mmap, + TP_PROTO(vm_flags_t *vm_flags, int *err), + TP_ARGS(vm_flags, err) +); + +DECLARE_HOOK(vendor_do_mprotect_pkey, + TP_PROTO(unsigned long prot, int *err), + TP_ARGS(prot, err) +); + +#endif + +/* This part must be outside protection */ +#include diff --git a/include/trace/hooks/vendor_hooks.h b/include/trace/hooks/vendor_hooks.h new file mode 100644 index 0000000000000000000000000000000000000000..21bafd6388740c456cbf6ccd63a72f0f28d4ccd6 --- /dev/null +++ b/include/trace/hooks/vendor_hooks.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include + +#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_VENDOR_HOOKS) + +#define DECLARE_HOOK DECLARE_TRACE + +#else /* !CONFIG_TRACEPOINTS || !CONFIG_VENDOR_HOOKS */ + +#define DECLARE_HOOK DECLARE_EVENT_NOP + +#endif diff --git a/mm/mmap.c b/mm/mmap.c index 76e95375ed02d8d80fef8196efa370aab6558992..d6c6a639ce3d572f7e41f4007b7063882dca5443 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -57,6 +57,9 @@ #define CREATE_TRACE_POINTS #include +#undef CREATE_TRACE_POINTS +#include + #include "internal.h" #ifndef arch_mmap_check @@ -1416,6 +1419,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr, struct mm_struct *mm = current->mm; vm_flags_t vm_flags; int pkey = 0; + int err = 0; *populate = 0; @@ -1479,6 +1483,10 @@ unsigned long do_mmap(struct file *file, unsigned long addr, vm_flags = calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; + trace_vendor_do_mmap(&vm_flags, &err); + if (err) + return err; + if (flags & MAP_LOCKED) if (!can_do_mlock()) return -EPERM; diff --git a/mm/mprotect.c b/mm/mprotect.c index 53b6b1b8fb67a9968adc478120eb09299b551841..8fc1f3bee7f3ea68dc840c82c44a8881c78a07fc 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -33,6 +33,7 @@ #include #include +#include #include "internal.h" static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, @@ -519,6 +520,11 @@ static int do_mprotect_pkey(unsigned long start, size_t len, const bool rier = (current->personality & READ_IMPLIES_EXEC) && (prot & PROT_READ); + error = 0; + trace_vendor_do_mprotect_pkey(prot, &error); + if (error) + return error; + start = untagged_addr(start); prot &= ~(PROT_GROWSDOWN|PROT_GROWSUP);