diff -NurpP linux-2.6.18-vs2.1.1-rc39/fs/proc/base.c linux-2.6.18-vs2.1.1-rc39.1/fs/proc/base.c --- linux-2.6.18-vs2.1.1-rc39/fs/proc/base.c 2006-09-25 15:40:02 +0200 +++ linux-2.6.18-vs2.1.1-rc39.1/fs/proc/base.c 2006-10-14 19:52:29 +0200 @@ -74,6 +74,8 @@ #include #include #include +#include + #include "internal.h" /* NOTE: @@ -86,6 +88,9 @@ * in /proc for a task before it execs a suid executable. */ +struct pid fake_init_pid = { .nr = 1, .count = ATOMIC_INIT(1) }; +struct task_struct fake_init = FAKE_INIT_TASK(fake_init); + /* * For hysterical raisins we keep the same inumbers as in the old procfs. * Feel free to change the macro below - just keep the range distinct from @@ -2076,8 +2084,6 @@ out: return; } -#define VXF_FAKE_INIT (VXF_INFO_INIT|VXF_STATE_INIT) - static inline int proc_pid_visible(struct task_struct *task, int pid) { if ((pid == 1) && @@ -2118,6 +2125,13 @@ struct dentry *proc_pid_lookup(struct in if (tgid == ~0U) goto out; + if ((tgid == 1) && !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT)) { + // printk("··· providing fake init\n"); + task = &fake_init; + get_task_struct(task); + goto found; + } + rcu_read_lock(); task = find_task_by_pid(tgid); if (task) @@ -2126,6 +2140,8 @@ struct dentry *proc_pid_lookup(struct in if (!task) goto out; +found: + // printk("··· proc_pid_lookup %p[#%d]\n", task, task?task->pid:0); inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); if (!inode) goto out_put_task; @@ -2171,6 +2187,13 @@ static struct dentry *proc_task_lookup(s if (vx_current_initpid(tid)) goto out; + if ((tid == 1) && !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT)) { + // printk("··· task_lookup: providing fake init\n"); + task = &fake_init; + get_task_struct(task); + goto found; + } + rcu_read_lock(); task = find_task_by_pid(tid); if (task) @@ -2181,8 +2204,11 @@ static struct dentry *proc_task_lookup(s if (leader->tgid != task->tgid) goto out_drop_task; +found: + //printk("··· proc_task_lookup %p[#%d]\n", task, task?task->pid:0); inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO); - + /* if (tid==1) + printk("··· proc_task_lookup %p[#%d] = %p\n", task, task?task->pid:0, inode); */ if (!inode) goto out_drop_task; diff -NurpP linux-2.6.18-vs2.1.1-rc39/fs/proc/internal.h linux-2.6.18-vs2.1.1-rc39.1/fs/proc/internal.h --- linux-2.6.18-vs2.1.1-rc39/fs/proc/internal.h 2006-09-20 16:58:35 +0200 +++ linux-2.6.18-vs2.1.1-rc39.1/fs/proc/internal.h 2006-10-14 19:55:07 +0200 @@ -45,6 +45,7 @@ extern struct file_operations proc_maps_ extern struct file_operations proc_numa_maps_operations; extern struct file_operations proc_smaps_operations; +extern struct task_struct fake_init; void free_proc_entry(struct proc_dir_entry *de); @@ -55,9 +56,18 @@ static inline struct pid *proc_pid(struc return PROC_I(inode)->pid; } +#define VXF_FAKE_INIT (VXF_INFO_INIT|VXF_STATE_INIT) + static inline struct task_struct *get_proc_task(struct inode *inode) { - return get_pid_task(proc_pid(inode), PIDTYPE_PID); + struct pid *pid = proc_pid(inode); + + if ((pid->nr == 1) && !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT)) { + // printk("··· get_proc_task(1), providing fake init\n"); + get_task_struct(&fake_init); + return &fake_init; + } + return get_pid_task(pid, PIDTYPE_PID); } static inline int proc_fd(struct inode *inode) diff -NurpP linux-2.6.18-vs2.1.1-rc39/include/linux/init_task.h linux-2.6.18-vs2.1.1-rc39.1/include/linux/init_task.h --- linux-2.6.18-vs2.1.1-rc39/include/linux/init_task.h 2006-09-20 17:51:11 +0200 +++ linux-2.6.18-vs2.1.1-rc39.1/include/linux/init_task.h 2006-10-14 19:46:01 +0200 @@ -134,6 +134,64 @@ extern struct group_info init_groups; .nx_info = NULL, \ } +/* + * fake INIT_TASK + */ +#define FAKE_INIT_TASK(tsk) \ +{ \ + .pid = 1, \ + .thread_info = &init_thread_info, \ + .fs = NULL, \ + .files = NULL /* &fake_init_files */, \ + .signal = NULL /* &fake_init_signals */, \ + .sighand = NULL /* &fake_init_sighand */, \ + .group_info = &init_groups, \ + .mm = NULL, \ + .active_mm = NULL, \ + .journal_info = NULL, \ + .pids[PIDTYPE_PID] = { .pid = &fake_init_pid }, \ + .state = 0, \ + .usage = ATOMIC_INIT(2), \ + .flags = 0, \ + .lock_depth = -1, \ + .prio = MAX_PRIO-20, \ + .static_prio = MAX_PRIO-20, \ + .normal_prio = MAX_PRIO-20, \ + .policy = SCHED_NORMAL, \ + .cpus_allowed = CPU_MASK_ALL, \ + .run_list = LIST_HEAD_INIT(tsk.run_list), \ + .ioprio = 0, \ + .time_slice = HZ, \ + .tasks = LIST_HEAD_INIT(tsk.tasks), \ + .ptrace_children= LIST_HEAD_INIT(tsk.ptrace_children), \ + .ptrace_list = LIST_HEAD_INIT(tsk.ptrace_list), \ + .real_parent = &tsk, \ + .parent = &tsk, \ + .children = LIST_HEAD_INIT(tsk.children), \ + .sibling = LIST_HEAD_INIT(tsk.sibling), \ + .group_leader = &tsk, \ + .cap_effective = CAP_INIT_EFF_SET, \ + .cap_inheritable = CAP_INIT_INH_SET, \ + .cap_permitted = CAP_FULL_SET, \ + .keep_capabilities = 0, \ + .user = INIT_USER, \ + .comm = "init (fake)", \ + .thread = INIT_THREAD, \ + .pending = { \ + .list = LIST_HEAD_INIT(tsk.pending.list), \ + .signal = {{0}}}, \ + .blocked = {{0}}, \ + .alloc_lock = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock), \ + .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ + .fs_excl = ATOMIC_INIT(0), \ + .pi_lock = SPIN_LOCK_UNLOCKED, \ + INIT_TRACE_IRQFLAGS \ + INIT_LOCKDEP \ + .xid = 0, \ + .vx_info = NULL, \ + .nid = 0, \ + .nx_info = NULL, \ +} #define INIT_CPU_TIMERS(cpu_timers) \ { \