diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/exec_domain.c | 12 | ||||
-rw-r--r-- | kernel/exit.c | 5 | ||||
-rw-r--r-- | kernel/fork.c | 1 | ||||
-rw-r--r-- | kernel/kmod.c | 49 | ||||
-rw-r--r-- | kernel/ksyms.c | 2 | ||||
-rw-r--r-- | kernel/ptrace.c | 8 | ||||
-rw-r--r-- | kernel/resource.c | 2 | ||||
-rw-r--r-- | kernel/sys.c | 19 | ||||
-rw-r--r-- | kernel/sysctl.c | 36 |
9 files changed, 105 insertions, 29 deletions
diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c index 4aa968ee1..c31678a4e 100644 --- a/kernel/exec_domain.c +++ b/kernel/exec_domain.c @@ -125,3 +125,15 @@ out: unlock_kernel(); return ret; } + +int get_exec_domain_list(char * page) +{ + int len = 0; + struct exec_domain * e; + + for (e=exec_domains; e && len < PAGE_SIZE - 80; e=e->next) + len += sprintf(page+len, "%d-%d\t%-16s\t[%s]\n", + e->pers_low, e->pers_high, e->name, + e->module ? e->module->name : "kernel"); + return len; +} diff --git a/kernel/exit.c b/kernel/exit.c index 2ca64035c..374241c67 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -402,6 +402,7 @@ fake_volatile: #ifdef CONFIG_BSD_PROCESS_ACCT acct_process(code); #endif + task_lock(tsk); sem_exit(); __exit_mm(tsk); #if CONFIG_AP1000 @@ -414,6 +415,7 @@ fake_volatile: tsk->state = TASK_ZOMBIE; tsk->exit_code = code; exit_notify(); + task_unlock(tsk); #ifdef DEBUG_PROC_TREE audit_ptree(); #endif @@ -455,6 +457,7 @@ asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struc add_wait_queue(¤t->wait_chldexit,&wait); repeat: flag = 0; + current->state = TASK_INTERRUPTIBLE; read_lock(&tasklist_lock); for (p = current->p_cptr ; p ; p = p->p_osptr) { if (pid>0) { @@ -521,12 +524,12 @@ repeat: retval = -ERESTARTSYS; if (signal_pending(current)) goto end_wait4; - current->state=TASK_INTERRUPTIBLE; schedule(); goto repeat; } retval = -ECHILD; end_wait4: + current->state = TASK_RUNNING; remove_wait_queue(¤t->wait_chldexit,&wait); return retval; } diff --git a/kernel/fork.c b/kernel/fork.c index 2cce575fc..a90a6bc47 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -650,6 +650,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs) p->p_cptr = NULL; init_waitqueue_head(&p->wait_chldexit); p->vfork_sem = NULL; + sema_init(&p->exit_sem, 1); p->sigpending = 0; sigemptyset(&p->signal); diff --git a/kernel/kmod.c b/kernel/kmod.c index 8b19e2415..36d754380 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -23,22 +23,36 @@ char modprobe_path[256] = "/sbin/modprobe"; static inline void -use_init_file_context(void) +use_init_fs_context(void) { - struct fs_struct * fs; - - lock_kernel(); + struct fs_struct *our_fs, *init_fs; /* - * Don't use the user's root, use init's root instead. - * Note that we can use "init_task" (which is not actually - * the same as the user-level "init" process) because we - * started "init" with a CLONE_FS + * Make modprobe's fs context be a copy of init's. + * + * We cannot use the user's fs context, because it + * may have a different root than init. + * Since init was created with CLONE_FS, we can grab + * its fs context from "init_task". + * + * The fs context has to be a copy. If it is shared + * with init, then any chdir() call in modprobe will + * also affect init and the other threads sharing + * init_task's fs context. + * + * We created the exec_modprobe thread without CLONE_FS, + * so we can update the fields in our fs context freely. */ - exit_fs(current); /* current->fs->count--; */ - fs = init_task.fs; - current->fs = fs; - atomic_inc(&fs->count); + lock_kernel(); + + our_fs = current->fs; + dput(our_fs->root); + dput(our_fs->pwd); + + init_fs = init_task.fs; + our_fs->umask = init_fs->umask; + our_fs->root = dget(init_fs->root); + our_fs->pwd = dget(init_fs->pwd); unlock_kernel(); } @@ -49,7 +63,10 @@ static int exec_modprobe(void * module_name) char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL }; int i; - use_init_file_context(); + current->session = 1; + current->pgrp = 1; + + use_init_fs_context(); /* Prevent parent user process from sending signals to child. Otherwise, if the modprobe program does not exist, it might @@ -104,7 +121,7 @@ int request_module(const char * module_name) return -EPERM; } - pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS); + pid = kernel_thread(exec_modprobe, (void*) module_name, 0); if (pid < 0) { printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid); return pid; @@ -126,8 +143,8 @@ int request_module(const char * module_name) spin_unlock_irq(¤t->sigmask_lock); if (waitpid_result != pid) { - printk (KERN_ERR "kmod: waitpid(%d,NULL,0) failed, returning %d.\n", - pid, waitpid_result); + printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n", + module_name, pid, -waitpid_result); } return 0; } diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 52952cf97..555e735d0 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -93,7 +93,6 @@ EXPORT_SYMBOL(exit_sighand); /* internal kernel memory management */ EXPORT_SYMBOL(__get_free_pages); -EXPORT_SYMBOL(__get_pages); EXPORT_SYMBOL(free_pages); EXPORT_SYMBOL(__free_page); EXPORT_SYMBOL(kmem_find_general_cachep); @@ -192,6 +191,7 @@ EXPORT_SYMBOL(posix_lock_file); EXPORT_SYMBOL(posix_test_lock); EXPORT_SYMBOL(posix_block_lock); EXPORT_SYMBOL(posix_unblock_lock); +EXPORT_SYMBOL(locks_mandatory_area); EXPORT_SYMBOL(dput); EXPORT_SYMBOL(put_cached_page); EXPORT_SYMBOL(is_root_busy); diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 4945a0223..2980059b2 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -50,15 +50,15 @@ repeat: flush_cache_page(vma, addr); if (write) { - maddr = kmap(page, KM_WRITE); + maddr = kmap(page); memcpy((char *)maddr + (addr & ~PAGE_MASK), buf, len); flush_page_to_ram(page); - kunmap(maddr, KM_WRITE); + kunmap(page); } else { - maddr = kmap(page, KM_READ); + maddr = kmap(page); memcpy(buf, (char *)maddr + (addr & ~PAGE_MASK), len); flush_page_to_ram(page); - kunmap(maddr, KM_READ); + kunmap(page); } return len; diff --git a/kernel/resource.c b/kernel/resource.c index 26ee5e29d..e3dd3a16d 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -20,7 +20,7 @@ struct resource iomem_resource = { "PCI mem", 0x00000000, 0xFFFFFFFF, IORESOURCE static rwlock_t resource_lock = RW_LOCK_UNLOCKED; /* - * This generates reports for /proc/ioports and /proc/memory + * This generates reports for /proc/ioports and /proc/iomem */ static char * do_resource_list(struct resource *entry, const char *fmt, int offset, char *buf, char *end) { diff --git a/kernel/sys.c b/kernel/sys.c index a0179d14e..344e56f35 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -896,6 +896,25 @@ asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim) ? -EFAULT : 0; } +/* + * Back compatibility for getrlimit. Needed for some apps. + */ + +asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim) +{ + struct rlimit x; + if (resource >= RLIM_NLIMITS) + return -EINVAL; + + memcpy(&x, current->rlim + resource, sizeof(*rlim)); + if(x.rlim_cur > 0x7FFFFFFF) + x.rlim_cur = 0x7FFFFFFF; + if(x.rlim_max > 0x7FFFFFFF) + x.rlim_max = 0x7FFFFFFF; + return copy_to_user(rlim, &x, sizeof(x))?-EFAULT:0; +} + + asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim) { struct rlimit new_rlim, *old_rlim; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 5b8638cdc..f18ad13c1 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -49,7 +49,11 @@ extern char modprobe_path[]; extern int sg_big_buff; #endif #ifdef CONFIG_SYSVIPC -extern int shmmax; +extern size_t shm_prm[]; +extern int msg_ctlmax; +extern int msg_ctlmnb; +extern int msg_ctlmni; +extern int sem_ctls[]; #endif #ifdef __sparc__ @@ -136,7 +140,7 @@ struct inode_operations proc_sys_inode_operations = NULL /* revalidate */ }; -extern struct proc_dir_entry proc_sys_root; +extern struct proc_dir_entry *proc_sys_root; static void register_proc_table(ctl_table *, struct proc_dir_entry *); static void unregister_proc_table(ctl_table *, struct proc_dir_entry *); @@ -213,7 +217,15 @@ static ctl_table kern_table[] = { {KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int), 0644, NULL, &proc_dointvec}, #ifdef CONFIG_SYSVIPC - {KERN_SHMMAX, "shmmax", &shmmax, sizeof (int), + {KERN_SHMMAX, "shmmax", &shm_prm, 3*sizeof (size_t), + 0644, NULL, &proc_doulongvec_minmax}, + {KERN_MSGMAX, "msgmax", &msg_ctlmax, sizeof (int), + 0644, NULL, &proc_dointvec}, + {KERN_MSGMNI, "msgmni", &msg_ctlmni, sizeof (int), + 0644, NULL, &proc_dointvec}, + {KERN_MSGMNB, "msgmnb", &msg_ctlmnb, sizeof (int), + 0644, NULL, &proc_dointvec}, + {KERN_SEM, "sem", &sem_ctls, 4*sizeof (int), 0644, NULL, &proc_dointvec}, #endif #ifdef CONFIG_MAGIC_SYSRQ @@ -285,7 +297,7 @@ static ctl_table dev_table[] = { void __init sysctl_init(void) { #ifdef CONFIG_PROC_FS - register_proc_table(root_table, &proc_sys_root); + register_proc_table(root_table, proc_sys_root); #endif } @@ -480,7 +492,7 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table, else DLIST_INSERT_BEFORE(&root_table_header, tmp, ctl_entry); #ifdef CONFIG_PROC_FS - register_proc_table(table, &proc_sys_root); + register_proc_table(table, proc_sys_root); #endif return tmp; } @@ -492,7 +504,7 @@ void unregister_sysctl_table(struct ctl_table_header * header) { DLIST_DELETE(header, ctl_entry); #ifdef CONFIG_PROC_FS - unregister_proc_table(header->ctl_table, &proc_sys_root); + unregister_proc_table(header->ctl_table, proc_sys_root); #endif kfree(header); } @@ -1067,6 +1079,12 @@ int proc_dointvec(ctl_table *table, int write, struct file *filp, return -ENOSYS; } +int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + return -ENOSYS; +} + int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, void *buffer, size_t *lenp) { @@ -1312,6 +1330,12 @@ int proc_dointvec(ctl_table *table, int write, struct file *filp, return -ENOSYS; } +int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + return -ENOSYS; +} + int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, void *buffer, size_t *lenp) { |