summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdike <jdike>2003-09-02 20:09:42 +0000
committerjdike <jdike>2003-09-02 20:09:42 +0000
commitbcd6919fc98dd484186ea3a34ceb96e1761ec8bd (patch)
treeb653bf4020dd57553d08f67bfc9ca5d03c7aa54d
parentcd656e578b3a3fd425e9091e12e7ad465900e26f (diff)
downloaduml-history-bcd6919fc98dd484186ea3a34ceb96e1761ec8bd.tar.gz
Fixed the chroot option.v_2_4_22_1
-rw-r--r--arch/um/fs/hostfs/hostfs_kern.c75
1 files changed, 55 insertions, 20 deletions
diff --git a/arch/um/fs/hostfs/hostfs_kern.c b/arch/um/fs/hostfs/hostfs_kern.c
index 3a50894..bb6668b 100644
--- a/arch/um/fs/hostfs/hostfs_kern.c
+++ b/arch/um/fs/hostfs/hostfs_kern.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
* Licensed under the GPL
*/
@@ -30,8 +30,10 @@ struct dentry_operations hostfs_dentry_ops = {
.d_delete = hostfs_d_delete,
};
+#define DEFAULT_ROOT "/"
+
/* Changed in hostfs_args before the kernel starts running */
-static char *root_ino = "/";
+static char *jail_dir = NULL;
static int append = 0;
#define HOSTFS_SUPER_MAGIC 0x00c0ffee
@@ -48,7 +50,7 @@ static int __init hostfs_args(char *options, int *add)
if(ptr != NULL)
*ptr++ = '\0';
if(*options != '\0')
- root_ino = options;
+ jail_dir = options;
options = ptr;
while(options){
@@ -529,6 +531,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
if(error) *error = err;
return(inode);
out_put:
+ make_bad_inode(inode);
iput(inode);
out:
if(error) *error = err;
@@ -858,43 +861,75 @@ static struct address_space_operations hostfs_link_aops = {
.readpage = hostfs_link_readpage,
};
-static struct super_block *hostfs_read_super_common(struct super_block *sb,
- char *data)
+static char *get_root(char *mount_arg)
+{
+ char *root, *slash = "";
+ int len = 0;
+
+ if(jail_dir != NULL){
+ len += strlen(jail_dir);
+ if((*jail_dir == '\0') ||
+ (jail_dir[strlen(jail_dir) - 1] != '/'))
+ slash = "/";
+ len += strlen(slash);
+ }
+
+ if(mount_arg == NULL)
+ mount_arg = DEFAULT_ROOT;
+
+ len += strlen(mount_arg) + 1;
+
+ root = kmalloc(len, GFP_KERNEL);
+ if(root == NULL)
+ return(NULL);
+
+ if(jail_dir != NULL)
+ sprintf(root, "%s%s%s", jail_dir, slash, mount_arg);
+ else
+ strcpy(root, mount_arg);
+
+ return(root);
+}
+
+struct super_block *hostfs_read_super(struct super_block *sb, void *data,
+ int silent)
{
struct inode *root_inode;
- char *name;
+ char *root_dir;
sb->s_blocksize = 1024;
sb->s_blocksize_bits = 10;
sb->s_magic = HOSTFS_SUPER_MAGIC;
sb->s_op = &hostfs_sbops;
- if((data == NULL) || (*((char *) data) == '\0')) data = root_ino;
- name = kmalloc(strlen(data) + 1, GFP_KERNEL);
- if(name == NULL) return(NULL);
- strcpy(name, data);
+
root_inode = get_inode(sb, NULL, NULL);
if(root_inode == NULL)
- goto out_free;
+ goto out;
+
+ root_dir = get_root(data);
+ if(root_dir == NULL)
+ goto out_put;
- root_inode->u.hostfs_i.host_filename = name;
+ root_inode->u.hostfs_i.host_filename = root_dir;
sb->s_root = d_alloc_root(root_inode);
+ if(sb->s_root == NULL)
+ goto out_free;
+
if(read_inode(root_inode))
- goto out_put;
+ goto out_dput;
return(sb);
+ out_dput:
+ dput(sb->s_root);
out_free:
- kfree(name);
+ kfree(root_dir);
out_put:
+ make_bad_inode(root_inode);
iput(root_inode);
+ out:
return(NULL);
}
-struct super_block *hostfs_read_super(struct super_block *sb, void *data,
- int silent)
-{
- return(hostfs_read_super_common(sb, data));
-}
-
DECLARE_FSTYPE(hostfs_type, "hostfs", hostfs_read_super, 0);
static int __init init_hostfs(void)