����Linux�Ż�
Linux����

linux�ں�ģ���ǿ��ɾ��-����rmmod����disk sleep����

����ʱ��:2016-12-14 09:47:33��Դ:dog250����:Bomb250
һ.���⣺
ǰЩ�����ڹ���������һ���ļ�����rmmodһ��ģ���ʱ����ģ���exit�����������ˣ�rmmod����ɱҲɱ��������Զ��������������Ѿ���D(disk sleep)״̬�ˣ��������Ϊ�������Ҳ����������ʵ�����Խ�������΢��Ͼ��ʱ�򻻻����ӣ��������˽���취��
 
��.������
���廹��ϵ���ˣ���Ȼ�����ں��г������⣬������Ҫ���ں���Ѱ�Ұ취��������������ǰ���Ƕ��ں�ж��ģ��ľ�ȷ���⣬���̶�����͸�ˣ������Ҳ���ԭ����ԭ���ҵ��ˣ��취�϶����еģ� (��Ҳ���Ҵӹ�˾ѧϰ��������Ҫ�Ķ�����)�� �Ұ������ԭ�򣬲鵽��rmmod���յ��õĴ��룺
asmlinkage long sys_delete_module(const char __user *name_user, unsigned int flags)  
{  
...  
if (!list_empty(&mod->modules_which_use_me)) { //0.�������ģ��������ģ�飬��ɾ��  
/* Other modules depend on us: get rid of them first. */  
ret = -EWOULDBLOCK;  
goto out;  
}  
...  
if (mod->state != MODULE_STATE_LIVE) { //1.���ģ�鲻��LIVE״̬����ô���޷�������ȥ�ˣ��õ��Ľ����busy  
...  
ret = -EBUSY;  
goto out;  
}  
...  
if (!forced && module_refcount(mod) != 0) //2.������ü�������0����ȴ���Ϊ0  
wait_for_zero_refcount(mod);  
up(&module_mutex);  
mod->exit(); //3.�����������������ˣ��Ǿ��޷�������  
down(&module_mutex);  
free_module(mod);  
... 
}
����ע����4�����ֱ�������£�
���0��������ģ������Ҫж�ص�ģ�顣ģ��a�Ƿ�����ģ��b�������ģ��a���ص�ʱ�����resolve_symbol�������ģ��a��symbol��ģ��b�У�������
���1��ֻ��LIVE״̬��ģ����ܱ�ж�ء�
���2�����ü�����������ģ������ں˱������õ�ʱ��Ϊ0��Ҫж�ؾ�Ҫ�ȴ����Dz�����Ϊֹ��
���3���������Ƚ��ձ飬��Ϊģ����һ��ʹ�ù�����oom������������ģ��oom����ģ�鱾��д�IJ�����bug�Ӷ��ƻ���һЩ���ݽṹ����ô�������exit����������������rmmod�����أ�
 
��.����һ�£�
������3����һ��������ģ�⣺
static DECLARE_COMPLETION(test_completion);  
int init_module()  
{  
return 0;  
}  
void cleanup_module( )  
{  
wait_for_completion(&test_completion);  
}  
MODULE_LICENSE("GPL");
����Ϊtest.ko��������rmmod test��ʱ���������rmmod���������ˣ�����Ȼ��cleanup_module�������⣬�����дһ��ģ����ж�������ڱ���ģ��֮ǰ������Ҫ��/proc/kallsym���ҵ��������У�
f88de380 d __this_module��[XXXX�޷�ж�ص�ģ������]
������Ϊmodules����û�б�����������������Ļ�����ȷ�ķ�ʽӦ���DZ�������������ȶ�ģ�����Ƶġ�
���µ�ģ��������Ժ�����ģ��Ϳ��Ա�rmmod�ˣ�
void force(void)  
{  
}  
int __init rm_init(void)  
{  
struct module *mod = (struct module*)0xf88de380;  
int i;  
int o=0;  
mod->state = MODULE_STATE_LIVE; //Ϊ��ж���ܽ�����ȥ��Ҳ���DZܿ����1����ģ���״̬�ı�ΪLIVE  
mod->exit = force;��//������ģ���exit�������޷����أ����滻mod��exit���ٴε���rmmod��ʱ�����õ�sys_delete_module��������� exit�ص��������µ�exit��Ȼ�����������ɹ����أ���������free��module  
for (i = 0; i < NR_CPUS; i++) { //�����ü�����0  
mod->ref[i].count = *(local_t *)&o;  
}  
return 0;  
}  
void __exit rm_exit(void)  
{  
}  
module_init(rm_init);  
module_exit(rm_exit);  
MODULE_LICENSE("GPL");
Ȼ���������ģ���ǰ���ģ��Ϳ���ж���ˡ�
 
