X-Git-Url: http://git.onelab.eu/?p=lxc-kernelspace-obsolete.git;a=blobdiff_plain;f=mntsu.c;h=34cfb5611d83e2140bb24de8a000cbc59478c19e;hp=ce3565550c7fbdf94056769e1d0bb54ceea83539;hb=HEAD;hpb=84ceafa307dc65ec34ff0a20acfe90984374b8ce diff --git a/mntsu.c b/mntsu.c index ce35655..34cfb56 100644 --- a/mntsu.c +++ b/mntsu.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -40,57 +41,7 @@ MODULE_DESCRIPTION("Hack to enable mount namespace switching via setns. Based on MODULE_LICENSE("GPL"); MODULE_VERSION(VERSION_STR); -static int setns_entry(struct kretprobe_instance *ri, struct pt_regs *regs) { - int nstype = regs->si; - printk(KERN_CRIT "nstype: %d",nstype); - - if (nstype==666) regs->si = 0; - return 0; -} - -static int setns_ret(struct kretprobe_instance *ri, struct pt_regs *regs) -{ - int nstype = regs->si; - printk(KERN_CRIT "nstype 2: %d",nstype); - - return 0; -} - -static struct kretprobe setns_probe = { - .entry_handler = (kprobe_opcode_t *) setns_entry, - .handler = (kprobe_opcode_t *) setns_ret, - .maxactive = 20, - .data_size = 0 -}; - -static void __exit mntsu_exit(void) -{ - unregister_kretprobe(&setns_probe); - printk("Procprotect: Stopped mntsu.\n"); -} - -static int __init mntsu_init(void) -{ - int ret=0; -printk("Mntsu: starting mntsu version %s.\n", - VERSION_STR); - - setns_probe.kp.addr = - (kprobe_opcode_t *) kallsyms_lookup_name("sys_setns"); - if (!setns_probe.kp.addr) { - printk("Couldn't find %s to plant kretprobe\n", "do_execve"); - return -1; - } - - if ((ret = register_kretprobe(&setns_probe)) <0) { - printk("register_kretprobe failed, returned %d\n", ret); - return -1; - } - printk("Planted kretprobe at %p, handler addr %p\n", - setns_probe.kp.addr, setns_probe.handler); - - return ret; -} +struct proc_dir_entry *proc_entry; static void *mntns_get(struct task_struct *task) { @@ -102,9 +53,11 @@ static void *mntns_get(struct task_struct *task) return ns; } +void (*put_mnt_ns2)(struct mnt_namespace *ns); + static void mntns_put(void *ns) { - put_mnt_ns(ns); + (*put_mnt_ns2)(ns); } static int mntns_install(struct nsproxy *nsproxy, void *ns) @@ -117,17 +70,15 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) return -EINVAL; atomic_inc(&mnt_ns->count); - put_mnt_ns(nsproxy->mnt_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); @@ -146,5 +97,105 @@ const struct proc_ns_operations mntns_operations = { .install = mntns_install, }; -module_init(mntsu_init); -module_exit(mntsu_exit); +void (*free_nsproxy2)(struct nsproxy *ns); + +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(struct task_struct *reftask) { + const struct proc_ns_operations *ops; + struct task_struct *tsk = current; + struct nsproxy *new_nsproxy; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + err = -EINVAL; + ops = &mntns_operations; + + new_nsproxy = (*create_new_namespaces)(0, tsk, tsk->fs); + if (IS_ERR(new_nsproxy)) { + err = PTR_ERR(new_nsproxy); + goto out; + } + + 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: + return err; + +} + +static void __exit lxcsu_exit(void) +{ + 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 lxcsu_init(void) +{ + int ret=0; + printk("Mntsu: starting lxcsu version %s.\n", + VERSION_STR); + + + free_nsproxy2 = kallsyms_lookup_name("free_nsproxy"); + printk(KERN_CRIT "free_nsproxy = %x",free_nsproxy2); + + switch_task_namespaces2 = kallsyms_lookup_name("switch_task_namespaces"); + printk(KERN_CRIT "switch_task_namespaces = %x",switch_task_namespaces2); + + create_new_namespaces = kallsyms_lookup_name("create_new_namespaces"); + printk(KERN_CRIT "create_new_namespaces = %x",create_new_namespaces); + + put_mnt_ns2 = kallsyms_lookup_name("put_mnt_ns"); + printk(KERN_CRIT "Put mnt ns = %x",put_mnt_ns2); + + proc_entry = create_proc_entry("lxcsu", 0644, NULL); + proc_entry->write_proc = lxcsu_write; + return ret; +} + +module_init(lxcsu_init); +module_exit(lxcsu_exit);