Skip to content

Commit

Permalink
feat: update liblol-dkms to 0.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
deepin-community-bot[bot] authored and xzl01 committed Jan 23, 2025
1 parent ff3e489 commit bfa0489
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 81 deletions.
40 changes: 26 additions & 14 deletions Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,31 @@ CONFIG_LOONGARCH_OW_SYSCALL := m
endif

obj-$(CONFIG_LOONGARCH_OW_SYSCALL) += la_ow_syscall.o
la_ow_syscall-y += fsstat.o la_ow_syscall_main.o signal.o
la_ow_syscall-y += fsstat.o la_ow_syscall_main.o signal.o systable.o
targets += feat_test.o

ifndef KBUILD_EXTMOD
ifdef CONFIG_KALLSYMS
ifndef CONFIG_RANDOMIZE_BASE
$(obj)/ksym_addr.h: System.map
$(obj)/kernel_feature.h: $(obj)/feat_test.syms
@$(kecho) ' GEN $@'
$(Q)grep ' sys_call_table$$' $< >/dev/null
$(Q)grep ' kallsyms_lookup_name$$' $< >/dev/null
$(Q)echo "#define LAOWSYS_SYS_CALL_TABLE_ADDR 0x$$(grep ' sys_call_table$$' $< | cut -d ' ' -f 1)" > $@
$(Q)echo "#define LAOWSYS_KALLSYMS_LOOKUP_NAME_ADDR 0x$$(grep ' kallsyms_lookup_name$$' $< | cut -d ' ' -f 1)" >> $@
ccflags-y += -DHAVE_KSYM_ADDR
$(obj)/$(la_ow_syscall-y): $(obj)/ksym_addr.h
endif
endif
endif
$(Q)if grep "kernel_have_new_stat" $< >/dev/null; then \
echo "#define KERNEL_HAVE_NEW_STAT"; \
else \
echo "/* KERNEL_HAVE_NEW_STAT is not defined */"; \
fi > $@
$(Q)if grep "kernel_have_systbl" $< >/dev/null; then \
echo "#define KERNEL_HAVE_SYSTBL"; \
else \
echo "/* KERNEL_HAVE_SYSTBL is not defined */"; \
fi >> $@

$(obj)/feat_test.syms: $(obj)/feat_test.o
@$(kecho) ' GEN $@'
$(Q)$(OBJDUMP) -t --section=.text $< >$@

$(obj)/module_version.h: $(src)/VERSION
@$(kecho) ' GEN $@'
$(Q)echo "#define THIS_MODULE_VERSION \"$(shell cat $<)\"" > $@

$(obj)/systable.o $(obj)/fsstat.o: $(obj)/kernel_feature.h
$(obj)/la_ow_syscall_main.o: $(obj)/module_version.h

clean-files += kernel_feature.h feat_test.syms module_version.h
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.0
0.1.1
12 changes: 12 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
liblol-dkms (0.1.1) unstable; urgency=low

* Release 0.1.1

-- Miao Wang <[email protected]> Wed, 18 Sep 2024 23:32:00 +0800

liblol-dkms (0.1.1~pre1) unstable; urgency=low

* Add support for kernel 6.11, where fstat and newfstat are introduced.

-- Miao Wang <[email protected]> Sun, 01 Sep 2024 00:48:00 +0800

liblol-dkms (0.1.0) unstable; urgency=low

* Initial build
Expand Down
4 changes: 4 additions & 0 deletions debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ override_dh_auto_install:
install -Dvm644 \
Kbuild \
Makefile \
VERSION \
feat_test.c \
fsstat.c \
fsstat.h \
la_ow_syscall_main.c \
signal.c \
signal.h \
systable.c \
systable.h \
-t $(TMPDIR)/usr/src/la_ow_syscall-$(DEB_VERSION_UPSTREAM)
install -Dvm644 \
debian/kmod-autoload.conf \
Expand Down
16 changes: 16 additions & 0 deletions feat_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
This file is used to test if the coresponding macro is defined in unistd.h
If a macro is defined, the coresponding function will be defined, and
the symbol will be shown in the .o file. Later, the Kbuild script will
generate kernel_feature.h according to the existence of the symbols.
*/

#include <asm/unistd.h>
#ifdef __ARCH_WANT_NEW_STAT
void kernel_have_new_stat(void);
void kernel_have_new_stat(void){ }
#endif
#ifndef __SYSCALL
void kernel_have_systbl(void);
void kernel_have_systbl(void){ }
#endif
3 changes: 3 additions & 0 deletions fsstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include <linux/file.h>
#include <linux/mm.h>
#include "fsstat.h"
#include "kernel_feature.h"

