zoukankan      html  css  js  c++  java
  • 内核空间可以直接访问应用层空间地址

    在linux驱动编写过程中, 如果要实现内核和应用的数据传递通常用copy_from/to_user()函数, 如果如果直接用mmecpy来传递, 可能会导致内核安全漏洞! 内核可以直接操作应用层的地址空间。

    以下是个例子:

    ==========================内核 ko部分=======================

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/miscdevice.h>
    #include <linux/fs.h>

    #define DEVNAME "wdt"

    struct wdt_regs {
        u32 wtcon;
        u32 wtdat;
        u32 wtcnt;
        u32 wtclrint;
    };

    enum {
        START = 100,
        STOP = 101,
        COUNT = 102,
        RESET = 103,
        INT = 104,
    };

    static struct wdt_info {
        struct miscdevice dev;
        struct file_operations fops;
        struct wdt_regs *regs;
    } info;

    static long wdt_ioctl(struct file *fp, unsigned int cmd, unsigned long data)
    {
        struct wdt_regs *p = NULL;
        switch (cmd) {
            case START:
            printk("int data = %d ", data);
            break;
        case STOP:
            p = (struct wdt_regs *)data;
            printk("addr=%p p->wtcon=%d ", p, p->wtcon);
            break;
        case COUNT:
            break;
        case RESET:
             break;
        case INT:
            break;
        }
    }

    static int wdt_init(void)
    {
        printk("%s ", __FUNCTION__);
        info.dev.minor = MISC_DYNAMIC_MINOR;
        info.dev.name = DEVNAME;
        info.dev.fops = &info.fops;
        info.fops.unlocked_ioctl = wdt_ioctl;
        if (misc_register(&info.dev) < 0) {
            printk("misc_register failed ");
            goto err_misc_register;
        }
        return 0;
    err_misc_register:
        return -1;
    }

    static void wdt_exit(void)
    {
        printk("%s ", __FUNCTION__);
        misc_deregister(&info.dev);
    }

    module_init(wdt_init);
    module_exit(wdt_exit);
    MODULE_LICENSE("GPL");

    ==============================应用层部分=========================

    #include <stdio.h>
    #include <fcntl.h>

    typedef unsigned int u32;

    struct wdt_regs {
        u32 wtcon;
        u32 wtdat;
        u32 wtcnt;
        u32 wtclrint;
    }data;

    enum {
        START = 100,
        STOP = 101,
        COUNT = 102,
        RESET = 103,
        INT = 104,
    };

    int main()
    {
        int tt = 111;
        int fd = open("/dev/wdt", O_RDWR);
        if (fd < 0) {
            perror("open");
            goto err_open;
        }
        data.wtcon = 1001;
        ioctl(fd, START, tt);
        printf("p=%p ", &data);
        ioctl(fd, STOP, &data);

        close(fd);

        return 0;

    err_open:
        return -1;
    }

    ==================运行结果=========================

    root@ubuntu:~/Desktop/test-ioctl# insmod test.ko

    root@ubuntu:~/Desktop/test-ioctl# ./a.out
    p=0x601070
    root@ubuntu:~/Desktop/test-ioctl# dmesg
    [322937.889964] int data = 111
    [322937.890010] addr=0000000000601070 p->wtcon=1001
    root@ubuntu:~/Desktop/test-ioctl#

    从以上的应用层打印地址和内核的打印地址信息看, 两个值是相等的!

  • 相关阅读:
    hdu 2275数据结构水题
    咨询工具、模型、方法论学习笔记 序
    DevExpress DXperience XtraTreeview 如何获取当前光标所在位置的 Node
    Delphi 各个编译版本的开关值
    把对象序列化到文件中和从文件中反序列化的管理类
    Advantech 硬件控制卡的 c# 接口函数
    Delphi 中的 TTimer 和 .NET Framework 中的 Timer 的计时周期研究
    C#设计模式编程之抽象工厂模式新解
    敏捷开发
    关于HTML静态页面(含自动分页)生成的可行性方案
  • 原文地址:https://www.cnblogs.com/newjiang/p/10996379.html
Copyright © 2011-2022 走看看