Revert "kernel: getname might sleep in kprobe handler (#670)"
This reverts commit 79bb9813ef.
This commit is contained in:
@@ -52,8 +52,6 @@ static inline bool is_isolated_uid(uid_t uid)
|
|||||||
appid <= LAST_APP_ZYGOTE_ISOLATED_UID);
|
appid <= LAST_APP_ZYGOTE_ISOLATED_UID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct group_info root_groups = { .usage = ATOMIC_INIT(2) };
|
|
||||||
|
|
||||||
static void setup_groups(struct root_profile *profile, struct cred *cred)
|
static void setup_groups(struct root_profile *profile, struct cred *cred)
|
||||||
{
|
{
|
||||||
if (profile->groups_count > KSU_MAX_GROUPS) {
|
if (profile->groups_count > KSU_MAX_GROUPS) {
|
||||||
@@ -62,14 +60,6 @@ static void setup_groups(struct root_profile *profile, struct cred *cred)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile->groups_count == 1 && profile->groups[0] == 0) {
|
|
||||||
// it is root groups, setgroup to root and return early!
|
|
||||||
if (cred->group_info)
|
|
||||||
put_group_info(cred->group_info);
|
|
||||||
cred->group_info = get_group_info(&root_groups);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 ngroups = profile->groups_count;
|
u32 ngroups = profile->groups_count;
|
||||||
struct group_info *group_info = groups_alloc(ngroups);
|
struct group_info *group_info = groups_alloc(ngroups);
|
||||||
if (!group_info) {
|
if (!group_info) {
|
||||||
|
|||||||
@@ -20,13 +20,6 @@
|
|||||||
#define SU_PATH "/system/bin/su"
|
#define SU_PATH "/system/bin/su"
|
||||||
#define SH_PATH "/system/bin/sh"
|
#define SH_PATH "/system/bin/sh"
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
|
||||||
#define ksu_copy_from_user_nofault(dst, src, sz) \
|
|
||||||
copy_from_user_nofault(dst, src, sz)
|
|
||||||
#else
|
|
||||||
#define ksu_copy_from_user_nofault(dst, src, sz) probe_user_read(dst, src, sz)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void escape_to_root();
|
extern void escape_to_root();
|
||||||
|
|
||||||
static void __user *userspace_stack_buffer(const void *d, size_t len)
|
static void __user *userspace_stack_buffer(const void *d, size_t len)
|
||||||
@@ -48,30 +41,32 @@ static char __user *sh_user_path(void)
|
|||||||
int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||||
int *flags)
|
int *flags)
|
||||||
{
|
{
|
||||||
|
struct filename *filename;
|
||||||
const char su[] = SU_PATH;
|
const char su[] = SU_PATH;
|
||||||
|
|
||||||
if (!ksu_is_allow_uid(current_uid().val)) {
|
if (!ksu_is_allow_uid(current_uid().val)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char path[sizeof(su)];
|
filename = getname(*filename_user);
|
||||||
memset(path, 0, sizeof(path));
|
|
||||||
if (ksu_copy_from_user_nofault(path, *filename_user, sizeof(path))) {
|
if (IS_ERR(filename)) {
|
||||||
pr_info("faccessat filename ERR: %d!\n", current_uid().val);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (unlikely(!memcmp(filename->name, su, sizeof(su)))) {
|
||||||
if (unlikely(!memcmp(path, su, sizeof(su)))) {
|
pr_info("faccessat su->sh!\n");
|
||||||
pr_info("faccessat su found: %d!\n", current_uid().val);
|
|
||||||
*filename_user = sh_user_path();
|
*filename_user = sh_user_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
putname(filename);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
|
int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
|
||||||
{
|
{
|
||||||
// const char sh[] = SH_PATH;
|
// const char sh[] = SH_PATH;
|
||||||
|
struct filename *filename;
|
||||||
const char su[] = SU_PATH;
|
const char su[] = SU_PATH;
|
||||||
|
|
||||||
if (!ksu_is_allow_uid(current_uid().val)) {
|
if (!ksu_is_allow_uid(current_uid().val)) {
|
||||||
@@ -79,23 +74,21 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!filename_user)) {
|
if (unlikely(!filename_user)) {
|
||||||
pr_info("stat filename is NULL: %d\n", current_uid().val);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// filename = getname(*filename_user);
|
filename = getname(*filename_user);
|
||||||
char path[sizeof(su)];
|
|
||||||
memset(path, 0, sizeof(path));
|
if (IS_ERR(filename)) {
|
||||||
if (ksu_copy_from_user_nofault(path, *filename_user, sizeof(path))) {
|
|
||||||
pr_info("stat filename ERR: %d!\n", current_uid().val);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (unlikely(!memcmp(filename->name, su, sizeof(su)))) {
|
||||||
if (unlikely(!memcmp(path, su, sizeof(su)))) {
|
pr_info("newfstatat su->sh!\n");
|
||||||
pr_info("stat su found: %d\n", current_uid().val);
|
|
||||||
*filename_user = sh_user_path();
|
*filename_user = sh_user_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
putname(filename);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +113,7 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
|
|||||||
if (!ksu_is_allow_uid(current_uid().val))
|
if (!ksu_is_allow_uid(current_uid().val))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pr_info("do_execveat_common su found: %d\n", current_uid().val);
|
pr_info("do_execveat_common su found\n");
|
||||||
memcpy((void *)filename->name, sh, sizeof(sh));
|
memcpy((void *)filename->name, sh, sizeof(sh));
|
||||||
|
|
||||||
escape_to_root();
|
escape_to_root();
|
||||||
@@ -145,10 +138,10 @@ static int newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
|||||||
int *dfd = (int *)&PT_REGS_PARM1(regs);
|
int *dfd = (int *)&PT_REGS_PARM1(regs);
|
||||||
const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs);
|
const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs);
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||||
// static int vfs_statx(int dfd, const char __user *filename, int flags, struct kstat *stat, u32 request_mask)
|
// static int vfs_statx(int dfd, const char __user *filename, int flags, struct kstat *stat, u32 request_mask)
|
||||||
int *flags = (int *)&PT_REGS_PARM3(regs);
|
int *flags = (int *)&PT_REGS_PARM3(regs);
|
||||||
#else
|
#else
|
||||||
// int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,int flag)
|
// int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,int flag)
|
||||||
int *flags = (int *)&PT_REGS_PARM4(regs);
|
int *flags = (int *)&PT_REGS_PARM4(regs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -179,11 +172,11 @@ static struct kprobe faccessat_kp = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct kprobe newfstatat_kp = {
|
static struct kprobe newfstatat_kp = {
|
||||||
// 5.10: https://elixir.bootlin.com/linux/v5.10/source/include/linux/fs.h#L3115
|
// 5.10: https://elixir.bootlin.com/linux/v5.10/source/include/linux/fs.h#L3115
|
||||||
// 5.9: https://elixir.bootlin.com/linux/v5.9.16/source/include/linux/fs.h#L3179
|
// 5.9: https://elixir.bootlin.com/linux/v5.9.16/source/include/linux/fs.h#L3179
|
||||||
// 4.11: https://elixir.bootlin.com/linux/v4.11/source/include/linux/fs.h#L2931
|
// 4.11: https://elixir.bootlin.com/linux/v4.11/source/include/linux/fs.h#L2931
|
||||||
// 4.10: https://elixir.bootlin.com/linux/v4.10.17/source/include/linux/fs.h#L2889
|
// 4.10: https://elixir.bootlin.com/linux/v4.10.17/source/include/linux/fs.h#L2889
|
||||||
// so, 4.11.0 <= version < 5.10 is vfs_statx, and others are vfs_fstatat
|
// so, 4.11.0 <= version < 5.10 is vfs_statx, and others are vfs_fstatat
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||||
.symbol_name = "vfs_fstatat",
|
.symbol_name = "vfs_fstatat",
|
||||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user