X-Git-Url: http://git.onelab.eu/?p=lxc-kernelspace-obsolete.git;a=blobdiff_plain;f=pidsu.c;fp=pidsu.c;h=fa0913344a8171c72e42da83b2d31ed2ac8e6f26;hp=0000000000000000000000000000000000000000;hb=7fc32ca36e05b7abb54df84fd5fd3664a62c7784;hpb=d905f603a2178bf63dcc0a49dbcdf15c922a849a diff --git a/pidsu.c b/pidsu.c new file mode 100644 index 0000000..fa09133 --- /dev/null +++ b/pidsu.c @@ -0,0 +1,205 @@ +#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 pid namespace switching via setns. Based on a patch by Eric Biederman."); +MODULE_LICENSE("GPL"); +MODULE_VERSION(VERSION_STR); + +struct proc_dir_entry *proc_entry; + +/* + * Pid namespaces + * + * Authors: + * (C) 2007 Pavel Emelyanov , OpenVZ, SWsoft Inc. + * (C) 2007 Sukadev Bhattiprolu , IBM + * Many thanks to Oleg Nesterov for comments and help + * + */ + +#define BITS_PER_PAGE (PAGE_SIZE*8) + +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); +void (*free_pid_ns2)(struct kref *kref); + + +struct pid_cache { + int nr_ids; + char name[16]; + struct kmem_cache *cachep; + struct list_head list; +}; + +static LIST_HEAD(pid_caches_lh); +static DEFINE_MUTEX(pid_caches_mutex); + +static void *pidns_get(struct task_struct *task) +{ + struct pid_namespace *ns; + + rcu_read_lock(); + ns = get_pid_ns(task_active_pid_ns(task)); + rcu_read_unlock(); + + return ns; +} + +static void pidns_put(void *ns) +{ + struct pid_namespace *pidns = ns; + if (pidns != &init_pid_ns) + kref_put(&pidns->kref, free_pid_ns2); +} + +static int pidns_install(struct nsproxy *nsproxy, void *ns) +{ + printk(KERN_CRIT "Entering pid ns"); + pidns_put(nsproxy->pid_ns); + nsproxy->pid_ns = get_pid_ns(ns); + return 0; +} + +const struct proc_ns_operations pidns_operations = { + .name = "pid", + .type = CLONE_NEWPID, + .get = pidns_get, + .put = pidns_put, + .install = pidns_install, +}; + +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 = &pidns_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->pid_ns); + if (err) { + (*free_nsproxy2)(new_nsproxy); + goto out; + } + (*switch_task_namespaces2)(tsk, new_nsproxy); + return 0; +out: + return err; + +} + +static void __exit pidsu_exit(void) +{ + remove_proc_entry("pidsu",NULL); + printk("Procprotect: Stopped pidsu.\n"); +} + +int pidsu_write(struct file *file, const char *buffer, unsigned long count, void *data) { + char pidname[80]; + int pid; + struct pid *p; + char **s; + struct task_struct *task; + + if (current->nsproxy->pid_ns!=init_task.nsproxy->pid_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 pidsu_init(void) +{ + int ret=0; + printk("Mntsu: starting pidsu version %s.\n", + VERSION_STR); + + free_pid_ns2 = kallsyms_lookup_name("free_pid_ns"); + printk(KERN_CRIT "free_pid_ns = %x",free_pid_ns2); + + free_nsproxy2 = kallsyms_lookup_name("free_nsproxy"); + printk(KERN_CRIT "free_nsproxy = %x",(unsigned int) free_nsproxy2); + + switch_task_namespaces2 = kallsyms_lookup_name("switch_task_namespaces"); + printk(KERN_CRIT "switch_task_namespaces = %x",(unsigned int) switch_task_namespaces2); + + create_new_namespaces = kallsyms_lookup_name("create_new_namespaces"); + printk(KERN_CRIT "create_new_namespaces = %x",(unsigned int) create_new_namespaces); + + /*put_pid_ns2 = kallsyms_lookup_name("put_pid_ns"); + printk(KERN_CRIT "Put pid ns = %x",put_pid_ns2);*/ + + proc_entry = create_proc_entry("pidsu", 0644, NULL); + proc_entry->write_proc = pidsu_write; + return ret; +} + +module_init(pidsu_init); +module_exit(pidsu_exit);