#ifndef KERNEL_HAVE_NEW_STAT
#define INIT_STRUCT_STAT_PADDING(st) memset(&st, 0, sizeof(st))

struct __old_kernel_stat {
Expand Down Expand Up @@ -82,3 +84,4 @@ __SYSCALL_DEFINEx(4, _newfstatat, int, dfd, const char __user *, filename,
return error;
return cp_new_stat(&stat, statbuf);
}
#endif
1 change: 1 addition & 0 deletions fsstat.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <linux/stat.h>
extern int (*p_vfs_fstatat)(int dfd, const char __user *filename,
struct kstat *stat, int flags);
extern int (*p_vfs_fstat)(int fd, struct kstat *stat);
74 changes: 8 additions & 66 deletions la_ow_syscall_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/kprobes.h> /* Needed for kprobe calls */
#include "module_version.h"

///< The license type -- this affects runtime behavior
MODULE_LICENSE("GPL");
Expand All @@ -13,75 +14,26 @@ MODULE_AUTHOR("Miao Wang");
MODULE_DESCRIPTION("LoongArch old-world syscall compatibility module");

///< The version of the module
MODULE_VERSION("0.1.0");
MODULE_VERSION(THIS_MODULE_VERSION);

#include <linux/kallsyms.h>
#include <linux/syscalls.h>

#include "systable.h"

#define __EXTERN
#include "fsstat.h"
#include "signal.h"

#define __ARCH_WANT_SET_GET_RLIMIT
#define __ARCH_WANT_NEW_STAT
#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (#call),

const char *sys_call_table_name[__NR_syscalls] = {
[0 ... __NR_syscalls - 1] = "sys_ni_syscall",
#include <asm/unistd.h>
};

#ifndef __loongarch64
#error This Linux kernel module is only supported on LoongArch
#endif

#ifdef HAVE_KSYM_ADDR
#include "ksym_addr.h"
#endif

static struct {
long syscall_num;
void *symbol_addr;
void *orig;
} syscall_to_replace[] = {
{ __NR_fstat, sys_newfstat },
{ __NR_newfstatat, sys_newfstatat },
{ __NR_getrlimit, NULL },
{ __NR_setrlimit, NULL },
{ __NR_rt_sigprocmask, sys_rt_sigprocmask },
{ __NR_rt_sigpending, sys_rt_sigpending },
{ __NR_rt_sigtimedwait, sys_rt_sigtimedwait },
{ __NR_rt_sigaction, sys_rt_sigaction },
{ __NR_rt_sigsuspend, sys_rt_sigsuspend },
{ __NR_pselect6, sys_pselect6 },
{ __NR_ppoll, sys_ppoll },
#ifdef CONFIG_SIGNALFD
{ __NR_signalfd4, sys_signalfd4 },
#endif
#ifdef CONFIG_EPOLL
{ __NR_epoll_pwait, sys_epoll_pwait },
{ __NR_epoll_pwait2, sys_epoll_pwait2 },
#endif
};

#define nr_syscalls_to_replace \
(sizeof(syscall_to_replace) / sizeof(syscall_to_replace[0]))

static unsigned long kallsyms_lookup_name_addr =
#ifdef HAVE_KSYM_ADDR
LAOWSYS_KALLSYMS_LOOKUP_NAME_ADDR
#else
0
#endif
;
static unsigned long kallsyms_lookup_name_addr = 0;
static unsigned int allow_mod_unreg = 0;

#include <asm-generic/sections.h>

#ifdef HAVE_KSYM_ADDR
static int __init find_kallsyms_lookup_name(void){ return 0; }
#else
// Taken from https://github.com/zizzu0/LinuxKernelModules/blob/main/FindKallsymsLookupName.c
#define KPROBE_PRE_HANDLER(fname) \
static int __kprobes fname(struct kprobe *p, struct pt_regs *regs)
Expand Down Expand Up @@ -172,8 +124,6 @@ static int __init find_kallsyms_lookup_name(void)
return -EINVAL;
}
}
#endif


int (*p_vfs_fstatat)(int dfd, const char __user *filename, struct kstat *stat,
int flags);
Expand Down Expand Up @@ -204,11 +154,6 @@ static struct {
};
#define nr_rel_tab (sizeof(relocation_table) / sizeof(relocation_table[0]))

#ifdef HAVE_KSYM_ADDR
static void **p_sys_call_table = (void **)LAOWSYS_SYS_CALL_TABLE_ADDR;
static int __init find_sys_call_table(void){ return 0; };
#else

static void **p_sys_call_table;

#include <linux/jiffies.h>
Expand Down Expand Up @@ -247,7 +192,6 @@ static int __init find_sys_call_table(void)

return -ENOSYS;
}
#endif

