注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

我的博客

笨笨猫

 
 
 

日志

 
 

Linux内核模块的强制删除  

2011-11-30 15:33:19|  分类: MeeGo |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Linux内核模块的强制删除-结束rmmod这类disk sleep进程

[日期:2011-05-29] 来源:Linux社区  作者:dog250

其中x就是那个模块里面的,既然x已经没有了(使用替换exit的方式已经成功卸载了模块,模块被free,x当然就不复存在了),刚刚被唤醒运行的rmmod就会oops,但是不管怎样,一个进程的oops一般是没有问题的,因此还是可以干掉它的,这种oops一般不会破坏其它的内核数据,一般都是由于引用已经被free的指针引起的(当然还真的可能有危险情况哦...)。 既然知道这些rmmod都是阻塞在睡眠里面,那么我们只需要强制唤醒它们就可以了,至于说被唤醒后oops了怎么办?由内核处理啦,或者听天由命!因此考虑以下的代码:


  1. int (*try)(task_t * p, unsigned int state, int sync);   
  2. int __init rm_init(void){   
  3.         struct task_struct *tsk = find_task_by_pid(28792); //28792为一个阻塞的rmmod进程,这个模块使用上述的替换exit的方式已经被重新rmmod卸载了,然而第一次的那个rmmod仍然阻塞在哪里,没有睡再去唤醒它了。   
  4.         try=0xc011a460;   
  5.         (*try)(tsk, TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE, 0); //我们唤醒它,至于它醒了之后干什么,随便吧!   
  6.         return 0;   
  7. }   
  8. void __exit rm_exit(void){   
  9. }   
  10. module_init(rm_init);   
  11. module_exit(rm_exit);   
  12. MODULE_LICENSE("GPL");  

然后再ps -e一下,基本没有那个rmmod进程了。一个[State:  D (disk sleep)]的进程这样完蛋了。
     以上代码基本都是硬编码的地址以及进程号,真正的代码应该使用参数来传递这些信息,就会比较方便了!
     既然模块结构都可以拿到,它的任意字段就可以被任意赋值,哪里出了问题就重新赋值哪里!既然内核空间都进入了,导不导出符号就不是根本问题了,就算没有procfs的kallsym,也一样能搞定,因为你能控制整个内存!

五.防删除:
我们可以在自己的模块初始化的时候将其引用计数设置成一个比较大的数,或者设置一下别的模块结构体字段,防治被rmmod,然而别人也可以再写一个模块把这些字段设置回去,简单的使用上述方式就可以干掉你的防删除模块,这是一个矛与盾的问题,关键是,别让人拥有root权限。

六.总结:
代码都拿到手了,流程还看不懂吗?流程都懂了,还怕定位不到问题吗?问题都定位了,还能解决不了吗?只要没有人为因素,事实上任何技术问题都是能解决的( 这是我从公司学习到的最重要的东西 ),所谓的不可能只是规范上的规定或者说既然你误操作了或者你的代码有bug,与其说去按照上述方式搞定它,还不如不搞定它,而是改正你自己的错误!

     解决模块由于阻塞而无法删除问题有下面的过程:
1.写一个模块替换exit函数,且设置引用计数为0,状态为LIVE,然后rmmod;
2.强制try_to_wake_up那个rmmod进程,注意不能使用wake_up,因为队列可能已经不在了,而应该直接唤醒task_struct;
3.听天由命!

附:内核缺页
在do_page_fault中,如果缺页发生在内核空间,最终OOPS的话,会调用die:
die("Oops", regs, error_code);
在die中,如果没有处在中断以及没有设置panic-on-oops的话,最终将以SIGSEGV退出当前进程:
if (in_interrupt())
    panic("Fatal exception in interrupt");
if (panic_on_oops) {
    printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
    set_cu
rrent_state(TASK_UNINTERRUPTIBLE);
    schedule_timeout(5 * HZ);
    panic("Fatal exception");
}
do_exit(SIGSEGV);
这样,如果唤醒睡眠在模块exit中的rmmod,显然在被唤醒之后,检测变量会导致缺页(由于变量已经被free了),因此会进入die("Oops"...),最终退出rmmod进程,这个也是很合理的哦!因此上述的清理D状态的进程还是可以用的。
  评论这张
 
阅读(1085)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017