向 Linux 添加一个需要 root 权限的新系统调用
Adding a new system call to Linux that requires root privileges
我正在尝试向 linux 内核(版本:3.10.91)添加一个系统调用,需要 运行.
的根权限
你可以在下面看到我的尝试:
#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/sched.h>
#include <asm/current.h>
#include <asm/errno.h>
asmlinkage long sys_set_casper(pid_t pid, int value)
{
struct task_struct *process;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
//valid values are 0,1,2,3
if (value != 0 && value != 1 && value != 2 && value != 3 )
return -EINVAL;
process = find_task_by_vpid(pid);
if (process == NULL)
return -ESRCH;
//modify the casper field accordingly
process->casper = value;
return 0;
}
Casper 只是我添加的任务描述符。基本上,当 casper 值为 1 时,我希望进程被隐藏(对 ps、pstree、top 等不可见)。内核重新编译就很好(我也做了必要的更改base.c 等等)。
我尝试使用以下代码测试我的系统调用,test.c:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define NR_set_casper 351
int main(int argc, char **argv)
{
long y;
printf("PID of current process: %d\n\n", getpid());
printf("Call set_casper system call to set flag 1\n");
y = syscall(NR_set_casper, getpid(), 0);
printf("Return value of set_casper system call: %ld\n", y);
if (y < 0)
{
printf("set_casper system call failed. Run with sudo\n");
return EXIT_FAILURE;
}
return 0;
}
我编译和运行如下:
gcc test.c
sudo ./a.out
输出为:
PID of current process: 3852
Call set_casper system call to set flag 1
Return value of set_casper system call: -1
set_casper system call failed. Run with sudo
奇怪的是,即使删除了 sudo 控制线:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
重新编译内核,还是一样的错误
基本上,为什么我的 sys_set_casper 函数 returns -1 ?
编辑
我添加了这个:351 i386 set_casper sys_set_casper 到
arch/x86/syscalls$ gedit syscall_32.tbl
但是,我的系统是 64 位的。这可能是问题所在吗?
正如其他人在评论中所说,问题是我根本没有调用系统调用。我只是将我的调用添加到 64 位系统调用 table 并再次尝试一切,它成功了。
我正在尝试向 linux 内核(版本:3.10.91)添加一个系统调用,需要 运行.
的根权限你可以在下面看到我的尝试:
#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/sched.h>
#include <asm/current.h>
#include <asm/errno.h>
asmlinkage long sys_set_casper(pid_t pid, int value)
{
struct task_struct *process;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
//valid values are 0,1,2,3
if (value != 0 && value != 1 && value != 2 && value != 3 )
return -EINVAL;
process = find_task_by_vpid(pid);
if (process == NULL)
return -ESRCH;
//modify the casper field accordingly
process->casper = value;
return 0;
}
Casper 只是我添加的任务描述符。基本上,当 casper 值为 1 时,我希望进程被隐藏(对 ps、pstree、top 等不可见)。内核重新编译就很好(我也做了必要的更改base.c 等等)。
我尝试使用以下代码测试我的系统调用,test.c:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define NR_set_casper 351
int main(int argc, char **argv)
{
long y;
printf("PID of current process: %d\n\n", getpid());
printf("Call set_casper system call to set flag 1\n");
y = syscall(NR_set_casper, getpid(), 0);
printf("Return value of set_casper system call: %ld\n", y);
if (y < 0)
{
printf("set_casper system call failed. Run with sudo\n");
return EXIT_FAILURE;
}
return 0;
}
我编译和运行如下:
gcc test.c
sudo ./a.out
输出为:
PID of current process: 3852
Call set_casper system call to set flag 1
Return value of set_casper system call: -1
set_casper system call failed. Run with sudo
奇怪的是,即使删除了 sudo 控制线:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
重新编译内核,还是一样的错误
基本上,为什么我的 sys_set_casper 函数 returns -1 ?
编辑
我添加了这个:351 i386 set_casper sys_set_casper 到 arch/x86/syscalls$ gedit syscall_32.tbl
但是,我的系统是 64 位的。这可能是问题所在吗?
正如其他人在评论中所说,问题是我根本没有调用系统调用。我只是将我的调用添加到 64 位系统调用 table 并再次尝试一切,它成功了。