增加Linux系统调用

gg297231604 2010-04-21 10:53:15
大家帮忙看下这个题:
修改已经编译成功的内核,为其增加新的系统调用
实现系统调用noexec,用它设置进程允许执行exec系统调用的次数。该系统调用能用来防止一些缓冲区溢出攻击,这些攻击最终通过exec产生一个shell界面。原型如下:
int noexec(int nexec);
参数nexec含义如下:
 nexec == 0, 执行exec将失败。
 nexec == n, n>0, 可以执行n次exec。
 nexec == -1, 执行exec的次数没有限制。
 nexec == 其它值, 不改变允许执行exec系统调用的次数。
系统调用的返回值是本次noexec调用之前允许exec系统调用的次数。
新创建的子进程允许执行exec的次数继承自父进程,只有超级用户能够通过noexec增加可执行exec的次数。
问题:
(1) 为了跟踪允许执行次数,是否要修改进程描述符task_struct?
(2) 为了保证继承语义,最早的进程应该如何初始化?
(3) fork系统调用是否要做修改?
(4) execve系统调用是否要修改?
我是个新手,请大家多多指教:)

...全文
912 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Kaiwii 2012-02-10
  • 打赏
  • 举报
回复
fork_out:
if (retval)
return ERR_PTR(retval);
/p->exec_count = current->exec_count;/*inserted by KaiwiiHo;deliever the value ofthe current task's nexec
to its child*/
return p;

如果我这样做的话,不行!不知道楼主是怎么解决的?
gg297231604 2010-05-01
  • 打赏
  • 举报
回复
感谢大家的回帖,有不妥之处请大家指教
gg297231604 2010-05-01
  • 打赏
  • 举报
回复
这个问题终于解决了,现在来结帖
(1)首先在task_struct中新增一个成员nexec,用来表示允许进程调用exec的次数
(2)最早进程exec初始化为-1
(3)在fork系统调用中,在函数copy_process里return p;之前添加
p->nexec = current->nexec; //将当前进程的nexec复制给子进程
(4)在do_execve函数中增加
if(!current->nexec)
goto out_ret;
if(current->nexec > 0)
current->nexec -- ;
测试方法:
主函数:
ret = syscall(321, 5);
printf("parent nexec = %d\n", ret);


if(-1 == (pid = fork()))
{
perror("fork");
exit(1);
}
if(pid == 0)
{
do_execute();
exit(1);
}
waitpid(pid, &status, 0);

do_execute函数:
void do_execute()
{
execl("/root/Documents/ex6/execute", "./execute", 0);
perror("faild execute");
}

文件execute.c:
int main(void)
{
printf("this is execute\n");
execl("/root/Documents/ex6/execute", "./execute", 0);
perror("faild execute");
return 0;
}

执行结果:


[root@localhost ex6]# ./noexec_test
parent nexec = -1
this is execute
this is execute
this is execute
this is execute
this is execute
faild execute: Success
在内核中增加的调试信息:
Apr 22 12:07:07 localhost kernel: when fork, current pid = 4510,nexec = -1, name: bash, parent = 4506
Apr 22 12:07:07 localhost kernel: when exec before changed,current pid = 4780,nexec = -1, name: bash, parent = 4510
Apr 22 12:07:07 localhost kernel: after changed,current pid = 4780,nexec = -1, name: bash, parent = 4510
Apr 22 12:07:07 localhost kernel: when fork, current pid = 4780,nexec = 5, name: noexec_test, parent = 4510
Apr 22 12:07:07 localhost kernel: when exec before changed,current pid = 4781,nexec = 5, name: noexec_test, parent = 4780
Apr 22 12:07:07 localhost kernel: after changed,current pid = 4781,nexec = 4, name: noexec_test, parent = 4780
Apr 22 12:07:07 localhost kernel: when exec before changed,current pid = 4781,nexec = 4, name: execute, parent = 4780
Apr 22 12:07:07 localhost kernel: after changed,current pid = 4781,nexec = 3, name: execute, parent = 4780
Apr 22 12:07:07 localhost kernel: when exec before changed,current pid = 4781,nexec = 3, name: execute, parent = 4780
Apr 22 12:07:07 localhost kernel: after changed,current pid = 4781,nexec = 2, name: execute, parent = 4780
Apr 22 12:07:07 localhost kernel: when exec before changed,current pid = 4781,nexec = 2, name: execute, parent = 4780
Apr 22 12:07:07 localhost kernel: after changed,current pid = 4781,nexec = 1, name: execute, parent = 4780
Apr 22 12:07:07 localhost kernel: when exec before changed,current pid = 4781,nexec = 1, name: execute, parent = 4780
Apr 22 12:07:07 localhost kernel: after changed,current pid = 4781,nexec = 0, name: execute, parent = 4780
Apr 22 12:07:07 localhost kernel: when exec before changed,current pid = 4781,nexec = 0, name: execute, parent = 4780
少逸 2010-04-26
  • 打赏
  • 举报
回复
帮顶一下!
yzx714 2010-04-25
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zmlovelx 的回复:]

task_struct中加入新域如n 标记允许exec系统调用的次数
加上noexec 为某process设置这个n
sys_execve 中
通过 current 中的n进行判断

