Discussion:
Using seteuid in a threaded app
(too old to reply)
Otto
2005-09-14 14:14:15 UTC
Permalink
Hi All,

I hope you can help me with this one, because I'm pretty much stumped.

My app runs as root... In one thread in my app, I'm accessing the file
system "impersonating" another user on the system, by calling
seteuid(). Maybe you can guess that this code has been ported from
_another_ OS... Anyway, up 'til now, this has always worked fine.

However, when it's running on Red Hat EL 4.0, every time I call
seteuid() in one thread, all of the other threads get a signal (SIG33).
I think this has two side effects:
1. All of the threads in my process switch to the new effective uid
2. Half of the other threads which are not signal-safe conk out,
because their last system call returned with EINTR. I should point out
that most of this code is in other libraries, and isn't under my
control...

Now I expect this is probably caused by an intentional change in the
pthreads stuff to gain better POSIX compliance, but I can't find any
documentation to this effect.

What I am really looking for is a way to revert to the "old" behavior,
where the seteuid call only affects the current thread. This would be
_really useful_

But, in anticipation of all the "you're doing this all wrong" replies
that I'm bound to receive, I'm willing to try an alternative
approach... So, is there a reliable way I can figure out, given a UID,
whether a particular file is accessible by that user, and to create
files owned by said user?

Thanks in advance for your help!

Cheers,
Otto
Kasper Dupont
2005-09-14 14:36:54 UTC
Permalink
Post by Otto
So, is there a reliable way I can figure out, given a UID,
whether a particular file is accessible by that user, and to create
files owned by said user?
If you want a reliable way, you need to change the uid of the
thread because if you try to do it by hand using stat or something
similar, you will run into race conditions.

I have a few different ideas on how to solve your problem. One would
be to use a semaphore to put your open call in a critical region.
Then only one thread at a time would be changing the effective user
ID.

Another approach would be to use the fsuid rather than euid. But
that is Linux specific and is not going to work on any other OS.

You also have to keep in mind that the uid is only part of what
decides if you are allowed to access a file. The set of groups which
a user is a member of is used as well. Unless you are absolutely
sure it doesn't matter in your case, you need to setup this set of
groups correctly as well.
--
Kasper Dupont
Note to self: Don't try to allocate
256000 pages with GFP_KERNEL on x86.
Otto
2005-09-14 16:02:40 UTC
Permalink
Hi Kasper,

Thanks, setfsuid might be just the ticket! Right now I'm pretty
Linux-specific already, so I will have to cross many other bridges
first when porting to Solaris etc...
Just to confirm, when using setfsuid/setfsgid, if I then create a file,
will the ownership of that file be that of my setfsuid user?

I did think of another option, which would be to change the signal
handler for SIG33 to Ignore after pthreads has been initialised, but
this seems risky to me...

Also, it's strange, isn't it, that the old functionality isn't
available through some alternative code path?

Cheers,
Otto
Kasper Dupont
2005-09-14 16:26:27 UTC
Permalink
Post by Otto
Just to confirm, when using setfsuid/setfsgid, if I then create a file,
will the ownership of that file be that of my setfsuid user?
Yes, that is how it is supposed to work. Notice that if you
change euid anywhere in the program, then it is going to
change both euid and fsuid. But changing fsuid doesn't touch
euid.
--
Kasper Dupont
Note to self: Don't try to allocate
256000 pages with GFP_KERNEL on x86.
Loading...