uml "exec" writes stdout/stderr back to mconsole
[strongswan.git] / src / dumm / patches / mconsole-exec-2.6.26.patch
1 --- linux-2.6.26rc5-orig/arch/um/drivers/mconsole_kern.c        2008-04-17 04:49:44.000000000 +0200
2 +++ uml-2.6.26rc5/arch/um/drivers/mconsole_kern.c       2008-07-08 16:00:07.000000000 +0200
3 @@ -4,6 +4,7 @@
4   * Licensed under the GPL
5   */
6  
7 +#include "linux/kmod.h"
8  #include <linux/console.h>
9  #include <linux/ctype.h>
10  #include <linux/interrupt.h>
11 @@ -18,6 +19,7 @@
12  #include <linux/utsname.h>
13  #include <linux/workqueue.h>
14  #include <linux/mutex.h>
15 +#include <linux/file.h>
16  #include <asm/uaccess.h>
17  
18  #include "init.h"
19 @@ -199,6 +201,36 @@
20  }
21  #endif
22  
23 +void mconsole_exec(struct mc_request *req)
24 +{
25 +       int res, len;
26 +       struct file *out;
27 +       char buf[MCONSOLE_MAX_DATA];
28 +
29 +       char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
30 +       char *argv[] = { "/bin/sh", "-c", req->request.data + strlen("exec "), NULL };
31 +       res = call_usermodehelper_pipe("/bin/sh", argv, envp, NULL, &out);
32 +       
33 +       if (res < 0) {
34 +               mconsole_reply(req, "call_usermodehelper_pipe failed", 1, 0);
35 +               return;
36 +       }
37 +       
38 +       for (;;) {
39 +               len = out->f_op->read(out, buf, sizeof(buf), 0);
40 +               if (len < 0) {
41 +                       mconsole_reply(req, "reading output failed", 1, 0);
42 +                       break;
43 +               }
44 +               if (len == 0) {
45 +                       mconsole_reply_len(req, buf, len, 0, 0);
46 +                       break;
47 +               }
48 +               mconsole_reply_len(req, buf, len, 0, 1);
49 +       }
50 +       fput(out);
51 +}
52 +
53  void mconsole_proc(struct mc_request *req)
54  {
55         char path[64];
56 @@ -270,6 +302,7 @@
57      stop - pause the UML; it will do nothing until it receives a 'go' \n\
58      go - continue the UML after a 'stop' \n\
59      log <string> - make UML enter <string> into the kernel log\n\
60 +    exec <string> - pass <string> to /bin/sh -c synchronously\n\
61      proc <file> - returns the contents of the UML's /proc/<file>\n\
62      stack <pid> - returns the stack of the specified pid\n\
63  "
64 --- linux-2.6.26rc5-orig/arch/um/drivers/mconsole_user.c        2008-05-21 18:34:47.000000000 +0200
65 +++ uml-2.6.26rc5/arch/um/drivers/mconsole_user.c       2008-07-07 13:47:13.000000000 +0200
66 @@ -32,6 +32,7 @@
67         { "stop", mconsole_stop, MCONSOLE_PROC },
68         { "go", mconsole_go, MCONSOLE_INTR },
69         { "log", mconsole_log, MCONSOLE_INTR },
70 +       { "exec", mconsole_exec, MCONSOLE_PROC },
71         { "proc", mconsole_proc, MCONSOLE_PROC },
72         { "stack", mconsole_stack, MCONSOLE_INTR },
73  };
74 --- linux-2.6.26rc5-orig/arch/um/include/mconsole.h     2008-04-17 04:49:44.000000000 +0200
75 +++ uml-2.6.26rc5/arch/um/include/mconsole.h    2008-07-07 13:46:56.000000000 +0200
76 @@ -85,6 +85,7 @@
77  extern void mconsole_stop(struct mc_request *req);
78  extern void mconsole_go(struct mc_request *req);
79  extern void mconsole_log(struct mc_request *req);
80 +extern void mconsole_exec(struct mc_request *req);
81  extern void mconsole_proc(struct mc_request *req);
82  extern void mconsole_stack(struct mc_request *req);
83  
84 --- linux-2.6.26rc5-orig/kernel/kmod.c  2008-05-21 18:34:56.000000000 +0200
85 +++ uml-2.6.26rc5/kernel/kmod.c 2008-07-08 13:50:37.000000000 +0200
86 @@ -125,6 +125,7 @@
87         enum umh_wait wait;
88         int retval;
89         struct file *stdin;
90 +       struct file *stdout;
91         void (*cleanup)(char **argv, char **envp);
92  };
93  
94 @@ -160,8 +161,26 @@
95                 FD_SET(0, fdt->open_fds);
96                 FD_CLR(0, fdt->close_on_exec);
97                 spin_unlock(&f->file_lock);
98 -
99 -               /* and disallow core files too */
100 +       }
101 +       if (sub_info->stdout) {
102 +               struct files_struct *f = current->files;
103 +               struct fdtable *fdt;
104 +               
105 +               sys_close(1);
106 +               sys_close(2);
107 +               get_file(sub_info->stdout);
108 +               fd_install(1, sub_info->stdout);
109 +               fd_install(2, sub_info->stdout);
110 +               spin_lock(&f->file_lock);
111 +               fdt = files_fdtable(f);
112 +               FD_SET(1, fdt->open_fds);
113 +               FD_CLR(1, fdt->close_on_exec);
114 +               FD_SET(2, fdt->open_fds);
115 +               FD_CLR(2, fdt->close_on_exec);
116 +               spin_unlock(&f->file_lock);
117 +       }
118 +       if (sub_info->stdin || sub_info->stdout) {
119 +               /* disallow core files */
120                 current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
121         }
122  
123 @@ -433,6 +452,29 @@
124  }
125  EXPORT_SYMBOL(call_usermodehelper_stdinpipe);
126  
127 +int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
128 +                                 struct file **filp)
129 +{
130 +       struct file *f;
131 +
132 +       f = create_write_pipe();
133 +       if (IS_ERR(f))
134 +               return PTR_ERR(f);
135 +       sub_info->stdout = f;
136 +
137 +       f = create_read_pipe(f);
138 +       if (IS_ERR(f)) {
139 +               free_write_pipe(sub_info->stdout);
140 +               sub_info->stdout = NULL;
141 +               return PTR_ERR(f);
142 +       }
143 +       *filp = f;
144 +
145 +       return 0;
146 +}
147 +EXPORT_SYMBOL(call_usermodehelper_stdoutpipe);
148 +
149 +
150  /**
151   * call_usermodehelper_exec - start a usermode application
152   * @sub_info: information about the subprocessa
153 @@ -489,7 +531,7 @@
154   * lower-level call_usermodehelper_* functions.
155   */
156  int call_usermodehelper_pipe(char *path, char **argv, char **envp,
157 -                            struct file **filp)
158 +                            struct file **in, struct file **out)
159  {
160         struct subprocess_info *sub_info;
161         int ret;
162 @@ -498,9 +540,17 @@
163         if (sub_info == NULL)
164                 return -ENOMEM;
165  
166 -       ret = call_usermodehelper_stdinpipe(sub_info, filp);
167 -       if (ret < 0)
168 -               goto out;
169 +       if (in) {
170 +               ret = call_usermodehelper_stdinpipe(sub_info, in);
171 +               if (ret < 0)
172 +                       goto out;
173 +       }
174 +
175 +       if (out) {
176 +               ret = call_usermodehelper_stdoutpipe(sub_info, out);
177 +               if (ret < 0)
178 +                       goto out;
179 +       }
180  
181         return call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC);
182  
183 --- linux-2.6.26rc5-orig/include/linux/kmod.h   2008-04-17 04:49:44.000000000 +0200
184 +++ uml-2.6.26rc5/include/linux/kmod.h  2008-07-08 10:29:29.000000000 +0200
185 @@ -93,6 +93,6 @@
186  
187  struct file;
188  extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[],
189 -                                   struct file **filp);
190 +                                   struct file **in, struct file **out);
191  
192  #endif /* __LINUX_KMOD_H__ */
193 --- linux-2.6.26rc5-orig/fs/exec.c      2008-06-05 14:00:42.000000000 +0200
194 +++ uml-2.6.26rc5/fs/exec.c     2008-07-08 10:28:33.000000000 +0200
195 @@ -1737,7 +1737,7 @@
196  
197                 /* SIGPIPE can happen, but it's just never processed */
198                 if (call_usermodehelper_pipe(corename+1, helper_argv, NULL,
199 -                               &file)) {
200 +                               &file, NULL)) {
201                         printk(KERN_INFO "Core dump to %s pipe failed\n",
202                                corename);
203                         goto fail_unlock;