static int __init oldsyscall_start(void)
{
Expand All @@ -274,7 +218,7 @@ static int __init oldsyscall_start(void)
if (rc < 0) {
return rc;
}
for (int i = 0; i < nr_syscalls_to_replace; i++) {
for (int i = 0; syscall_to_replace[i].syscall_num != -1; i++) {
if (syscall_to_replace[i].symbol_addr) {
continue;
}
Expand All @@ -296,7 +240,7 @@ static int __init oldsyscall_start(void)
return -EINVAL;
}
}
for (int i = 0; i < nr_syscalls_to_replace; i++) {
for (int i = 0; syscall_to_replace[i].syscall_num != -1; i++) {
pr_debug("will replace syscall_%ld with %px, orig %px\n",
syscall_to_replace[i].syscall_num,
syscall_to_replace[i].symbol_addr,
Expand All @@ -312,7 +256,7 @@ static int __init oldsyscall_start(void)

static void __exit oldsyscall_end(void)
{
for (int i = 0; i < nr_syscalls_to_replace; i++) {
for (int i = 0; syscall_to_replace[i].syscall_num != -1; i++) {
pr_debug("will restore syscall_%ld to %px\n",
syscall_to_replace[i].syscall_num,
syscall_to_replace[i].orig);
Expand All @@ -326,7 +270,5 @@ module_exit(oldsyscall_end);
module_param(allow_mod_unreg, uint, 0000);
MODULE_PARM_DESC(allow_mod_unreg,
"Allow this module to be unload (Danger! Debug use only)");
#ifndef HAVE_KSYM_ADDR
module_param(kallsyms_lookup_name_addr, ulong, 0000);
MODULE_PARM_DESC(kallsyms_lookup_name_addr, "Address for kallsyms_lookup_name, provide this when unable to find using kprobe");
#endif
65 changes: 65 additions & 0 deletions systable.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "systable.h"
#include "kernel_feature.h"

/*
In 6.11 or newer, the asm-generic/unistd.h is not used by the loongarch
asm/unistd.h. Instead, the definition of the syscall table and the syscall
numbers is generated after commit 26a3b85bac08 ("loongarch: convert to
generic syscall table"). As a result, we can no more get the definition of
those syscalls that are not available on Loongarch.
To solve this problem, we still use asm-generic/unistd.h to retrive the
definitions.
To avoid any possible conflicts, only syscall related data are defined here.
No functions are implemented here, so the above hacks will not affect other
parts of our module and will not introduce unexpected changes related to the
syscall numbers, ensuring the consistence of our module with the kernel.
*/

#include <asm-generic/unistd.h>

/*
And we also need those hacks to prevent including asm/unistd.h, which will
cause redefinition of the syscall numbers.
*/

#define _LINUX_UNISTD_H_ /* prevent loading uapi/linux/unistd.h */
#define __ASM_VDSO_H /* prevent loading asm/vdso.h */
#define _ASM_SECCOMP_H /* prevent loading asm/seccomp.h */
#include <linux/syscalls.h>

#define __ARCH_WANT_SET_GET_RLIMIT
#define __ARCH_WANT_NEW_STAT

#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (#call),

const char *sys_call_table_name[__NR_syscalls] = {
[0 ... __NR_syscalls - 1] = "sys_ni_syscall",
#include <asm-generic/unistd.h>
};

struct syscall_replace_table syscall_to_replace[] = {
#ifndef KERNEL_HAVE_NEW_STAT
{ __NR_fstat, sys_newfstat },
{ __NR_newfstatat, sys_newfstatat },
#endif
{ __NR_getrlimit, NULL },
{ __NR_setrlimit, NULL },
{ __NR_rt_sigprocmask, sys_rt_sigprocmask },
{ __NR_rt_sigpending, sys_rt_sigpending },
{ __NR_rt_sigtimedwait, sys_rt_sigtimedwait },
{ __NR_rt_sigaction, sys_rt_sigaction },
{ __NR_rt_sigsuspend, sys_rt_sigsuspend },
{ __NR_pselect6, sys_pselect6 },
{ __NR_ppoll, sys_ppoll },
#ifdef CONFIG_SIGNALFD
{ __NR_signalfd4, sys_signalfd4 },
#endif
#ifdef CONFIG_EPOLL
{ __NR_epoll_pwait, sys_epoll_pwait },
{ __NR_epoll_pwait2, sys_epoll_pwait2 },
#endif
{ -1, NULL },
};
8 changes: 8 additions & 0 deletions systable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
struct syscall_replace_table {
long syscall_num;
void *symbol_addr;
void *orig;
};

extern const char *sys_call_table_name[];
extern struct syscall_replace_table syscall_to_replace[];

0 comments on commit bfa0489

Please sign in to comment.