Always keep a page mapped at EA 0. Right now it is shared among all processes, as long as noone does a NULL pointer deref and uses the data there, there should be no security implications. Still, this is better not used in any kind of environment where users can't be trusted.
Index: mainline/arch/powerpc/kernel/process.c =================================================================== --- mainline.orig/arch/powerpc/kernel/process.c +++ mainline/arch/powerpc/kernel/process.c @@ -330,6 +330,14 @@ struct task_struct *__switch_to(struct t calculate_steal_time(); last = _switch(old_thread, new_thread); + /* current is still really us, just a different us :-) */ + if (current->mm) { +#ifdef CONFIG_PPC_HAS_HASH_64K + __hash_page_64K(0, _PAGE_USER|_PAGE_RW, get_vsid(current->mm->context.id, 0), ¤t->zero_pte.pte, 0x300, 1); +#else + __hash_page_4K(0, _PAGE_USER|_PAGE_RW, get_vsid(current->mm->context.id, 0), ¤t->zero_pte, 0x300, 1); +#endif + } local_irq_restore(flags); Index: mainline/kernel/fork.c =================================================================== --- mainline.orig/kernel/fork.c +++ mainline/kernel/fork.c @@ -104,8 +104,12 @@ struct kmem_cache *vm_area_cachep; /* SLAB cache for mm_struct structures (tsk->mm) */ static struct kmem_cache *mm_cachep; +static struct page *zero_page; + void free_task(struct task_struct *tsk) { + if (tsk->mm) + flush_hash_page(get_vsid(tsk->mm->context.id, 0) << 28, tsk->zero_pte, MMU_PAGE_4K, 0); free_thread_info(tsk->stack); rt_mutex_debug_task_free(tsk); free_task_struct(tsk); @@ -156,6 +160,8 @@ void __init fork_init(unsigned long memp init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2; init_task.signal->rlim[RLIMIT_SIGPENDING] = init_task.signal->rlim[RLIMIT_NPROC]; + + zero_page = alloc_page(GFP_KERNEL); } static struct task_struct *dup_task_struct(struct task_struct *orig) @@ -182,6 +188,11 @@ static struct task_struct *dup_task_stru #ifdef CONFIG_CC_STACKPROTECTOR tsk->stack_canary = get_random_int(); #endif +#ifdef CONFIG_PPC_64K_PAGES + tsk->zero_pte.pte = mk_pte(zero_page,_PAGE_BASE|_PAGE_RW|_PAGE_USER|_PAGE_EXEC); +#else + tsk->zero_pte = mk_pte(zero_page,_PAGE_BASE|_PAGE_RW|_PAGE_USER|_PAGE_EXEC); +#endif /* One for us, one for whoever does the "release_task()" (usually parent) */ atomic_set(&tsk->usage,2); Index: mainline/include/linux/sched.h =================================================================== --- mainline.orig/include/linux/sched.h +++ mainline/include/linux/sched.h @@ -863,6 +863,7 @@ struct task_struct { struct list_head ptrace_list; struct mm_struct *mm, *active_mm; + real_pte_t zero_pte; /* task state */ struct linux_binfmt *binfmt; -- _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev