I just upgraded from 2.4.8-pre3-ac2 to 2.4.19-pre2-ac2, and found that
for threaded programs like mozilla and xmms, files in /proc/<pid> are
owned by root, even if the process belongs to another user. I
particularly wanted to be able to read /proc/<pid>/environ, but I can't.
Is this a known problem? I haven't seen it float by.
I'll backtrack kernels to see if I can find the patch that caused it and
report back if I hear nothing.
Thanks,
Danek
On Wed, Mar 06, 2002 at 10:01:10PM -0800, Danek Duvall wrote:
> I just upgraded from 2.4.8-pre3-ac2 to 2.4.19-pre2-ac2, and found that
> for threaded programs like mozilla and xmms, files in /proc/<pid> are
> owned by root, even if the process belongs to another user.
>
> I'll backtrack kernels to see if I can find the patch that caused it
> and report back if I hear nothing.
It's caused by the ac2 patch, but I'm not sure which part. Maybe the
changes to set_user(), causing the dumpable flag to be set to zero, and
thus the uid/gid of the inode not to be set to the real owner?
Danek
> I just upgraded from 2.4.8-pre3-ac2 to 2.4.19-pre2-ac2, and found that
> for threaded programs like mozilla and xmms, files in /proc/<pid> are
> owned by root, even if the process belongs to another user. I
> particularly wanted to be able to read /proc/<pid>/environ, but I can't.
>
> Is this a known problem? I haven't seen it float by.
>
> I'll backtrack kernels to see if I can find the patch that caused it and
> report back if I hear nothing.
Thanks - that will really help. There are several sets of thread related
changes in -ac. Its all working for me however 8)
On Thu, Mar 07, 2002 at 01:43:54PM +0000, Alan Cox wrote:
> > I just upgraded from 2.4.8-pre3-ac2 to 2.4.19-pre2-ac2, and found that
> > for threaded programs like mozilla and xmms, files in /proc/<pid> are
> > owned by root, even if the process belongs to another user. I
> > particularly wanted to be able to read /proc/<pid>/environ, but I can't.
> >
> > [ ... ]
>
> Thanks - that will really help. There are several sets of thread related
> changes in -ac. Its all working for me however 8)
Ok, I found the responsible hunk, though I haven't any idea why it would
make a difference:
diff -durp linux-2.4.18-pre7-ac2/kernel/kmod.c linux-2.4.18-pre7-ac3/kernel/kmod.c
--- linux-2.4.18-pre7-ac2/kernel/kmod.c Tue Jul 17 18:23:50 2001
+++ linux-2.4.18-pre7-ac3/kernel/kmod.c Thu Mar 7 23:05:34 2002
@@ -111,15 +111,8 @@ int exec_usermodehelper(char *program_pa
if (curtask->files->fd[i]) close(i);
}
- /* Drop the "current user" thing */
- {
- struct user_struct *user = curtask->user;
- curtask->user = INIT_USER;
- atomic_inc(&INIT_USER->__count);
- atomic_inc(&INIT_USER->processes);
- atomic_dec(&user->processes);
- free_uid(user);
- }
+ /* Become root */
+ set_user(0, 1);
/* Give kmod all effective privileges.. */
curtask->euid = curtask->fsuid = 0;
This hunk shows up for the first time in 2.4.18-pre7-ac3, which shows
the behavior, while prior versions do not. If I revert this hunk from
ac3, I get the behavior I expect. It also fixes my problem when I
revert this from 2.4.19-pre2-ac2, which is where I first saw the
problems.
I don't see why mozilla would even touch this path of execution, so I
don't know why it would make a difference there, but it makes some sense
in the case of xmms, as my sound support is in modules. But it shows up
both places.
I also checked to see if the CLONE_THREAD change in kernel/fork.c in the
same patch had any effect, because that looked more relevant to
threading, but it didn't.
So now I guess I get to help you reproduce it on your end. Let me know
what you need from me.
Thanks,
Danek
> Ok, I found the responsible hunk, though I haven't any idea why it would
> make a difference:
Nor me at the moment, but at least I know what to stare at 8)
Alan
On Fri, Mar 08, 2002 at 02:06:32AM -0800, Danek Duvall wrote:
>
> > > I just upgraded from 2.4.8-pre3-ac2 to 2.4.19-pre2-ac2, and found that
> > > for threaded programs like mozilla and xmms, files in /proc/<pid> are
> > > owned by root, even if the process belongs to another user. I
> > > particularly wanted to be able to read /proc/<pid>/environ, but I can't.
> Ok, I found the responsible hunk, though I haven't any idea why it would
> make a difference:
>
> diff -durp linux-2.4.18-pre7-ac2/kernel/kmod.c linux-2.4.18-pre7-ac3/kernel/kmod.c
> --- linux-2.4.18-pre7-ac2/kernel/kmod.c Tue Jul 17 18:23:50 2001
> +++ linux-2.4.18-pre7-ac3/kernel/kmod.c Thu Mar 7 23:05:34 2002
> @@ -111,15 +111,8 @@ int exec_usermodehelper(char *program_pa
> if (curtask->files->fd[i]) close(i);
> }
>
> - /* Drop the "current user" thing */
> - {
> - struct user_struct *user = curtask->user;
> - curtask->user = INIT_USER;
> - atomic_inc(&INIT_USER->__count);
> - atomic_inc(&INIT_USER->processes);
> - atomic_dec(&user->processes);
> - free_uid(user);
> - }
> + /* Become root */
> + set_user(0, 1);
>
> /* Give kmod all effective privileges.. */
> curtask->euid = curtask->fsuid = 0;
The problem arises when a threaded process calls request_module().
request_module() calls kernel_thread(), which does a clone(CLONE_VM).
The created kernel thread in turn executes exec_usermodehelper, this
calls set_user() with dumpclear=1, which leads to set_user() marking
the current task as not dumpable.
The problem is, that current->mm of the kernel thread is shared (from
the clone(CLONE_VM)) with the task doing the request_module() (and in
turn with all other threads of the process). As the dumpable flag
happens to be a property of the tasks mm, set_user also marks the
process (and all threads) as not dumpable.
Then see the following piece of code in proc_pid_make_inode()
(fs/proc/base.c):
inode->i_uid = 0;
inode->i_gid = 0;
if (ino == PROC_PID_INO || task_dumpable(task)) {
inode->i_uid = task->euid;
inode->i_gid = task->egid;
}
set_user() just marked the tasks mm as not dumpable, so the files in
/proc/<pid> (where ino != PROC_PID_INO) get UID 0.
BTW, the problem should also occur with _every_ process running into a
request_module().
Danek, can you please try changing the second argument to set_user()
into 0, ie.
/* Become root */
set_user(0, 0);
Apart from not setting current as not dumpable (which wasn't done by
the old code anyway), this should not change anything.
Andreas
--
Andreas Ferber - dev/consulting GmbH - Bielefeld, FRG
---------------------------------------------------------
+49 521 1365800 - [email protected] - http://www.devcon.net
On Fri, Mar 08, 2002 at 07:59:39PM +0100, Andreas Ferber wrote:
> Danek, can you please try changing the second argument to set_user()
> into 0, ie.
>
> /* Become root */
> set_user(0, 0);
This works. I initially didn't think it would, despite tracing the
problem correctly, because it didn't explain to me why mozilla would be
showing the problem. As it turns out, though, mozilla does try to load
the ipv6 module, so that's why it demonstrates the problem. Also, it
turns out that the problem with xmms goes away if I quit the first
invocation and start up a new one (the second one doesn't have to load
any modules), but mozilla keeps on showing the problem because it never
successfully loads the ipv6 module.
So it also turns out that either by changing that argument to 0 or just
reverting that hunk of the patch, xmms starts skipping whenever mozilla
loads a page, even a really simple one. Disk activity and other network
activity don't seem to cause the skipping, and the skipping disappears
when I go back to an unaltered ac kernel, so there seems to be something
wrong with set_user(0, 0) as well, just a different problem.
Danek
On Fri, Mar 08, 2002 at 12:31:57PM -0800, Danek Duvall wrote:
>
> So it also turns out that either by changing that argument to 0 or just
> reverting that hunk of the patch, xmms starts skipping whenever mozilla
> loads a page, even a really simple one.
ie. always when mozilla tries to do a socket(PF_INET6, ...), which
ends up requesting the ipv6 module.
As a side note, IMHO it would be sensible to have some way of
disabling module autoloading of protocol modules in the network stack.
As more and more apps start supporting IPv6, those ipv6 module
requests are getting more frequent on machines without IPv6 support
(the vast majority for now), which might turn into a real performance
penalty (fork+exec+wait for modprobe finish...)
> Disk activity and other network
> activity don't seem to cause the skipping, and the skipping disappears
> when I go back to an unaltered ac kernel, so there seems to be something
> wrong with set_user(0, 0) as well, just a different problem.
Uhm, this one seems rather strange. AFAICT, the dumpable flag is used
purely for access control to the processes in-memory data, ie.
/proc/<pid>/*, coredump generation etc., it doesn't affect scheduler,
memory management or the like.
Maybe it's related to the wmb() done by set_user() if dumpclear is
set? (although it's actually a nop on most x86 (which arch are you
using?))
Just for testing, can you try moving the wmb() in set_user()
(kernel/sys.c, line 512 in 2.4.19-pre2-ac3) out of the if statement?
(ie. put it right after the closing brace)
Andreas
--
Andreas Ferber - dev/consulting GmbH - Bielefeld, FRG
---------------------------------------------------------
+49 521 1365800 - [email protected] - http://www.devcon.net
On Fri, Mar 08, 2002 at 10:29:42PM +0100, Andreas Ferber wrote:
> On Fri, Mar 08, 2002 at 12:31:57PM -0800, Danek Duvall wrote:
>
> > So it also turns out that either by changing that argument to 0 or
> > just reverting that hunk of the patch, xmms starts skipping whenever
> > mozilla loads a page, even a really simple one.
>
> ie. always when mozilla tries to do a socket(PF_INET6, ...), which
> ends up requesting the ipv6 module.
I don't think so -- modprobe logs its attempts in /var/log/ksymoops/ and
there aren't nearly as many attempts to load net-pf-10 logged there as
pages I reloaded.
Besides if you were right, it would do the same thing in the unchanged
ac kernel -- try to load ipv6 each time and fail -- and I'd presumably
see the skipping there, too.
> > Disk activity and other network activity don't seem to cause the
> > skipping, and the skipping disappears when I go back to an unaltered
> > ac kernel, so there seems to be something wrong with set_user(0, 0)
> > as well, just a different problem.
>
> Uhm, this one seems rather strange.
No argument from me.
> Maybe it's related to the wmb() done by set_user() if dumpclear is
> set? (although it's actually a nop on most x86 (which arch are you
> using?))
AMD K6-III, just to be specific.
> Just for testing, can you try moving the wmb() in set_user()
> (kernel/sys.c, line 512 in 2.4.19-pre2-ac3) out of the if statement?
I'd expect to see the skipping regardless, then, right? I'll give it a
shot tonight and report back.
Thanks,
Danek
Andreas Ferber wrote:
>As a side note, IMHO it would be sensible to have some way of
>disabling module autoloading of protocol modules in the network stack.
>
What is the problem with using modules.conf e.g.
alias net-pf-10 off
?
Joe
On Fri, Mar 08, 2002 at 01:47:29PM -0800, J Sloan wrote:
> Andreas Ferber wrote:
>
> >As a side note, IMHO it would be sensible to have some way of
> >disabling module autoloading of protocol modules in the network stack.
> >
>
> What is the problem with using modules.conf e.g.
>
> alias net-pf-10 off
I have that. The problem is that if every time a program attempts to
make an IPv6 connection it forces the kernel to spawn off modprobe to go
look for it, you have a performance issue. Of course, I'd imagine that
a reasonably written program would not try to use IPv6 beyond the first
failure.
Danek
On Fri, Mar 08, 2002 at 01:41:49PM -0800, Danek Duvall wrote:
> >
> > > So it also turns out that either by changing that argument to 0 or
> > > just reverting that hunk of the patch, xmms starts skipping whenever
> > > mozilla loads a page, even a really simple one.
> > ie. always when mozilla tries to do a socket(PF_INET6, ...), which
> > ends up requesting the ipv6 module.
> I don't think so -- modprobe logs its attempts in /var/log/ksymoops/ and
> there aren't nearly as many attempts to load net-pf-10 logged there as
> pages I reloaded.
Hmm, right. Actually, it should only try to open an IPv6 socket if
you stomp on a webserver which runs IPv6 already.
> > Maybe it's related to the wmb() done by set_user() if dumpclear is
> > set? (although it's actually a nop on most x86 (which arch are you
> > using?))
> AMD K6-III, just to be specific.
OK, if you didn't compile your kernel for an IDT WinChip, wmb() only
affects the compilers optimizer (it stops the compiler from reordering
memory writes across it, so it's effect is not changed by the if
around it in this case).
> > Just for testing, can you try moving the wmb() in set_user()
> > (kernel/sys.c, line 512 in 2.4.19-pre2-ac3) out of the if statement?
> I'd expect to see the skipping regardless, then, right?
Nope, the other way round. At the moment, the wmb() in set_user() is
only done if dumpclear is set, ie. with set_user(0, 1).
But as stated above, moving the wmb() should not change anything on an
x86 (non-WinChip) machine. I think your problem is buried somewhere
else ...
> I'll give it a
> shot tonight and report back.
... but really testing it doesn't hurt, so please proceed :-)
What you can also try is making the kernel do those module requests
without the rest of mozilla around it. Try running the following test
program a few times while you are listening to music.
---------- snip ----------
/*
* Save as ipv6test.c and compile with "gcc -o ipv6test ipv6test.c".
* Run with "./ipv6test".
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
int main(void)
{
int s;
printf("Creating IPv6 socket...");
if ((s = socket(PF_INET6, SOCK_STREAM, 0)) != -1) {
printf(" succeeded.\n");
close(s);
}
else
printf("failed.\nsocket: %m\n");
return 0;
}
---------- snip ----------
If this doesn't cause skips, it seems very unlikely to me that your
skips are related to request_module() or the functions called by it.
Andreas
--
Andreas Ferber - dev/consulting GmbH - Bielefeld, FRG
---------------------------------------------------------
+49 521 1365800 - [email protected] - http://www.devcon.net
Ok, after trying all four combinations (call to wmb() moved or not, and
set_user(0, 1) vs set_user(0, 0)), it turns out all four exhibit
skipping, so that's unrelated (in fact, it seems to happen not on net
access, but on redraw -- mozilla's dialogs make xmms skip, too).
The call to set_user() definitely changes the behavior of the directory
in /proc as we expected.
I suppose I'll have to wait for the low latency patch to be updated to
the latest ac kernel; that appears to have been the reason there wasn't
any skipping in my 2.4.18-pre3-ac2. I tried porting it myself, but the
rejects were significant enough to confuse me, so I'll wait.
I'll leave it for someone else to decide what arguments to set_user()
exec_usermodehelper() should pass.
Thanks all!
Danek
On Fri, Mar 08, 2002 at 07:09:37PM -0800, Danek Duvall wrote:
> Ok, after trying all four combinations (call to wmb() moved or not, and
> set_user(0, 1) vs set_user(0, 0)), it turns out all four exhibit
> skipping, so that's unrelated (in fact, it seems to happen not on net
> access, but on redraw -- mozilla's dialogs make xmms skip, too).
OK, so it's clearly unrelated.
> I'll leave it for someone else to decide what arguments to set_user()
> exec_usermodehelper() should pass.
Clearing dumpable at this point is obviously wrong as it always has
side-effects on the process that was leading into the module request.
It's also unnecessary, as it /only/ has effect on the /old/ mm_struct,
before doing the execve() of the usermode helper. As request_module
and friends don't introduce sensitive data into the address space of
the calling process, leaving dumpable alone is just fine.
So, IMO, set_user(0, 0) should be the way to go.
Andreas
--
Andreas Ferber - dev/consulting GmbH - Bielefeld, FRG
---------------------------------------------------------
+49 521 1365800 - [email protected] - http://www.devcon.net