LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-20-2012, 01:33 AM   #1
xhpohanka
LQ Newbie
 
Registered: Nov 2011
Location: Czech Republic
Distribution: Debian derivatives, uClinux and others
Posts: 10

Rep: Reputation: Disabled
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

Last edited by xhpohanka; 09-20-2012 at 03:30 AM.
 
Old 09-20-2012, 03:10 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,856
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Pick one:

1. perform open before setuid
2. change chmod from 0640 to 0660
 
Old 09-20-2012, 03:32 AM   #3
xhpohanka
LQ Newbie
 
Registered: Nov 2011
Location: Czech Republic
Distribution: Debian derivatives, uClinux and others
Posts: 10

Original Poster
Rep: Reputation: Disabled
Hi,

Quote:
Originally Posted by NevemTeve View Post
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.

Last edited by xhpohanka; 09-20-2012 at 03:34 AM.
 
Old 09-20-2012, 06:44 AM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,856
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Pick one:

1. perform open(2) before setuid(2)
2. use setgid(2) also
 
Old 10-03-2012, 02:27 AM   #5
xhpohanka
LQ Newbie
 
Registered: Nov 2011
Location: Czech Republic
Distribution: Debian derivatives, uClinux and others
Posts: 10

Original Poster
Rep: Reputation: Disabled
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.
 
Old 10-03-2012, 07:57 AM   #6
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,856
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
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)?
 
Old 10-03-2012, 08:26 AM   #7
xhpohanka
LQ Newbie
 
Registered: Nov 2011
Location: Czech Republic
Distribution: Debian derivatives, uClinux and others
Posts: 10

Original Poster
Rep: Reputation: Disabled
Thank you for pointing to setgroups()

Quote:
Originally Posted by NevemTeve View Post
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.
 
Old 10-06-2012, 11:17 AM   #8
Reuti
Senior Member
 
Registered: Dec 2004
Location: Marburg, Germany
Distribution: openSUSE 15.2
Posts: 1,339

Rep: Reputation: 260Reputation: 260Reputation: 260
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);
        }

    }
 
1 members found this post helpful.
Old 10-06-2012, 02:44 PM   #9
xhpohanka
LQ Newbie
 
Registered: Nov 2011
Location: Czech Republic
Distribution: Debian derivatives, uClinux and others
Posts: 10

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Reuti View Post
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....
 
  


Reply

Tags
daemon, permissions, uid



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
sshd: fatal: daemon() failed: No such device oru Linux - Networking 10 08-13-2013 03:06 PM
Device node access permissions in Linux ramonfried Linux - Kernel 1 08-28-2011 04:34 AM
Memory mapped device access in Linux tsik Linux - Software 1 10-31-2006 09:26 PM
Daemon cannot open device driver JackD Linux - Security 2 09-18-2001 01:31 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:07 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration