All of lore.kernel.org
 help / color / mirror / Atom feed
* call_usermodehelper does not report exit status?
@ 2003-09-19 16:24 Omen Wild
  2003-09-19 18:21 ` Andrew Morton
  0 siblings, 1 reply; 8+ messages in thread
From: Omen Wild @ 2003-09-19 16:24 UTC (permalink / raw)
  To: linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 893 bytes --]

As part of a LSM I am writing, I need to call a user-space program and
check its return status.  I found the call_usermodehelper function and
call it with the wait flag set, but I cannot get a non-zero return
status of the program to propagate into the kernel.  If I try to run a
non-existent program then call_usermodehelper returns -1, so at least
some errors propagate properly.  I have attached a trivial LSM test
program that hooks inode_rename, runs /bin/false and prints the return
status of call_usermodehelper.  

This is with kernel 2.6.0-test5-mm3 compiled on an up to date Debian
unstable.

For simplicity I have also attached a patch to security/Makefile to
build this test LSM as a kernel module.

Before I break out UML or the kernel debugger, does anyone have any
ideas what I am doing wrong?

Thanks,
  Omen

-- 
There is much Obi-Wan did not tell you.

[-- Attachment #1.2: Makefile.patch --]
[-- Type: text/plain, Size: 319 bytes --]

--- Makefile.orig       2003-09-19 12:18:20.000000000 -0400
+++ Makefile    2003-09-19 12:14:11.000000000 -0400
@@ -18,3 +18,6 @@
 
 obj-$(CONFIG_SECURITY_CAPABILITIES)    += commoncap.o capability.o
 obj-$(CONFIG_SECURITY_ROOTPLUG)                += commoncap.o root_plug.o
+
+# Test modules
+obj-m += test.o

[-- Attachment #1.3: test.c --]
[-- Type: text/plain, Size: 1748 bytes --]

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/security.h>
#include <linux/stat.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/ctype.h>
#include <linux/file.h>
#include <linux/spinlock.h>

#include <linux/fs.h>
#include <net/tcp.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <linux/dcache.h>
#include <linux/list.h>
#include <linux/namespace.h>
#include <linux/writeback.h>
#include <linux/quotaops.h>

#if defined(CONFIG_SECURITY_enforcer_MODULE)
#define MY_NAME THIS_MODULE->name
#else
#define MY_NAME "Test"
#endif

static int test_inode_rename (struct inode *inode, int mask)
{
   int status;
   char *envp[] = {
	  "HOME=/",
	  "TERM=linux",
	  "PATH=/usr/sbin:/sbin:/bin:/usr/bin",
	  NULL };

   char *argv[] = {
	  "/bin/false",
	  NULL };

   printk(KERN_INFO "calling helper '%s'\n",
		  argv[0]);

   status = call_usermodehelper(argv[0], argv, envp, 1);

   printk(KERN_INFO "helper returned = %d\n", status);

   return 0;
}

static struct security_operations test_ops = {
   .inode_rename = test_inode_rename,
};

static int __init test_init (void)
{
   /* register ourselves with the security framework */
   if (register_security (&test_ops)) {
	  printk (KERN_INFO "Failure registering " MY_NAME " module with the kernel\n");
	  return -EINVAL;
   }

   printk (KERN_INFO MY_NAME " LSM initialized.\n");
   return 0;
}

static void __exit test_exit (void)
{
   if (unregister_security (&test_ops))
	  printk (KERN_INFO MY_NAME ": failure unregistering with the kernel.\n");
}


module_init (test_init);
module_exit (test_exit);

MODULE_AUTHOR("Omen Wild <Omen.Wild@Dartmouth.EDU>");
MODULE_DESCRIPTION("Test Module");
MODULE_LICENSE("GPL");

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: call_usermodehelper does not report exit status?
  2003-09-19 16:24 call_usermodehelper does not report exit status? Omen Wild
@ 2003-09-19 18:21 ` Andrew Morton
  2003-09-19 19:51   ` Omen Wild
  0 siblings, 1 reply; 8+ messages in thread
From: Andrew Morton @ 2003-09-19 18:21 UTC (permalink / raw)
  To: Omen Wild; +Cc: linux-kernel

Omen Wild <Omen.Wild@Dartmouth.EDU> wrote:
>
> I found the call_usermodehelper function and
> call it with the wait flag set, but I cannot get a non-zero return
> status of the program to propagate into the kernel.

This might fix it.

 25-akpm/kernel/exit.c |   21 +++++++++++++++++----
 25-akpm/kernel/kmod.c |    2 +-
 2 files changed, 18 insertions(+), 5 deletions(-)

diff -puN kernel/kmod.c~call_usermodehelper-retval-fix kernel/kmod.c
--- 25/kernel/kmod.c~call_usermodehelper-retval-fix	Fri Sep 19 11:14:47 2003
+++ 25-akpm/kernel/kmod.c	Fri Sep 19 11:20:14 2003
@@ -190,7 +190,7 @@ static int wait_for_helper(void *data)
 		/* We don't have a SIGCHLD signal handler, so this
 		 * always returns -ECHILD, but the important thing is
 		 * that it blocks. */
-		sys_wait4(pid, NULL, 0, NULL);
+		sys_wait4(pid, &sub_info->retval, 0, NULL);
 
 	complete(sub_info->complete);
 	return 0;
diff -puN kernel/exit.c~call_usermodehelper-retval-fix kernel/exit.c
--- 25/kernel/exit.c~call_usermodehelper-retval-fix	Fri Sep 19 11:16:59 2003
+++ 25-akpm/kernel/exit.c	Fri Sep 19 11:20:10 2003
@@ -883,10 +883,17 @@ static int wait_task_zombie(task_t *p, u
 
 	retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
 	if (!retval && stat_addr) {
+		int stat;
+
 		if (p->signal->group_exit)
-			retval = put_user(p->signal->group_exit_code, stat_addr);
+			stat = p->signal->group_exit_code;
+		else
+			stat = p->exit_code;
+
+		if (current->mm)
+			retval = put_user(stat, stat_addr);
 		else
-			retval = put_user(p->exit_code, stat_addr);
+			retval = __put_user(stat, stat_addr);
 	}
 	if (retval) {
 		p->state = TASK_ZOMBIE;
@@ -987,8 +994,14 @@ static int wait_task_stopped(task_t *p, 
 	write_unlock_irq(&tasklist_lock);
 
 	retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
-	if (!retval && stat_addr)
-		retval = put_user((exit_code << 8) | 0x7f, stat_addr);
+	if (!retval && stat_addr) {
+		int stat = (exit_code << 8) | 0x7f;
+
+		if (current->mm)
+			retval = put_user(stat, stat_addr);
+		else
+			retval = __put_user(stat, stat_addr);
+	}
 	if (!retval)
 		retval = p->pid;
 	put_task_struct(p);

_


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: call_usermodehelper does not report exit status?
  2003-09-19 19:51   ` Omen Wild
@ 2003-09-19 19:42     ` Andrew Morton
  2003-09-20 18:55       ` Milton D. Miller II
  0 siblings, 1 reply; 8+ messages in thread
From: Andrew Morton @ 2003-09-19 19:42 UTC (permalink / raw)
  To: Omen Wild; +Cc: linux-kernel

Omen Wild <Omen.Wild@Dartmouth.EDU> wrote:
>
> Quoting Andrew Morton <akpm@osdl.org> on Fri, Sep 19 11:21:
> >
> > This might fix it.
> 
> Hmmm, that did not fix it for me.  No change in behavior.
> 

Curses, foiled again.

I agree that as long as we are supporting synchronous callouts we should be
correctly returning the exit code.   I'll work on it a bit.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: call_usermodehelper does not report exit status?
  2003-09-19 18:21 ` Andrew Morton
@ 2003-09-19 19:51   ` Omen Wild
  2003-09-19 19:42     ` Andrew Morton
  0 siblings, 1 reply; 8+ messages in thread
From: Omen Wild @ 2003-09-19 19:51 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 200 bytes --]

Quoting Andrew Morton <akpm@osdl.org> on Fri, Sep 19 11:21:
>
> This might fix it.

Hmmm, that did not fix it for me.  No change in behavior.

-- 
There are more ways into the woods than out.

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: call_usermodehelper does not report exit status?
  2003-09-19 19:42     ` Andrew Morton
@ 2003-09-20 18:55       ` Milton D. Miller II
  2003-09-25 18:41         ` Chris Wright
  0 siblings, 1 reply; 8+ messages in thread
From: Milton D. Miller II @ 2003-09-20 18:55 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Rusty Russell, Omen Wild, linux-kernel

Andrew Morton <akpm@osdl.org> wrote:
> Omen Wild <Omen.Wild@Dartmouth.EDU> wrote:
> >
> > I found the call_usermodehelper function and
> > call it with the wait flag set, but I cannot get a non-zero return
> > status of the program to propagate into the kernel.
> 
> This might fix it.


I think you missed the why behind the comment just above your first change.

 		/* We don't have a SIGCHLD signal handler, so this
 		 * always returns -ECHILD, but the important thing is
 		 * that it blocks. */
-		sys_wait4(pid, NULL, 0, NULL);
+		sys_wait4(pid, &sub_info->retval, 0, NULL);


