First commit of mntsu tool
[lxc-kernelspace-obsolete.git] / mntsu.c
1 #include <linux/module.h>
2 #include <linux/moduleparam.h>
3 #include <linux/types.h>
4 #include <linux/kernel.h>
5 #include <linux/fs_struct.h>
6 #include <linux/fs.h>
7 #include <linux/mm.h>
8 #include <linux/reboot.h>
9 #include <linux/delay.h>
10 #include <linux/proc_fs.h>
11 #include <asm/uaccess.h>
12 #include <linux/sysrq.h>
13 #include <linux/timer.h>
14 #include <linux/time.h>
15 #include <linux/lglock.h>
16 #include <linux/init.h>
17 #include <linux/idr.h>
18 #include <linux/namei.h>
19 #include <linux/bitops.h>
20 #include <linux/mnt_namespace.h>
21 #include <linux/path.h>
22 #include <linux/dcache.h>
23 #include <linux/spinlock.h>
24 #include <linux/completion.h>
25 #include <linux/sched.h>
26 #include <linux/seq_file.h>
27 #include <linux/kprobes.h>
28 #include <linux/kallsyms.h>
29 #include <linux/nsproxy.h>
30 #include "mount.h"
31
32 #define VERSION_STR "0.0.1"
33
34 #ifndef CONFIG_X86_64
35 #error "This code does not support your architecture"
36 #endif
37
38 MODULE_AUTHOR("Sapan Bhatia <sapanb@cs.princeton.edu>");
39 MODULE_DESCRIPTION("Hack to enable mount namespace switching via setns. Based on a patch by Eric Biederman.");
40 MODULE_LICENSE("GPL");
41 MODULE_VERSION(VERSION_STR);
42
43 static int setns_entry(struct kretprobe_instance *ri, struct pt_regs *regs) {
44         int nstype = regs->si;
45     printk(KERN_CRIT "nstype: %d",nstype);
46
47     if (nstype==666) regs->si = 0;
48         return 0;
49 }
50
51 static int setns_ret(struct kretprobe_instance *ri, struct pt_regs *regs)
52 {
53     int nstype = regs->si;
54     printk(KERN_CRIT "nstype 2: %d",nstype);
55         
56         return 0;
57 }
58
59 static struct kretprobe setns_probe = {
60         .entry_handler = (kprobe_opcode_t *) setns_entry,
61         .handler = (kprobe_opcode_t *) setns_ret,
62         .maxactive = 20,
63         .data_size = 0
64 };
65
66 static void __exit mntsu_exit(void)
67 {
68         unregister_kretprobe(&setns_probe);
69         printk("Procprotect: Stopped mntsu.\n");
70 }
71
72 static int __init mntsu_init(void)
73 {
74                 int ret=0;
75 printk("Mntsu: starting mntsu version %s.\n",
76                VERSION_STR);
77
78           setns_probe.kp.addr = 
79                   (kprobe_opcode_t *) kallsyms_lookup_name("sys_setns");
80           if (!setns_probe.kp.addr) {
81                   printk("Couldn't find %s to plant kretprobe\n", "do_execve");
82                   return -1;
83           }
84   
85           if ((ret = register_kretprobe(&setns_probe)) <0) {
86                   printk("register_kretprobe failed, returned %d\n", ret);
87                   return -1;
88           }
89           printk("Planted kretprobe at %p, handler addr %p\n",
90                  setns_probe.kp.addr, setns_probe.handler);
91
92         return ret;
93 }
94
95 static void *mntns_get(struct task_struct *task)
96 {
97        struct mnt_namespace *ns;
98        rcu_read_lock();
99        ns = task->nsproxy->mnt_ns;
100        atomic_inc(&ns->count);
101        rcu_read_unlock();
102        return ns;
103 }
104
105 static void mntns_put(void *ns)
106 {
107        put_mnt_ns(ns);
108 }
109
110 static int mntns_install(struct nsproxy *nsproxy, void *ns)
111 {
112        struct fs_struct *fs = current->fs;
113        struct mnt_namespace *mnt_ns = ns;
114        struct path root;
115
116        if (fs->users != 1)
117                return -EINVAL;
118
119        atomic_inc(&mnt_ns->count);
120        put_mnt_ns(nsproxy->mnt_ns);
121        nsproxy->mnt_ns = mnt_ns;
122
123        /* Find the root */
124        root.mnt    = mnt_ns->root;
125        root.dentry = mnt_ns->root->mnt.mnt_root;
126        path_get(&root);
127        while(d_mountpoint(root.dentry) && follow_down(&root))
128                ;
129
130        /* Update the pwd and root */
131        path_get(&root);
132        path_get(&root);
133        path_put(&fs->root);
134        path_put(&fs->pwd);
135        fs->root = root;
136        fs->pwd  = root;
137        path_put(&root);
138
139        return 0;
140 }
141
142 const struct proc_ns_operations mntns_operations = {
143        .name           = "mnt_ns",
144        .get            = mntns_get,
145        .put            = mntns_put,
146        .install        = mntns_install,
147 };
148
149 module_init(mntsu_init);
150 module_exit(mntsu_exit);