Skip to content

Commit eaeb05b

Browse files
authored
Merge pull request #728 from bytedance/b1_7_file_ref
FIXME: building errors with new kernels after 6.13
2 parents b285d58 + 5e91740 commit eaeb05b

File tree

2 files changed

+37
-48
lines changed

2 files changed

+37
-48
lines changed

driver/LKM/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ endif
9898
ifneq ($(FS_OP_ITERATE_SHARED),)
9999
ccflags-y += -D SMITH_FS_OP_ITERATE_SHARED
100100
endif
101+
FS_FILE_REF := $(shell sh -c "grep -s file_ref_t $(FS_H_FILES)")
102+
ifneq ($(FS_FILE_REF),)
103+
ccflags-y += -D SMITH_FS_FILE_REF
104+
endif
101105

102106
PROCFS_H_FILES := $(shell find -L $(K_I_PATH) -path "*/linux/proc_fs.h") /dev/null
103107
PROCFS_PDE_DATA := $(shell sh -c "grep -s PDE_DATA $(PROCFS_H_FILES)")

driver/LKM/src/smith_hook.c

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,14 @@ static struct files_struct *smith_get_files_struct(struct task_struct *task)
391391
return files;
392392
}
393393

394+
/* only inc f_count when it's not 0 to avoid races upon exe_file */
395+
#ifdef SMITH_FS_FILE_REF
396+
#define smith_get_file(x) (file_ref_read(&(x)->f_ref) && \
397+
atomic_long_inc_not_zero(&(x)->f_ref.refcnt))
398+
#else
399+
#define smith_get_file(x) atomic_long_inc_not_zero(&(x)->f_count)
400+
#endif
401+
394402
#ifdef SMITH_HAVE_FCHECK_FILES
395403
#define smith_lookup_fd fcheck_files /* < 5.10.220 */
396404
#else
@@ -410,7 +418,7 @@ static struct file *smith_fget_raw(unsigned int fd)
410418
file = smith_lookup_fd(files, fd);
411419
if (file) {
412420
/* File object ref couldn't be taken */
413-
if (!atomic_long_inc_not_zero(&file->f_count))
421+
if (!smith_get_file(file))
414422
file = NULL;
415423
}
416424
rcu_read_unlock();
@@ -432,9 +440,6 @@ static char *smith_d_path(const struct path *path, char *buf, int buflen)
432440
return name;
433441
}
434442

435-
/* only inc f_count when it's not 0 to avoid races upon exe_file */
436-
#define smith_get_file(x) atomic_long_inc_not_zero(&(x)->f_count)
437-
438443
/*
439444
* query task's executable image file, with mmap lock avoided, just because
440445
* mmput() could lead resched() (since it's calling might_sleep() interally)
@@ -821,15 +826,6 @@ struct execve_data {
821826
int free_ld_preload;
822827
};
823828

824-
struct update_cred_data {
825-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
826-
uid_t old_uid;
827-
#else
828-
int old_uid;
829-
#endif
830-
};
831-
832-
833829
/*
834830
* Our own implementation of kernel_getsockname and kernel_getpeername,
835831
* resuing codes logic of kernel inet_getname and inet6_getname.
@@ -3798,45 +3794,36 @@ static int do_init_module_pre_handler(struct kprobe *p, struct pt_regs *regs)
37983794
return 0;
37993795
}
38003796

3801-
static int update_cred_entry_handler(struct kretprobe_instance *ri,
3802-
struct pt_regs *regs)
3803-
{
3804-
struct update_cred_data *data;
3805-
data = (struct update_cred_data *)ri->data;
3806-
data->old_uid = __get_current_uid();
3807-
return 0;
3808-
}
3809-
3810-
static int update_cred_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
3797+
static int update_cred_pre_handler(struct kprobe *p, struct pt_regs *regs)
38113798
{
3812-
int now_uid;
3813-
int retval;
38143799
char *exe_path = NULL;
38153800
char *buffer = NULL;
38163801
char *pid_tree = NULL;
3817-
struct update_cred_data *data;
3802+
struct cred *cred;
3803+
int new_uid, old_uid;
38183804

3819-
now_uid = __get_current_uid();
3820-
retval = regs_return_value(regs);
3805+
cred = (void *)p_regs_get_arg1(regs);
3806+
if (IS_ERR_OR_NULL(cred))
3807+
return 0;
3808+
3809+
new_uid = _XID_VALUE(cred->uid);
3810+
old_uid = __get_current_uid();
38213811

3822-
//only get old uid ≠0 && new uid == 0
3823-
if (now_uid != 0)
3812+
// only report if old uid ≠0 && new uid == 0
3813+
if (new_uid != 0 || old_uid == 0)
38243814
return 0;
38253815

3826-
data = (struct update_cred_data *)ri->data;
3827-
if (data->old_uid != 0) {
3828-
buffer = smith_kzalloc(PATH_MAX, GFP_ATOMIC);
3829-
exe_path = smith_get_exe_file(buffer, PATH_MAX);
3816+
buffer = smith_kzalloc(PATH_MAX, GFP_ATOMIC);
3817+
exe_path = smith_get_exe_file(buffer, PATH_MAX);
38303818

3831-
pid_tree = smith_get_pid_tree(PID_TREE_LIMIT);
3832-
update_cred_print(exe_path, pid_tree, data->old_uid, retval);
3819+
pid_tree = smith_get_pid_tree(PID_TREE_LIMIT);
3820+
update_cred_print(exe_path, pid_tree, old_uid, 0);
38333821

3834-
if (buffer)
3835-
smith_kfree(buffer);
3822+
if (buffer)
3823+
smith_kfree(buffer);
3824+
if (pid_tree)
3825+
smith_kfree(pid_tree);
38363826

3837-
if (pid_tree)
3838-
smith_kfree(pid_tree);
3839-
}
38403827
return 0;
38413828
}
38423829

@@ -4043,11 +4030,9 @@ static struct kprobe do_init_module_kprobe = {
40434030
.pre_handler = do_init_module_pre_handler,
40444031
};
40454032

4046-
static struct kretprobe update_cred_kretprobe = {
4047-
.kp.symbol_name = "commit_creds",
4048-
.data_size = sizeof(struct update_cred_data),
4049-
.handler = update_cred_handler,
4050-
.entry_handler = update_cred_entry_handler,
4033+
static struct kprobe update_cred_kprobe = {
4034+
.symbol_name = "commit_creds",
4035+
.pre_handler = update_cred_pre_handler,
40514036
};
40524037

40534038
static struct kprobe security_inode_create_kprobe = {
@@ -4554,7 +4539,7 @@ static void unregister_prctl_kprobe(void)
45544539
static int register_update_cred_kprobe(void)
45554540
{
45564541
int ret;
4557-
ret = smith_register_kretprobe(&update_cred_kretprobe);
4542+
ret = register_kprobe(&update_cred_kprobe);
45584543
if (ret == 0)
45594544
update_cred_kprobe_state = 0x1;
45604545

@@ -4563,7 +4548,7 @@ static int register_update_cred_kprobe(void)
45634548

45644549
static void unregister_update_cred_kprobe(void)
45654550
{
4566-
smith_unregister_kretprobe(&update_cred_kretprobe);
4551+
unregister_kprobe(&update_cred_kprobe);
45674552
}
45684553

45694554
static int register_mprotect_kprobe(void)

0 commit comments

Comments
 (0)