The exit code notices that there is no signal handler for SIGCHILD and
does a fast exit, then we notice when woken up the child no longer exists.

Rusty discovered this back in June when we were trying to fix a checker
error on the wait call, and decided that at the time no one was using the
return value, hence the simpler fix.  

http://linux.bkbits.net:8080/linux-2.5/cset@1.1046.366.23?nav=index.html|src/|src/kernel|related/kernel/kmod.c


milton

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: call_usermodehelper does not report exit status?
  2003-09-20 18:55       ` Milton D. Miller II
@ 2003-09-25 18:41         ` Chris Wright
  2003-09-25 19:05           ` Andrew Morton
  0 siblings, 1 reply; 8+ messages in thread
From: Chris Wright @ 2003-09-25 18:41 UTC (permalink / raw)
  To: Milton D. Miller II; +Cc: Andrew Morton, Rusty Russell, Omen Wild, linux-kernel

* Milton D. Miller II (miltonm@realtime.net) wrote:
> Andrew Morton <akpm@osdl.org> wrote:
> > This might fix it.
> 
> I think you missed the why behind the comment just above your first change.

Anything wrong with just setting a SIG_DFL handler?  W.R.T. the kernel
pointer, either Andrew's patch which does put_user/__put_user depending
on context, or some ugly set_fs() should work.  This simplistic approach
works for me, thoughts?

thanks,
-chris

-- 
Linux Security Modules     http://lsm.immunix.org     http://lsm.bkbits.net


--- linux-2.6.0-test5-mm4/kernel/kmod.c	2003-09-08 12:49:59.000000000 -0700
+++ 2.6.0-test5-mm4/kernel/kmod.c	2003-09-25 11:34:59.000000000 -0700
@@ -181,16 +181,24 @@
 {
 	struct subprocess_info *sub_info = data;
 	pid_t pid;
+	struct k_sigaction sa;
+
+	sa.sa.sa_handler = SIG_DFL;
+	sa.sa.sa_flags = 0;
+	siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD));
+	do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0);
 
 	sub_info->retval = 0;
 	pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
 	if (pid < 0)
 		sub_info->retval = pid;
-	else
-		/* We don't have a SIGCHLD signal handler, so this
-		 * always returns -ECHILD, but the important thing is
-		 * that it blocks. */
-		sys_wait4(pid, NULL, 0, NULL);
+	else {
+		mm_segment_t old_fs;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		sys_wait4(pid, &sub_info->retval, 0, NULL);
+		set_fs(old_fs);
+	}
 
 	complete(sub_info->complete);
 	return 0;

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: call_usermodehelper does not report exit status?
  2003-09-25 18:41         ` Chris Wright
@ 2003-09-25 19:05           ` Andrew Morton
  2003-09-25 19:38             ` Chris Wright
  0 siblings, 1 reply; 8+ messages in thread
From: Andrew Morton @ 2003-09-25 19:05 UTC (permalink / raw)
  To: Chris Wright; +Cc: miltonm, rusty, Omen.Wild, linux-kernel

Chris Wright <chrisw@osdl.org> wrote:
>
> Anything wrong with just setting a SIG_DFL handler?

Seems that any time we make a change here it looks fine, tests out fine,
and explodes messily three weeks later.

> W.R.T. the kernel
> pointer, either Andrew's patch which does put_user/__put_user depending
> on context, or some ugly set_fs() should work.  This simplistic approach
> works for me, thoughts?

Yes, set_fs() is better.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: call_usermodehelper does not report exit status?
  2003-09-25 19:05           ` Andrew Morton
@ 2003-09-25 19:38             ` Chris Wright
  0 siblings, 0 replies; 8+ messages in thread
From: Chris Wright @ 2003-09-25 19:38 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Chris Wright, miltonm, rusty, Omen.Wild, linux-kernel

* Andrew Morton (akpm@osdl.org) wrote:
> Chris Wright <chrisw@osdl.org> wrote:
> >
> > Anything wrong with just setting a SIG_DFL handler?
> 
> Seems that any time we make a change here it looks fine, tests out fine,
> and explodes messily three weeks later.

Heh.  Care to try it? ;-)

thanks,
-chris
-- 
Linux Security Modules     http://lsm.immunix.org     http://lsm.bkbits.net

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2003-09-25 19:38 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-19 16:24 call_usermodehelper does not report exit status? Omen Wild
2003-09-19 18:21 ` Andrew Morton
2003-09-19 19:51   ` Omen Wild
2003-09-19 19:42     ` Andrew Morton
2003-09-20 18:55       ` Milton D. Miller II
2003-09-25 18:41         ` Chris Wright
2003-09-25 19:05           ` Andrew Morton
2003-09-25 19:38             ` Chris Wright

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.