LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   How to access a device from linux daemon (http://www.linuxquestions.org/questions/programming-9/how-to-access-a-device-from-linux-daemon-4175428143/)

xhpohanka 09-20-2012 01:33 AM

How to access a device from linux daemon
 
I'm writing a linux daemon that should control a hardware device presented on a filesystem as /dev/mydevice. The owner of the file is root and group is set to mydaemon. Chmod 660.

The daemon is started as root, but then drops the user and changes it to mydaemon
Code:

if (getuid() == 0 || geteuid() == 0) {
    struct passwd *pw = getpwnam("mydaemon");
    if (pw)
        setuid(pw->pw_uid);
}

I expected that now I should have access to a files belonging to mydaemon group, but call to
Code:

open("/dev/mydevice", "O_RDWR");
still ends with permission denied error.

Running the same code as mydaemon user without daemonizing works fine - so mydaemon really have access to device files.

What I'm doing wrong?

I have posted the same question on stackoverflow (http://stackoverflow.com/q/12476288/693039), but unfortunately there is no answer, yet.

best regards
Jan

NevemTeve 09-20-2012 03:10 AM

Pick one:

1. perform open before setuid
2. change chmod from 0640 to 0660

xhpohanka 09-20-2012 03:32 AM

Hi,

Quote:

Originally Posted by NevemTeve (Post 4784856)
2. change chmod from 0640 to 0660

Thank you for response, but 0640 was a typo, in it is 660 in fact:
Code:

# ls /dev/mydevice
crw-rw----    1 root    mydaemon    249,  0 Jan  1 00:14 /dev/mydevice

I think that permissions are ok, as the same application without daemonizing code (no setuid) runs fine, when I run it directly as mydaemon.

NevemTeve 09-20-2012 06:44 AM

Pick one:

1. perform open(2) before setuid(2)
2. use setgid(2) also

xhpohanka 10-03-2012 02:27 AM

Unfortunately I have still not solved my problem. Better description is now in stackoverflow question http://stackoverflow.com/questions/12476288.

In short:
I have a file owned by a root:video. Chmod is 440.
User mydaemon is also member of a video group.
When I run my application as root and change user to mydaemon using setuid and setgid to mydaemon:mydaemon I cannot access the files belonging to video group.

NevemTeve 10-03-2012 07:57 AM

Because you should have setgid(2) to 'video' group. Or, better, call getgroups(2), add 'video' to the list, then call setgroups(2).

PS: Ever tried to open the file before setuid(2)?

xhpohanka 10-03-2012 08:26 AM

Thank you for pointing to setgroups()

Quote:

Originally Posted by NevemTeve (Post 4795972)
PS: Ever tried to open the file before setuid(2)?

Unfortunately this is not an option for me. I need to be able to close and reopen the files.

Reuti 10-06-2012 11:17 AM

It looks like you are setting the primary group only, but not the additional group list. You can add this to the settings:
Code:

    if (pw) {

        int ngroups;
        gid_t *groups;
        ngroups=0;

        ret = getgrouplist("mydaemon", pw->pw_gid, NULL, &ngroups);
        if (ret < 0) {
            printf("expected error with initial call to getgrouplist to get the size\n");
            printf("found %d groups\n", ngroups);
        }

        printf("need %d bytes\n", ngroups * sizeof (gid_t));
        groups = malloc(ngroups * sizeof (gid_t));
        if (groups == NULL) {
            printf("malloc failed\n");
            exit(1);
        }

        ret = getgrouplist("mydaemon", pw->pw_gid, groups, &ngroups);
        if (ret < 0) {
            printf("second call to getgroups failed\n");
            exit(1);
        }

        ret = setgroups(ngroups, groups);
        if (ret < 0) {
            printf("setgroups failed\n");
            exit(1);
        }

        ret = setgid(pw->pw_gid);
        if (ret < 0) {
            printf("error with setgid\n");
            exit(1);
        }

        ret = setuid(pw->pw_uid);
        if (ret < 0) {
            printf("error with setuid\n");
            exit(1);
        }

    }


xhpohanka 10-06-2012 02:44 PM

Quote:

Originally Posted by Reuti (Post 4798868)
It looks like you are setting the primary group only, but not the additional group list. You can add this to the settings:

Thank you, you point me to the root of the problem....


All times are GMT -5. The time now is 08:06 AM.