diff options
author | jdike <jdike> | 2003-09-02 20:09:42 +0000 |
---|---|---|
committer | jdike <jdike> | 2003-09-02 20:09:42 +0000 |
commit | bcd6919fc98dd484186ea3a34ceb96e1761ec8bd (patch) | |
tree | b653bf4020dd57553d08f67bfc9ca5d03c7aa54d | |
parent | cd656e578b3a3fd425e9091e12e7ad465900e26f (diff) | |
download | uml-history-bcd6919fc98dd484186ea3a34ceb96e1761ec8bd.tar.gz |
Fixed the chroot option.v_2_4_22_1
-rw-r--r-- | arch/um/fs/hostfs/hostfs_kern.c | 75 |
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) |