Commit cb365cb6 authored by Paolo \'Blaisorblade\' Giarrusso's avatar Paolo \'Blaisorblade\' Giarrusso Committed by Linus Torvalds

[PATCH] uml: mconsole_proc simplify and partial fix

From: Gerd Knorr <kraxel@bytesex.org>, and me, Paolo Giarrusso

This is a rewrite of the mconsole_proc function.

The old code had the problem that the kernel crashed after calling
"uml_mconsole proc <somefile>" a few times.  I havn't tracked what exactly
causes the problem, I guess trying to access the procfs without actually
mounting it somewhere causes some corruption of kernel data structures.

The new code simply openes /proc/<file> via sys_open().  That simplifies the
function alot.  It also doesn't crash any more ;)

Also, from Paolo Giarrusso: When printing the content of a file through the
"proc" command, make it begin on his own line.

PROBLEMS:

Drawback is that it only works when procfs is actually mounted below /proc.
And within UML, often this is false, because when building honeypots we mount
HPPFS under /proc to avoid the hacker recognizing he's attacking a UML
instance.

One suggestion I've received to fix the later issue was to mount the procfs
within a kernel thread with a private namespace, but I havn't tried that so
far.

Instead, we'd like to fix the actual code of the mconsole_proc function.  From
"Anthony Brock" Anthony_Brock (at) ous (dot) edu comes a comment, suggesting
where the bug lays (as noted in the source): removing part of the code (it
seems the symlink lookup) there are no more crashes.
Signed-off-by: default avatarPaolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 92a48831
...@@ -119,12 +119,98 @@ void mconsole_log(struct mc_request *req) ...@@ -119,12 +119,98 @@ void mconsole_log(struct mc_request *req)
mconsole_reply(req, "", 0, 0); mconsole_reply(req, "", 0, 0);
} }
/* This is a more convoluted version of mconsole_proc, which has some stability
* problems; however, we need it fixed, because it is expected that UML users
* mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still
* show the real procfs content, not the ones from hppfs.*/
#if 0
void mconsole_proc(struct mc_request *req)
{
struct nameidata nd;
struct file_system_type *proc;
struct super_block *super;
struct file *file;
int n, err;
char *ptr = req->request.data, *buf;
ptr += strlen("proc");
while(isspace(*ptr)) ptr++;
proc = get_fs_type("proc");
if(proc == NULL){
mconsole_reply(req, "procfs not registered", 1, 0);
goto out;
}
super = (*proc->get_sb)(proc, 0, NULL, NULL);
put_filesystem(proc);
if(super == NULL){
mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
goto out;
}
up_write(&super->s_umount);
nd.dentry = super->s_root;
nd.mnt = NULL;
nd.flags = O_RDONLY + 1;
nd.last_type = LAST_ROOT;
/* START: it was experienced that the stability problems are closed
* if commenting out these two calls + the below read cycle. To
* make UML crash again, it was enough to readd either one.*/
err = link_path_walk(ptr, &nd);
if(err){
mconsole_reply(req, "Failed to look up file", 1, 0);
goto out_kill;
}
file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
if(IS_ERR(file)){
mconsole_reply(req, "Failed to open file", 1, 0);
goto out_kill;
}
/*END*/
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if(buf == NULL){
mconsole_reply(req, "Failed to allocate buffer", 1, 0);
goto out_fput;
}
if((file->f_op != NULL) && (file->f_op->read != NULL)){
do {
n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
&file->f_pos);
if(n >= 0){
buf[n] = '\0';
mconsole_reply(req, buf, 0, (n > 0));
}
else {
mconsole_reply(req, "Read of file failed",
1, 0);
goto out_free;
}
} while(n > 0);
}
else mconsole_reply(req, "", 0, 0);
out_free:
kfree(buf);
out_fput:
fput(file);
out_kill:
deactivate_super(super);
out: ;
}
#endif
void mconsole_proc(struct mc_request *req) void mconsole_proc(struct mc_request *req)
{ {
char path[64]; char path[64];
char *buf; char *buf;
int len; int len;
int fd; int fd;
int first_chunk = 1;
char *ptr = req->request.data; char *ptr = req->request.data;
ptr += strlen("proc"); ptr += strlen("proc");
...@@ -149,7 +235,13 @@ void mconsole_proc(struct mc_request *req) ...@@ -149,7 +235,13 @@ void mconsole_proc(struct mc_request *req)
if (len < 0) { if (len < 0) {
mconsole_reply(req, "Read of file failed", 1, 0); mconsole_reply(req, "Read of file failed", 1, 0);
goto out_free; goto out_free;
} else if (len == PAGE_SIZE-1) { }
/*Begin the file content on his own line.*/
if (first_chunk) {
mconsole_reply(req, "\n", 0, 1);
first_chunk = 0;
}
if (len == PAGE_SIZE-1) {
buf[len] = '\0'; buf[len] = '\0';
mconsole_reply(req, buf, 0, 1); mconsole_reply(req, buf, 0, 1);
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment