X-Git-Url: http://git.onelab.eu/?p=lxc-kernelspace-obsolete.git;a=blobdiff_plain;f=mntsu.c;h=34cfb5611d83e2140bb24de8a000cbc59478c19e;hp=d16ad80b16da431cd3a939629d7b644811c5f792;hb=HEAD;hpb=a9d6589acce0d5f0eab3f9948bb3562f754a8fd0 diff --git a/mntsu.c b/mntsu.c index d16ad80..34cfb56 100644 --- a/mntsu.c +++ b/mntsu.c @@ -41,6 +41,7 @@ MODULE_DESCRIPTION("Hack to enable mount namespace switching via setns. Based on MODULE_LICENSE("GPL"); MODULE_VERSION(VERSION_STR); +struct proc_dir_entry *proc_entry; static void *mntns_get(struct task_struct *task) { @@ -72,14 +73,12 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) (*put_mnt_ns2)(nsproxy->mnt_ns); nsproxy->mnt_ns = mnt_ns; - /* Find the root */ - root.mnt = mnt_ns->root; + root.mnt = &mnt_ns->root->mnt; root.dentry = mnt_ns->root->mnt.mnt_root; path_get(&root); while(d_mountpoint(root.dentry) && follow_down(&root)) ; - /* Update the pwd and root */ path_get(&root); path_get(&root); path_put(&fs->root); @@ -99,31 +98,22 @@ const struct proc_ns_operations mntns_operations = { }; void (*free_nsproxy2)(struct nsproxy *ns); -struct file *(*proc_ns_fget2)(int fd); struct nsproxy * (*create_new_namespaces)(unsigned long flags, struct task_struct *tsk, struct fs_struct *new_fs); void (*switch_task_namespaces2)(struct task_struct *p, struct nsproxy *new); -static int setns_entry(int fd, int nstype) { - if (nstype==666) { +static int setns(struct task_struct *reftask) { const struct proc_ns_operations *ops; struct task_struct *tsk = current; struct nsproxy *new_nsproxy; - struct proc_inode *ei; - struct file *file; int err; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - file = (*proc_ns_fget2)(fd); - if (IS_ERR(file)) - return PTR_ERR(file); - err = -EINVAL; - ei = PROC_I(file->f_dentry->d_inode); ops = &mntns_operations; new_nsproxy = (*create_new_namespaces)(0, tsk, tsk->fs); @@ -132,39 +122,64 @@ static int setns_entry(int fd, int nstype) { goto out; } - err = ops->install(new_nsproxy, ei->ns); + err = ops->install(new_nsproxy, reftask->nsproxy->mnt_ns); if (err) { (*free_nsproxy2)(new_nsproxy); goto out; } (*switch_task_namespaces2)(tsk, new_nsproxy); + return 0; out: - fput(file); - } + return err; - jprobe_return(); - return 0; } -static struct jprobe setns_jprobe = { - .entry = (kprobe_opcode_t *) setns_entry -}; - -static void __exit mntsu_exit(void) +static void __exit lxcsu_exit(void) { - unregister_jprobe(&setns_jprobe); - printk("Procprotect: Stopped mntsu.\n"); + remove_proc_entry("lxcsu",NULL); + printk("Procprotect: Stopped lxcsu.\n"); +} + +int lxcsu_write(struct file *file, const char *buffer, unsigned long count, void *data) { + char pidname[PATH_MAX]; + int pid; + struct pid *p; + char **s; + struct task_struct *task; + + if (current->nsproxy->mnt_ns!=init_task.nsproxy->mnt_ns) + return -EPERM; + + if (copy_from_user(pidname, buffer, count)) { + return -EFAULT; + } + if (count && (pidname[count-1]==10 || pidname[count-1]==13)) { + pidname[count-1]='\0'; + } + else + pidname[count]='\0'; + + pid = simple_strtol(pidname,s,10); + p = find_vpid(pid); + task = get_pid_task(p,PIDTYPE_PID); + if (task) { + setns(task); + } + else { + printk(KERN_CRIT "Task %d not found",pid); + } + + return count; } -static int __init mntsu_init(void) + +static int __init lxcsu_init(void) { int ret=0; - printk("Mntsu: starting mntsu version %s.\n", + printk("Mntsu: starting lxcsu version %s.\n", VERSION_STR); - proc_ns_fget2 = kallsyms_lookup_name("proc_ns_fget"); - printk(KERN_CRIT "proc_ns_fget = %x",proc_ns_fget2); - + free_nsproxy2 = kallsyms_lookup_name("free_nsproxy"); printk(KERN_CRIT "free_nsproxy = %x",free_nsproxy2); @@ -177,20 +192,10 @@ static int __init mntsu_init(void) put_mnt_ns2 = kallsyms_lookup_name("put_mnt_ns"); printk(KERN_CRIT "Put mnt ns = %x",put_mnt_ns2); - setns_jprobe.kp.addr = - (kprobe_opcode_t *) kallsyms_lookup_name("sys_setns"); - if (!setns_jprobe.kp.addr) { - printk("Couldn't find %s to plant jprobe\n", "do_execve"); - return -1; - } - - if ((ret = register_jprobe(&setns_jprobe)) <0) { - printk("register_jprobe failed, returned %d\n", ret); - return -1; - } - + proc_entry = create_proc_entry("lxcsu", 0644, NULL); + proc_entry->write_proc = lxcsu_write; return ret; } -module_init(mntsu_init); -module_exit(mntsu_exit); +module_init(lxcsu_init); +module_exit(lxcsu_exit);