From: Sapan Bhatia Date: Thu, 16 Aug 2012 08:25:33 +0000 (-0400) Subject: Changed name to lxcsu, bug fixes X-Git-Tag: lxcsu-0.2-1~6 X-Git-Url: http://git.onelab.eu/?p=lxc-kernelspace-obsolete.git;a=commitdiff_plain;h=a9d6589acce0d5f0eab3f9948bb3562f754a8fd0 Changed name to lxcsu, bug fixes --- diff --git a/Makefile b/Makefile index 5f0bc71..e49bca6 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -obj-m += mntsu.o +obj-m += lxcsu.o all: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + make -C /lib/modules/3.4.7-1.fc16.x86_64/build M=$(PWD) modules clean: - make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean + make -C /lib/modules/3.4.7-1.fc16.x86_64/build M=$(PWD) clean diff --git a/lxcsu.c b/lxcsu.c new file mode 100644 index 0000000..fb0a34b --- /dev/null +++ b/lxcsu.c @@ -0,0 +1,198 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mount.h" + +#define VERSION_STR "0.0.1" + +#ifndef CONFIG_X86_64 +#error "This code does not support your architecture" +#endif + +MODULE_AUTHOR("Sapan Bhatia "); +MODULE_DESCRIPTION("Hack to enable mount namespace switching via setns. Based on a patch by Eric Biederman."); +MODULE_LICENSE("GPL"); +MODULE_VERSION(VERSION_STR); + +struct proc_dir_entry *proc_entry; + +static void *mntns_get(struct task_struct *task) +{ + struct mnt_namespace *ns; + rcu_read_lock(); + ns = task->nsproxy->mnt_ns; + atomic_inc(&ns->count); + rcu_read_unlock(); + return ns; +} + +void (*put_mnt_ns2)(struct mnt_namespace *ns); + +static void mntns_put(void *ns) +{ + (*put_mnt_ns2)(ns); +} + +static int mntns_install(struct nsproxy *nsproxy, void *ns) +{ + struct fs_struct *fs = current->fs; + struct mnt_namespace *mnt_ns = ns; + struct path root; + + if (fs->users != 1) + return -EINVAL; + + atomic_inc(&mnt_ns->count); + (*put_mnt_ns2)(nsproxy->mnt_ns); + nsproxy->mnt_ns = mnt_ns; + + 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)) + ; + + path_get(&root); + path_get(&root); + path_put(&fs->root); + path_put(&fs->pwd); + fs->root = root; + fs->pwd = root; + path_put(&root); + + return 0; +} + +const struct proc_ns_operations mntns_operations = { + .name = "mnt_ns", + .get = mntns_get, + .put = mntns_put, + .install = mntns_install, +}; + +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); diff --git a/procprotect.spec b/lxcsu.spec similarity index 100% rename from procprotect.spec rename to lxcsu.spec diff --git a/mntsu.c b/mntsu.c index ce35655..d16ad80 100644 --- a/mntsu.c +++ b/mntsu.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -40,57 +41,6 @@ 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; -} static void *mntns_get(struct task_struct *task) { @@ -102,9 +52,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,7 +69,7 @@ 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 */ @@ -146,5 +98,99 @@ const struct proc_ns_operations mntns_operations = { .install = mntns_install, }; +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) { + 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); + if (IS_ERR(new_nsproxy)) { + err = PTR_ERR(new_nsproxy); + goto out; + } + + err = ops->install(new_nsproxy, ei->ns); + if (err) { + (*free_nsproxy2)(new_nsproxy); + goto out; + } + (*switch_task_namespaces2)(tsk, new_nsproxy); +out: + fput(file); + } + + jprobe_return(); + return 0; +} + +static struct jprobe setns_jprobe = { + .entry = (kprobe_opcode_t *) setns_entry +}; + +static void __exit mntsu_exit(void) +{ + unregister_jprobe(&setns_jprobe); + printk("Procprotect: Stopped mntsu.\n"); +} + +static int __init mntsu_init(void) +{ + int ret=0; + printk("Mntsu: starting mntsu 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); + + 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); + + 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; + } + + return ret; +} + module_init(mntsu_init); module_exit(mntsu_exit);