书写驱动必要安全性检测
2017-10-26 08:39
246 查看
驱动安全性意义
驱动直接操作的对象是硬件,运行在内核空间,如果驱动不可靠一旦出现问题,操作系统会出现异常,有很大几率造成系统崩溃。因此驱动安全性极为重要,在驱动代码中凡是有可能执行失败的函数,都需要对其返回值进行判断,成功后才可以进入下一个环节。最大限度减少出错的可能。示例代码(没有安全检测)
#include<linux/kernel.h> #include<linux/module.h> #include<linux/init.h> #include<linux/fs.h> #include<linux/cdev.h> #include<linux/kdev_t.h> #include<linux/slab.h> #define MY_DEVICE_NAME "linux26" static struct cdev *pcdev; static dev_t dev_no; //第一个设备号(包含主次) static int major=0; ssize_t my_device_open(struct inode *node, struct file *file) { printk("my device is open\n"); return 0; } ssize_t my_device_close(struct inode *node, struct file *file) { printk("my device is close\n"); return 0; } ssize_t my_device_read(struct file *fp, char __user *buf, size_t size, loff_t *loff) { printk("my device is read\n"); return 0; } ssize_t my_device_write(struct file *file, const char __user *buf, size_t size, loff_t *loff) { printk("my device is write\n"); return 0; } //文件结构体 struct file_operations my_fops={ .owner=THIS_MODULE, .open=my_device_open, .read=my_device_read, .write=my_device_write, .release=my_device_close, }; static int __init linux26_cdev_init(void) { //分配cdev空间 pcdev=cdev_alloc(); //动态分配设备号 次设备号0开始 数量为2个 名称为宏 alloc_chrdev_region(&dev_no,0,2,MY_DEVICE_NAME); //初始化结构体 cdev_init(pcdev,&my_fops); //注册驱动 cdev_add(pcdev,dev_no,2); //再去查注册文件很麻烦,这里打印主设备号方便创建节点 major=MAJOR(dev_no); printk("linux26 major is %d\n",major); return 0; } static void __exit linux26_cdev_exit(void) { cdev_del(pcdev); unregister_chrdev_region(dev_no,2); kfree(pcdev); } module_init(linux26_cdev_init); module_exit(linux26_cdev_exit); MODULE_LICENSE("GPL");
修改后的代码(加入安全检测)
#include<linux/kernel.h> #include<linux/module.h> #include<linux/init.h> #include<linux/fs.h> #include<linux/cdev.h> #include<linux/kdev_t.h> #include<linux/slab.h> #define MY_DEVICE_NAME "linux26" static struct cdev *pcdev; static dev_t dev_no; //第一个设备号(包含主次) static int major=0; ssize_t my_device_open(struct inode *node, struct file *file) { printk("my device is open\n"); return 0; } ssize_t my_device_close(struct inode *node, struct file *file) { printk("my device is close\n"); return 0; } ssize_t my_device_read(struct file *fp, char __user *buf, size_t size, loff_t *loff) { printk("my device is read\n"); return 0; } ssize_t my_device_write(struct file *file, const char __user *buf, size_t size, loff_t *loff) { printk("my device is write\n"); return 0; } //文件结构体 struct file_operations my_fops={ .owner=THIS_MODULE, .open=my_device_open, .read=my_device_read, .write=my_device_write, .release=my_device_close, }; static int __init linux26_cdev_init(void) { int ret =-1; //分配cdev空间 pcdev=cdev_alloc(); if(pcdev==NULL) { printk("cdev alloc is fail\n"); ret=-ENOMEM; //分配内存失败 当然写-1也没有关系 return ret; } //动态分配设备号 次设备号0开始 数量为2个 名称为宏 ret=alloc_chrdev_region(&dev_no,0,2,MY_DEVICE_NAME); if(ret<0) { //释放前面成功的资源 否则造成内存泄漏 kfree(pcdev); //释放结构体空间 printk("alloc chrdev is fail\n"); return ret; } //初始化结构体 cdev_init(pcdev,&my_fops); //cdev_init没有返回值不用管 //注册驱动 ret=cdev_add(pcdev,dev_no,2); if(ret<0) { //释放前面申请的资源 否则会造成内存泄漏 unregister_chrdev_region(dev_no,2); //释放设备号 kfree(pcdev); //释放结构体空间 printk("cdev_add is fail\n"); return ret; } //再去查注册文件很麻烦,这里打印主设备号方便创建节点 major=MAJOR(dev_no); printk("linux26 major is %d\n",major); return 0; } static void __exit linux26_cdev_exit(void) { cdev_del(pcdev); unregister_chrdev_region(dev_no,2); kfree(pcdev); } module_init(linux26_cdev_init); module_exit(linux26_cdev_exit); MODULE_LICENSE("GPL");
如果前面注册的太多,每个需要判断的函数里面释放的资源就比较多,代码重复性较高,造成代码长度大大加长,阅读性变差。可以采取一些方法进行改变可以参考下面的例子。
最终版本(相对完善)
#include<linux/kernel.h> #include<linux/module.h> #include<linux/init.h> #include<linux/fs.h> #include<linux/cdev.h> #include<linux/kdev_t.h> #include<linux/slab.h> #define MY_DEVICE_NAME "linux26" static struct cdev *pcdev; static dev_t dev_no; //第一个设备号(包含主次) static int major=0; ssize_t my_device_open(struct inode *node, struct file *file) { printk("my device is open\n"); return 0; } ssize_t my_device_close(struct inode *node, struct file *file) { printk("my device is close\n"); return 0; } ssize_t my_device_read(struct file *fp, char __user *buf, size_t size, loff_t *loff) { printk("my device is read\n"); return 0; } ssize_t my_device_write(struct file *file, const char __user *buf, size_t size, loff_t *loff) { printk("my device is write\n"); return 0; } //文件结构体 struct file_operations my_fops={ .owner=THIS_MODULE, .open=my_device_open, .read=my_device_read, .write=my_device_write, .release=my_device_close, }; static int __init linux26_cdev_init(void) { int ret =-1; //分配cdev空间 pcdev=cdev_alloc(); if(pcdev==NULL) { printk("cdev alloc is fail\n"); ret=-ENOMEM; goto err_cdev_alloc; } //动态分配设备号 次设备号0开始 数量为2个 名称为宏 ret=alloc_chrdev_region(&dev_no,0,2,MY_DEVICE_NAME); if(ret<0) { printk("alloc chrdev is fail\n"); ret=-1; goto err_alloc_chrdev_region; } //初始化结构体 //cdev_init没有返回值不用管 cdev_init(pcdev,&my_fops); //注册驱动 ret=cdev_add(pcdev,dev_no,2); if(ret<0) { printk("cdev_add is fail\n"); ret=-1; goto err_cdev_add; } //再去查注册文件很麻烦,这里打印主设备号方便创建节点 major=MAJOR(dev_no); printk("linux26 major is %d\n",major); return 0; //非常重要 如果没有这个返回值,即使前面全部执行成功,也会执行后面的代码造成前功尽弃 err_cdev_add: //释放前面申请的资源 否则会造成内存泄漏 unregister_chrdev_region(dev_no,2); //释放设备号 err_alloc_chrdev_region: //释放前面成功的资源 否则造成内存泄漏 kfree(pcdev); //释放结构体空间 err_cdev_alloc: return ret; //分配内存失败 当然写-1也没有关系 } static void __exit linux26_cdev_exit(void) { //释放资源函数一般都能成功,很少有返回值,这里没有返回值检查 cdev_del(pcdev); unregister_chrdev_region(dev_no,2); kfree(pcdev); } module_init(linux26_cdev_init); module_exit(linux26_cdev_exit); MODULE_LICENSE("GPL");
相关文章推荐
- 基于VisualC++2010开发Windows7杀毒应用程序范例(3)---检测所有驱动程序,并启动,暂停,终止驱动
- S3c6410 linux内核移植(8)---添加adc驱动、电池电量检测之原理
- 检测网站速度和安全性的方法
- asp.net 后台录入时,检测安全性的两句代码
- 驱动检测
- BackTrack 4 OAT软件包检测ORACLE服务器安全性!
- sqlserver,driver,mysql等的驱动书写
- 书写NDIS过滤钩子驱动实现ip包过滤
- driver verifier检测驱动死锁
- 关于HMC5883L驱动书写及调试的总结
- DCL(双检测锁定-Double Checked Lock)安全性分析(转)
- 书写NDIS过滤钩子驱动实现ip包过滤
- Linux驱动编程 step-by-step (六) 用户地址检测 简单模块调试 以及一些杂项
- SD/MMC驱动2(SD检测)
- 如何安全设定和检测你的密码安全性? 推荐
- Linux驱动开发学习的一些必要步骤
- S3c6410 linux内核移植(8)---添加adc驱动、电池电量检测之原理
- 方维购物分享系统怎么样,方维系统安全性检测
- 推荐几个检测网站信息的平台(安全性、访问速度、漏洞)
- android电池充电以及电量检测驱动分析