kernel: hook newfstatat/faccessat syscall instead of unstable symbol
This commit is contained in:
@@ -21,9 +21,13 @@
|
|||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
||||||
#define PRCTL_SYMBOL "__arm64_sys_prctl"
|
#define PRCTL_SYMBOL "__arm64_sys_prctl"
|
||||||
#define SYS_READ_SYMBOL "__arm64_sys_read"
|
#define SYS_READ_SYMBOL "__arm64_sys_read"
|
||||||
|
#define SYS_NEWFSTATAT_SYMBOL "__arm64_sys_newfstatat"
|
||||||
|
#define SYS_FACCESSAT_SYMBOL "__arm64_sys_faccessat"
|
||||||
#else
|
#else
|
||||||
#define PRCTL_SYMBOL "sys_prctl"
|
#define PRCTL_SYMBOL "sys_prctl"
|
||||||
#define SYS_READ_SYMBOL "sys_read"
|
#define SYS_READ_SYMBOL "sys_read"
|
||||||
|
#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat"
|
||||||
|
#define SYS_FACCESSAT_SYMBOL "sys_faccessat"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(__x86_64__)
|
#elif defined(__x86_64__)
|
||||||
@@ -44,9 +48,13 @@
|
|||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
||||||
#define PRCTL_SYMBOL "__x64_sys_prctl"
|
#define PRCTL_SYMBOL "__x64_sys_prctl"
|
||||||
#define SYS_READ_SYMBOL "__x64_sys_read"
|
#define SYS_READ_SYMBOL "__x64_sys_read"
|
||||||
|
#define SYS_NEWFSTATAT_SYMBOL "__x64_sys_newfstatat"
|
||||||
|
#define SYS_FACCESSAT_SYMBOL "__x64_sys_faccessat"
|
||||||
#else
|
#else
|
||||||
#define PRCTL_SYMBOL "sys_prctl"
|
#define PRCTL_SYMBOL "sys_prctl"
|
||||||
#define SYS_READ_SYMBOL "sys_read"
|
#define SYS_READ_SYMBOL "sys_read"
|
||||||
|
#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat"
|
||||||
|
#define SYS_FACCESSAT_SYMBOL "sys_faccessat"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "asm/current.h"
|
#include "asm/current.h"
|
||||||
|
#include "linux/compiler_attributes.h"
|
||||||
#include "linux/cred.h"
|
#include "linux/cred.h"
|
||||||
#include "linux/err.h"
|
#include "linux/err.h"
|
||||||
#include "linux/fs.h"
|
#include "linux/fs.h"
|
||||||
@@ -40,7 +41,7 @@ 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 * __unused_flags)
|
||||||
{
|
{
|
||||||
const char su[] = SU_PATH;
|
const char su[] = SU_PATH;
|
||||||
|
|
||||||
@@ -131,7 +132,7 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
|
|||||||
|
|
||||||
#ifdef CONFIG_KPROBES
|
#ifdef CONFIG_KPROBES
|
||||||
|
|
||||||
static int faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
__maybe_unused static int faccessat_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);
|
||||||
@@ -142,7 +143,21 @@ static int faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
|||||||
return ksu_handle_faccessat(dfd, filename_user, mode, flags);
|
return ksu_handle_faccessat(dfd, filename_user, mode, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
static int sys_faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
||||||
|
struct pt_regs *real_regs = (struct pt_regs *)PT_REGS_PARM1(regs);
|
||||||
|
#else
|
||||||
|
struct pt_regs *real_regs = regs;
|
||||||
|
#endif
|
||||||
|
int *dfd = (int *)PT_REGS_PARM1(real_regs);
|
||||||
|
const char __user **filename_user = (const char **)&PT_REGS_PARM2(real_regs);
|
||||||
|
int *mode = (int *)&PT_REGS_PARM3(real_regs);
|
||||||
|
|
||||||
|
return ksu_handle_faccessat(dfd, filename_user, mode, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
__maybe_unused 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);
|
||||||
@@ -157,6 +172,20 @@ static int newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
|||||||
return ksu_handle_stat(dfd, filename_user, flags);
|
return ksu_handle_stat(dfd, filename_user, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sys_newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
|
||||||
|
struct pt_regs *real_regs = (struct pt_regs *)PT_REGS_PARM1(regs);
|
||||||
|
#else
|
||||||
|
struct pt_regs *real_regs = regs;
|
||||||
|
#endif
|
||||||
|
int *dfd = (int *)&PT_REGS_PARM1(real_regs);
|
||||||
|
const char __user **filename_user = (const char **)&PT_REGS_PARM2(real_regs);
|
||||||
|
int *flags = (int *)&PT_REGS_SYSCALL_PARM4(real_regs);
|
||||||
|
|
||||||
|
return ksu_handle_stat(dfd, filename_user, flags);
|
||||||
|
}
|
||||||
|
|
||||||
// https://elixir.bootlin.com/linux/v5.10.158/source/fs/exec.c#L1864
|
// https://elixir.bootlin.com/linux/v5.10.158/source/fs/exec.c#L1864
|
||||||
static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
@@ -167,6 +196,12 @@ static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
|||||||
return ksu_handle_execveat_sucompat(fd, filename_ptr, NULL, NULL, NULL);
|
return ksu_handle_execveat_sucompat(fd, filename_ptr, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||||
|
static struct kprobe faccessat_kp = {
|
||||||
|
.symbol_name = SYS_FACCESSAT_SYMBOL,
|
||||||
|
.pre_handler = sys_faccessat_handler_pre,
|
||||||
|
};
|
||||||
|
#else
|
||||||
static struct kprobe faccessat_kp = {
|
static struct kprobe faccessat_kp = {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||||
.symbol_name = "do_faccessat",
|
.symbol_name = "do_faccessat",
|
||||||
@@ -175,7 +210,14 @@ static struct kprobe faccessat_kp = {
|
|||||||
#endif
|
#endif
|
||||||
.pre_handler = faccessat_handler_pre,
|
.pre_handler = faccessat_handler_pre,
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||||
|
static struct kprobe newfstatat_kp = {
|
||||||
|
.symbol_name = SYS_NEWFSTATAT_SYMBOL,
|
||||||
|
.pre_handler = sys_newfstatat_handler_pre,
|
||||||
|
};
|
||||||
|
#else
|
||||||
static struct kprobe newfstatat_kp = {
|
static struct kprobe newfstatat_kp = {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||||
.symbol_name = "vfs_statx",
|
.symbol_name = "vfs_statx",
|
||||||
@@ -184,6 +226,7 @@ static struct kprobe newfstatat_kp = {
|
|||||||
#endif
|
#endif
|
||||||
.pre_handler = newfstatat_handler_pre,
|
.pre_handler = newfstatat_handler_pre,
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct kprobe execve_kp = {
|
static struct kprobe execve_kp = {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user