��.�������һЩ���ͣ�
������ģ�鵼�µ��޷�ж�ص����⣬������һ�ַ����ʽ�������ڱ��module��complete�����completion�����completion��Ȼ���޷�ֱ�ӵõ��ģ�����Ҫͨ��/proc/kallsyms�õ����completion�ĵ�ַ��Ȼ��ǿ��ת����completion���������
int __init rm_init(void)  
{  
complete((struct completion *)0xf88de36c);  
return 0;  
}  
void __exit rm_exit(void)  
{  
}  
module_init(rm_init);  
module_exit(rm_exit);  
MODULE_LICENSE("GPL");
��Ȼ���ַ�ʽ����õ��ˣ��������ʹ���滻exit�ķ�ʽ���ᵼ��ǰ����Ǹ�������rmmod�޷��˳�������������±�д��ģ���е���try_to_wake_up������Ȼ����Ҳ�Dz��׵��ģ���Ϊ��������wait_for_completion����wait_for_completion�д����������Ѿ����滻exit�ص�����������ж�ص�ģ�����ݣ����磺
spin_unlock_irq(&x->wait.lock);
schedule();
spin_lock_irq(&x->wait.lock);
����x�����Ǹ�ģ������ģ���Ȼx�Ѿ�û����(ʹ���滻exit�ķ�ʽ�Ѿ��ɹ�ж����ģ�飬ģ�鱻free��x��Ȼ�Ͳ���������)���ոձ��������е�rmmod�ͻ�oops�����Dz���������һ�����̵�oopsһ����û������ģ���˻��ǿ��Ըɵ����ģ�����oopsһ�㲻���ƻ��������ں����ݣ�һ�㶼�����������Ѿ���free��ָ�������(��Ȼ����Ŀ�����Σ�����Ŷ...)�� ��Ȼ֪����Щrmmod����������˯�����棬��ô����ֻ��Ҫǿ�ƻ������ǾͿ����ˣ�����˵�����Ѻ�oops����ô�죿���ں˴�����������������������˿������µĴ��룺
int (*try)(task_t * p, unsigned int state, int sync);  
int __init rm_init(void){  
struct task_struct *tsk = find_task_by_pid(28792); //28792Ϊһ��������rmmod���̣����ģ��ʹ���������滻exit�ķ�ʽ�Ѿ�������rmmodж���ˣ�Ȼ����һ�ε��Ǹ�rmmod��Ȼ���������û��˯��ȥ�������ˡ�  
try=0xc011a460;  
(*try)(tsk, TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE, 0); //���ǻ�����������������֮���ʲô�����ɣ�  
return 0;  
}  
void __exit rm_exit(void){  
}  
module_init(rm_init);  
module_exit(rm_exit);  
MODULE_LICENSE("GPL");
Ȼ����ps -eһ�£�����û���Ǹ�rmmod�����ˡ�һ��[State:  D (disk sleep)]�Ľ��������군�ˡ�
���ϴ����������Ӳ����ĵ�ַ�Լ����̺ţ������Ĵ���Ӧ��ʹ�ò�����������Щ��Ϣ���ͻ�ȽϷ����ˣ�
��Ȼģ��ṹ�������õ������������ֶξͿ��Ա����⸳ֵ�����������������¸�ֵ�����Ȼ�ں˿ռ䶼�����ˣ������������žͲ��Ǹ��������ˣ�����û��procfs��kallsym��Ҳһ���ܸ㶨����Ϊ���ܿ��������ڴ棡
 
��.��ɾ����
���ǿ������Լ���ģ���ʼ����ʱ�������ü������ó�һ���Ƚϴ��������������һ�±��ģ��ṹ���ֶΣ����α�rmmod��Ȼ������Ҳ������дһ��ģ�����Щ�ֶ����û�ȥ���򵥵�ʹ��������ʽ�Ϳ��Ըɵ���ķ�ɾ��ģ�飬����һ��ì��ܵ����⣬�ؼ��ǣ�������ӵ��rootȨ�ޡ�
 
��.�ܽ᣺
���붼�õ����ˣ����̻������������̶����ˣ����¶�λ�������������ⶼ��λ�ˣ����ܽ��������ֻҪû����Ϊ���أ���ʵ���κμ������ⶼ���ܽ���ģ������Ҵӹ�˾ѧϰ��������Ҫ�Ķ�����������ν�IJ�����ֻ�ǹ淶�ϵĹ涨����˵��Ȼ��������˻�����Ĵ�����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״̬�Ľ��̻��ǿ����õġ�
 
�������ø��µ�ַ��//m.ajphoenix.com/linux/26881.html