0

I am adding an IOctl call from the native OpenGL framework on an Android device such that I can log frame information in the kernel via a tracing kernel module. In my kernel module I am creating the cdev for the IOctl calls but am having the problem that my dev's default permissions are 6000 and since the user-land IOctl calls are coming from a non-root process the open call is unable to open the file decriptor required for the ioctl call.

My cdev approach is very much standard and as follows (note devnode is an attempt to fix permissions, see this).

static dev_t dev;
static struct cdev c_dev;
static struct class *cl;

static char *device_node(struct device *dev, umode_t *mode) 
{ 
    if(!mode)
        return NULL;
    *mode=0666;
    return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
}

static int IOctlInit(void)
{
    int ret;
    struct device *dev_ret;

    if((ret = alloc_chrdev_region(&dev, FIRST_MINOR, MINOR_CNT, EGL_SYSLOGGER_NAME)))
        return ret;

    cdev_init(&c_dev, &syslog_EGL_fops);

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

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

    cl->devnode = device_node;

    if(IS_ERR(dev_ret = device_create(cl, NULL, dev, NULL, EGL_SYSLOGGER_NAME)))
    {
        class_destroy(cl);
        cdev_del(&c_dev);
        unregister_chrdev_region(dev, MINOR_CNT);
        return PTR_ERR(cl);
    }

    return 0;
}

And similarly using a misc dev with .mode=0666 I have the same problem

static struct miscdevice misc_dev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = EGL_SYSLOGGER_NAME,
    .fops = &syslog_EGL_fops,
    /** .mode = S_IRWXUGO, */
    .mode = 0666,
};

static `enter code here`int IOctlInit(void)
{
    int ret;

    ret = misc_register(&misc_dev);
    if(ret)
        printk("Unable to register EGL IOctl misc dev\n");
    printk("Misc dev registered\n");

    return 0;
}

Both approaches work once running chmod 666 /dev/$EGL_SYSLOGGER_NAME but I am hoping to find a solution that does not need this intervention. According to this post the misc dev approach should solve my problem but I have not had any success.

I am not sure what I have missed and would greatly appreciate some tips.

Cheers

Alex Hoffmann
  • 355
  • 4
  • 20
  • 2
    I think the 'group' and 'other' permissions get masked out when the kernel creates the file in /dev. On "normal" Linux userland, "udev" rules can change the permissions and ownership of the device file. I'm not sure what the equivalent is in the Android userland, but the settings are probably in some .rc file somewhere. – Ian Abbott Mar 04 '20 at 14:28
  • I know that I can create udev rules but if I have to add udev rules I may as well just add a chmod, was trying to avoid the need for any sort of extra step :( – Alex Hoffmann Mar 04 '20 at 14:50
  • 1
    I think the most you can do with the devnode handler is provide information to the userspace uevent handler about the desired name and permissions via the DEVNAME=, DEVMODE= uevent variables (also DEVUID= and DEVGID= if using the "device type" devnode handler), but it is up to the userspace uevent handler to parse and use that information. For Android, that is the responsibility of the "ueventd" daemon. – Ian Abbott Mar 04 '20 at 16:34
  • 1
    By the way, presumably one of those `return PTR_ERR(cl);` lines in your code should be `return PTR_ERR(dev_ret);`. – Ian Abbott Mar 04 '20 at 16:35
  • Thanks for the insight @IanAbbott. Shame a workaround doesn't exist – Alex Hoffmann Mar 04 '20 at 16:52

0 Answers0