Changed name to lxcsu, bug fixes
[lxc-kernelspace-obsolete.git] / mntsu.c
diff --git a/mntsu.c b/mntsu.c
index ce35655..d16ad80 100644 (file)
--- a/mntsu.c
+++ b/mntsu.c
@@ -24,6 +24,7 @@
 #include <linux/completion.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
+#include <linux/file.h>
 #include <linux/kprobes.h>
 #include <linux/kallsyms.h>
 #include <linux/nsproxy.h>
@@ -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);