init 进程配置n为一个默认值
fork系统调实现估计要改
主要应该在do_fork这里 task_struct 是如何生成的 把n也拷贝到子进程
[/Quote]up!~~
昵称2019~ 2010-04-25
  • 打赏
  • 举报
回复
学习嵌入式linux的高手们,来加入我们共嵌入式学习交流群“一切都好”群号:36711379。。。。。来这里一起交流
gg297231604 2010-04-25
  • 打赏
  • 举报
回复
nexec的初始值是-1
然后复制进程nexec是在copy_process() return p;前
p->nexec = current->nexec
而且上面将父进程nexec设为0后,子进程也阻止了exec的执行
那么子进程应该继承了父进程的值
gg297231604 2010-04-25
  • 打赏
  • 举报
回复
通过在内核中加入printk调试信息,能获得正确的nexec值
另一个问题是测试的问题,因为execve调用成功后不会返回,如何在同一进程中多次调用execve呢
我用线程似乎也解决不了问题,大家帮忙给给建议
帅得不敢出门 2010-04-24
  • 打赏
  • 举报
回复
在调用sys_noexec前current->nexec 是多少
fork中赋值代码正确不
gg297231604 2010-04-24
  • 打赏
  • 举报
回复
又改了一下:
ret = syscall(321, 0);
printf("parent nexec = %d\n", ret);

if(-1 == (pid = fork()))
{
perror("fork");
exit(1);
}
if(pid == 0)
{
ret = syscall(321, 5);
printf("before child nexec = %d\n", ret);
execl("/bin/ps", "ps", 0);
perror("Failed to execute command");
exit(1);
}

waitpid(pid, &status, 0);
运行如下:
]# ./noexec_test
parent nexec = 0
before child nexec = 0
PID TTY TIME CMD
3145 pts/0 00:00:00 bash
3978 pts/0 00:00:00 noexec_test
3979 pts/0 00:00:00 ps
系统调用no_exec总无法正确获得更改之前的nexec值
这是为什么呢?
gg297231604 2010-04-24
  • 打赏
  • 举报
回复
我在task_struct中加入了一个成员nexec
在INIT_TASK宏中将它初始化为-1
在fork和execve中也改了
新增了个系统调用,如下:
asmlinkage int sys_noexec(int nexec)
{
int ret = current->nexec;
if(ret >= -1)
current->nexec = nexec;
return ret;
}
写了个测试程序,如下:
int main(int argc, char *argv[])
{
int status, ret;
pid_t pid;

ret = syscall(321, 0);
printf("parent nexec = %d\n", ret);

if(-1 == (pid = fork()))
{
perror("fork");
exit(1);
}
if(pid == 0)
{
execl("/bin/ps", "ps", 0);
perror("Failed to execute command");
exit(1);
}

waitpid(pid, &status, 0);
return 0;
}
结果如下:
#./noexec_test
parent nexec = 0
Failed to execute command: Success
预期parent nexec应该为-1,但他却是0
帅得不敢出门 2010-04-22
  • 打赏
  • 举报
回复
task_struct中加入新域如n 标记允许exec系统调用的次数
加上noexec 为某process设置这个n
sys_execve 中
通过 current 中的n进行判断

init 进程配置n为一个默认值
fork系统调实现估计要改
主要应该在do_fork这里 task_struct 是如何生成的 把n也拷贝到子进程

gg297231604 2010-04-22
  • 打赏
  • 举报
回复
请大家发表点意见
gg297231604 2010-04-22
  • 打赏
  • 举报
回复
task_struct中有这两个成员
unsigned did_exec:1; //按POSIX要求设计的布尔量,区分进程是正在执行老程序代码,还是在执行execve装入的新代码
unsigned in_execve:1; /* Tell the LSMs that the process is doing an
* execve */
 本课程的主题是: 透析Linux系统编程    不同于市面上的课程,只会把核心主题放到函数的讲解,本课程的核心主题是 Linux系统编程的经验总结 ;    当你在系统编程中,调用一个系统调用来解决问题时,是否考虑过 该系统调用是否会对系统性能带来影响?是否还有最优的方式?    当你在系统编程过程中,遇到问题,是否只是检查代码逻辑,而不会去深入底层去查找问题 ?    本课程将一一解决系统编程带给你的难点,疑点?    比如控制文件IO章节,给出系统文件操作的默认行为,应用中如何修改这些行为,给出文件IO操作的最优方式;   比如系统调用,给出系统调用原理;系统调用的正确使用方式等   比如进程实现,结合底层,对比线程,深入理解两者;给出进程使用经验总结;   比如线程同步,不仅引出互斥锁 条件变量 自旋锁 读写锁使用方式,同时给出各个机制的应用场景 ;   比如 进程间通信,引出各个进程间通信的机制原理,给出各个进程间通信的应用场景;   比如 信号,给出信号在进程中信号处理处理函数的正确使用方式,给出在多线程中信号处理的正确方式;   比如 共享库,给出共享库的实现机制,给出共享库的正确使用方式;   同时 会讲解 系统安全问题 ; 可执行程序的静态布局和动态布局 ;灵活使用内存映射和虚拟内存;系统事件跟踪;   给出程序性能的调优思路;    丰富的项目实例讲解 ,提供宝贵的商业项目开发经验 ; 

4,436

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