Как дать root разрешение модулю? - PullRequest
2 голосов
/ 10 апреля 2020

Я работаю над модулем, который, когда я звоню echo "hello" > /dev/filename, я получаю bash: /dev/filename: permission denied. Чтобы получить разрешение, я должен позвонить sudo chmod 666 /dev/filename, и тогда эхо может работать. Как я могу сделать так, чтобы у моего модуля было разрешение root, чтобы мне не нужно было звонить sudo chmod 666?

ED: Это модуль символов

Ответы [ 3 ]

0 голосов
/ 11 апреля 2020

Вы можете определить разрешение вашего модуля при инициализации, благодаря полю mode из структуры miscdevice (см. здесь ):

#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);
0 голосов
/ 11 апреля 2020

мой модуль имеет разрешение root

Модуль ядра работает на уровне ядра - у него есть все возможные разрешения на что-либо с чем-либо.

  1. Вы можете изменить разрешение символьного устройства, что можно сделать, например, с помощью chmod.
  2. Или, в качестве альтернативы, увеличьте разрешение процесса, выполняющего запись в файл символьного устройства, что можно сделать, например, запустив оболочку с root permisions sudo sh -c 'echo hello > /dev/filename' или перенаправив данные в sudo tee .
0 голосов
/ 11 апреля 2020

Предположим, 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;
}
...