如何授予模块根权限?

时间:2020-04-10 17:43:33

标签: linux-kernel linux-device-driver

我正在开发一个模块,当我调用echo "hello" > /dev/filename时我得到bash: /dev/filename: permission denied。要获得我的许可,我必须致电sudo chmod 666 /dev/filename,然后echo才能起作用。如何使我的模块具有root权限,所以不必调用sudo chmod 666

ED:这是一个字符模块

3 个答案:

答案 0 :(得分:0)

由于mode结构中的miscdevice字段(请参见here),因此您可以在初始化时定义模块权限:

#include <linux/miscdevice.h>

static struct miscdevice my_module_cnf = {
    /*some other fields*/,
    .mode = 0666,
};

static int __init my_module_init(void)
{
    int ret = misc_register(&my_module_cnf);
    if (ret < 0) {
        printk(KERN_ERR "Unable to register my module");
        return ret;
    }

    return 0;
}

static void __exit my_module_exit(void)
{
    misc_deregister(&my_module_cnf);
}

module_init(my_module_init);
module_exit(my_module_exit);

答案 1 :(得分:0)

我的模块具有root权限

内核模块在内核级别运行-它具有所有可能执行任何操作的所有权限。

  1. 您可以更改字符设备的权限,例如,可以使用chmod进行更改。
  2. 或者提高正在写入字符设备文件的进程的权限,例如,可以通过根权限sudo sh -c 'echo hello > /dev/filename'运行shell或将数据通过管道传输到sudo tee来实现。

答案 2 :(得分:-1)

假设您要写入的file是字符设备。您可以通过覆盖下面为设备创建的类的dev_uevent以编程方式进行操作。

static struct class *cl;

int my_uevent(struct device *dev, struct kobj_uevent_env *env)
{
    add_uevent_var(env, "DEVMODE=%#o", 0666);
    return 0;
}

.....

int my_init(void)
{
    int ret;
    struct device *dev_ret = NULL;

    if((ret = alloc_chrdev_region(&dev, FIRST_MINOR, MINOR_CNT, "char_dev")) < 0)
    {
        return ret;
    }
    printk("Major Nr: %d\n", MAJOR(dev));

    cdev_init(&c_dev, &fops);

    if((ret = cdev_add(&c_dev, dev, MINOR_CNT)) < 0)
    {
        unregister_chrdev_region(dev, MINOR_CNT);
        return ret;
    }

    if(IS_ERR(cl = class_create(THIS_MODULE, "chardrv")))
    {
        cdev_del(&c_dev);
        unregister_chrdev_region(dev, MINOR_CNT);
        return PTR_ERR(cl);
    }

    cl->dev_uevent = my_uevent; // <-- overwrite dev_uevent here

    if(IS_ERR(dev_ret = device_create(cl, NULL, dev, NULL, "mychar%d", 0)))
    {
        class_destroy(cl);
        cdev_del(&c_dev);
        unregister_chrdev_region(dev, MINOR_CNT);
        return PTR_ERR(dev_ret);
    }
    return 0;
}