When I am programming a loadable kernel module in Linux, I added a system call that traverses processes and stores them in a structure, then uses copy_to_user() to copy the structure from kernel space to user space. However, I encountered an error during the copy_to_user() process.
this is my struct:
struct process
{
int pid;
int depth;
int have_brother;
char name[16];
}
Below is my module code.
#define free_syscall_num 336 //free syscall number
#define syscall_table_address 0xffffffff8d200320 //syscall table address
long(*save_syscall)(void); //Save the original sys_ni_syscall();
unsigned long *syscall_table=0;
struct process a[1000];
int counter = 0;
/*
*Recursively traverse the linux process tree
*/
void preorder_traversal_processtree(struct task_struct *p_task,int b)
{
struct list_head *list;
a[counter].pid = p_task -> pid;
a[counter].depth = b;
if(p_task -> sibling.next == &(p_task->parent->children))
{
a[counter].have_brother=0;
}
else
{
a[counter].have_brother=1;
}
strcpy(a[counter].name,p_task -> comm);
printk("pid: %dn", a[counter].pid);
counter ++;
list_for_each(list, &p_task->children)
{
printk("pstree is running, counter = %dn", counter);
struct task_struct *t = list_entry(list, struct task_struct, sibling);
preorder_traversal_processtree(t,b+1);
}
}
/*
The body of the system call
*/
asmlinkage long my_syscall(char __user* buf)
{
counter = 0;
preorder_traversal_processtree(&init_task,0);
if (!access_ok(buf, 1000 * sizeof(struct process)))
{
printk("Invalid user space addressn");
}
if(copy_to_user((struct process *)buf, a, 1000*sizeof(struct process)))
{
printk("Efaultn");
return -EFAULT;
}
else
{
printk("%lun",sizeof(a));
return sizeof(a);
}
}
module_init(mymod_init);
module_exit(mymod_exit);
MODULE_LICENSE("GPL");
this is my test code:
struct process a[1000];
int brother_reg[100];
int main()
{
int i,j;
int x = syscall(336, &a);
printf("%dn",a[0].pid);
return 0;
}
I tried testing with access_ok() and found that the address is invalid. When I tested with strace, syscall_0x150() returned -1 (bad address).Linux is Linux 5.15.0-105-generic.
Any help will great.
赵宇彤 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.