Skip to content

Commit

Permalink
kernel: hook newfstatat/faccessat syscall instead of unstable symbol
Browse files Browse the repository at this point in the history
  • Loading branch information
tiann committed Mar 20, 2024
1 parent 2a64784 commit 815f4d0
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 3 deletions.
8 changes: 8 additions & 0 deletions kernel/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
#define PRCTL_SYMBOL "__arm64_sys_prctl"
#define SYS_READ_SYMBOL "__arm64_sys_read"
#define SYS_NEWFSTATAT_SYMBOL "__arm64_sys_newfstatat"
#define SYS_FACCESSAT_SYMBOL "__arm64_sys_faccessat"
#else
#define PRCTL_SYMBOL "sys_prctl"
#define SYS_READ_SYMBOL "sys_read"
#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat"
#define SYS_FACCESSAT_SYMBOL "sys_faccessat"
#endif

#elif defined(__x86_64__)
Expand All @@ -44,9 +48,13 @@
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
#define PRCTL_SYMBOL "__x64_sys_prctl"
#define SYS_READ_SYMBOL "__x64_sys_read"
#define SYS_NEWFSTATAT_SYMBOL "__x64_sys_newfstatat"
#define SYS_FACCESSAT_SYMBOL "__x64_sys_faccessat"
#else
#define PRCTL_SYMBOL "sys_prctl"
#define SYS_READ_SYMBOL "sys_read"
#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat"
#define SYS_FACCESSAT_SYMBOL "sys_faccessat"
#endif

#else
Expand Down
49 changes: 46 additions & 3 deletions kernel/sucompat.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "asm/current.h"
#include "linux/compiler_attributes.h"
#include "linux/cred.h"
#include "linux/err.h"
#include "linux/fs.h"
Expand Down Expand Up @@ -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 *flags)
int * __unused_flags)
{
const char su[] = SU_PATH;

Expand Down Expand Up @@ -131,7 +132,7 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,

#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);
const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs);
Expand All @@ -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);
}

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);
const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs);
Expand All @@ -157,6 +172,20 @@ static int newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs)
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
static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
{
Expand All @@ -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);
}

#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 = {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
.symbol_name = "do_faccessat",
Expand All @@ -175,7 +210,14 @@ static struct kprobe faccessat_kp = {
#endif
.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 = {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
.symbol_name = "vfs_statx",
Expand All @@ -184,6 +226,7 @@ static struct kprobe newfstatat_kp = {
#endif
.pre_handler = newfstatat_handler_pre,
};
#endif

static struct kprobe execve_kp = {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
Expand Down

0 comments on commit 815f4d0

Please sign in to comment.