From 8fee64342a05660e1a7ecf4e1e994bac0f57aca1 Mon Sep 17 00:00:00 2001 From: GarfieldHan <2652609017@qq.com> Date: Sat, 20 Jul 2024 16:06:53 +0800 Subject: [PATCH] selinux: Fix Android specific configs handling in policydb_write() orig patch: https://android-review.googlesource.com/c/kernel/common/+/3009995 Co-authored-by: sekaiacg Co-authored-by: Wang Han Signed-off-by: GarfieldHan <2652609017@qq.com> --- kernel/include/preset.h | 1 + kernel/patch/android/sepolicy_flags.c | 58 +++++++++++++++++++++++++++ kernel/patch/include/sepolicy_flags.h | 40 ++++++++++++++++++ kernel/patch/patch.c | 10 ++++- tools/symbol.c | 1 + 5 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 kernel/patch/android/sepolicy_flags.c create mode 100644 kernel/patch/include/sepolicy_flags.h diff --git a/kernel/include/preset.h b/kernel/include/preset.h index b63772de..be6232f8 100644 --- a/kernel/include/preset.h +++ b/kernel/include/preset.h @@ -118,6 +118,7 @@ struct patch_symbol uint64_t cgroup_post_fork; uint64_t avc_denied; uint64_t slow_avc_audit; + uint64_t policydb_write; uint64_t input_handle_event; }; char _cap[PATCH_SYMBOL_LEN]; diff --git a/kernel/patch/android/sepolicy_flags.c b/kernel/patch/android/sepolicy_flags.c new file mode 100644 index 00000000..5548c730 --- /dev/null +++ b/kernel/patch/android/sepolicy_flags.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2024 1f2003d5. All Rights Reserved. + * Copyright (C) 2024 sekaiacg. All Rights Reserved. + */ + +#include "sepolicy_flags.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * see: https://android-review.googlesource.com/c/kernel/common/+/3009995 + * + */ + +static int (*policydb_write_backup)(struct _policydb *p, struct _policy_file *fp) = 0; +static int policydb_write_replace(struct _policydb *p, struct _policy_file *fp) +{ + char *data = fp->data; + int ret = policydb_write_backup(p, fp); + if (!ret) { + __le32 *config = (__le32 *)(data + POLICYDB_CONFIG_OFFSET); + __le32 before_config = *config; + bool android_netlink_route_exists = before_config & POLICYDB_CONFIG_ANDROID_NETLINK_ROUTE; + bool android_netlink_getneigh_exists = before_config & POLICYDB_CONFIG_ANDROID_NETLINK_GETNEIGH; + if (p->android_netlink_route == 1 && !android_netlink_route_exists) { + *config |= POLICYDB_CONFIG_ANDROID_NETLINK_ROUTE; + } + if (p->android_netlink_getneigh == 1 && !android_netlink_getneigh_exists) { + *config |= POLICYDB_CONFIG_ANDROID_NETLINK_GETNEIGH; + } + } + return ret; +} + +int android_sepolicy_flags_init() +{ + unsigned long policydb_write_addr = get_preset_patch_sym()->policydb_write; + if (likely(policydb_write_addr)) { + hook_err_t err = hook((void *)policydb_write_addr, (void *)policydb_write_replace, (void **)&policydb_write_backup); + if (unlikely(err != HOOK_NO_ERR)) { + log_boot("hook policydb_write_addr: %llx, error: %d\n", policydb_write_addr, err); + return -1; + } + } + + return 0; +} diff --git a/kernel/patch/include/sepolicy_flags.h b/kernel/patch/include/sepolicy_flags.h new file mode 100644 index 00000000..4a6b9216 --- /dev/null +++ b/kernel/patch/include/sepolicy_flags.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2024 1f2003d5. All Rights Reserved. + * Copyright (C) 2024 sekaiacg. All Rights Reserved. + */ + +#ifndef _KP_SEPOLICY_FLAGS_H_ +#define _KP_SEPOLICY_FLAGS_H_ + +#include + +#define SELINUX_MAGIC 0xf97cff8c +#define POLICYDB_MAGIC SELINUX_MAGIC +#define POLICYDB_STRING "SE Linux" + +#define POLICYDB_CONFIG_MLS 1 +#define POLICYDB_CONFIG_ANDROID_NETLINK_ROUTE (1 << 31) +#define POLICYDB_CONFIG_ANDROID_NETLINK_GETNEIGH (1 << 30) + +/* + * config offset: + * __le32(POLICYDB_MAGIC) + __le32(POLICYDB_STRING_LEN) + + * char[POLICYDB_STRING_LEN] + __le32(policyvers) + */ +#define POLICYDB_CONFIG_OFFSET (2 * sizeof(__le32) + strlen(POLICYDB_STRING) + sizeof(__le32)) + +struct _policy_file +{ + char *data; + size_t len; +}; + +struct _policydb +{ + int mls_enabled; + int android_netlink_route; + int android_netlink_getneigh; +}; + +#endif \ No newline at end of file diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index d4093dfe..34330486 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -46,7 +46,10 @@ int resolve_pt_regs(); int supercall_install(); int su_compat_init(); +#ifdef ANDROID int android_user_init(); +int android_sepolicy_flags_init(); +#endif static void before_rest_init(hook_fargs4_t *args, void *udata) { @@ -62,6 +65,11 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) if ((rc = bypass_selinux())) goto out; log_boot("bypass_selinux done: %d\n", rc); +#ifdef ANDROID + rc = android_sepolicy_flags_init(); + log_boot("android_sepolicy_flags_init done: %d\n", rc); +#endif + if ((rc = task_observer())) goto out; log_boot("task_observer done: %d\n", rc); @@ -75,10 +83,8 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) log_boot("resolve_pt_regs done: %d\n", rc); #ifdef ANDROID - rc = android_user_init(); log_boot("android_user_init done: %d\n", rc); - #endif out: diff --git a/tools/symbol.c b/tools/symbol.c index d3787b90..9c5c275a 100644 --- a/tools/symbol.c +++ b/tools/symbol.c @@ -126,6 +126,7 @@ int fillin_patch_symbol(kallsym_t *kallsym, char *img_buf, int imglen, patch_sym symbol->slow_avc_audit = try_get_symbol_offset_zero(kallsym, img_buf, "slow_avc_audit"); + symbol->policydb_write = try_get_symbol_offset_zero(kallsym, img_buf, "policydb_write"); symbol->input_handle_event = get_symbol_offset_zero(kallsym, img_buf, "input_handle_event"); if ((is_be() ^ target_is_be)) {