From 546db14ee74118296f425f3b91634fb767d67290 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 27 Jan 2000 01:05:20 +0000 Subject: Merge with Linux 2.3.23. The new bootmem stuff has broken various platforms. At this time I've only verified that IP22 support compiles and IP27 actually works. --- kernel/exit.c | 34 ++++++++++++++++++++++++++++++---- kernel/fork.c | 11 ++++++++--- kernel/ksyms.c | 8 +++++++- kernel/ptrace.c | 48 +++++++++++++++++++++++++----------------------- kernel/time.c | 22 +++++++++++++--------- 5 files changed, 83 insertions(+), 40 deletions(-) (limited to 'kernel') diff --git a/kernel/exit.c b/kernel/exit.c index 39103a683..2ca64035c 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -135,7 +135,9 @@ static inline void forget_original_parent(struct task_struct * father) read_lock(&tasklist_lock); for_each_task(p) { if (p->p_opptr == father) { + /* We dont want people slaying init */ p->exit_signal = SIGCHLD; + p->self_exec_id++; p->p_opptr = child_reaper; /* init */ if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0); } @@ -288,7 +290,7 @@ void exit_mm(struct task_struct *tsk) */ static void exit_notify(void) { - struct task_struct * p; + struct task_struct * p, *t; forget_original_parent(current); /* @@ -300,15 +302,39 @@ static void exit_notify(void) * and we were the only connection outside, so our pgrp * is about to become orphaned. */ - if ((current->p_pptr->pgrp != current->pgrp) && - (current->p_pptr->session == current->session) && + + t = current->p_pptr; + + if ((t->pgrp != current->pgrp) && + (t->session == current->session) && will_become_orphaned_pgrp(current->pgrp, current) && has_stopped_jobs(current->pgrp)) { kill_pg(current->pgrp,SIGHUP,1); kill_pg(current->pgrp,SIGCONT,1); } - /* Let father know we died */ + /* Let father know we died + * + * Thread signals are configurable, but you aren't going to use + * that to send signals to arbitary processes. + * That stops right now. + * + * If the parent exec id doesn't match the exec id we saved + * when we started then we know the parent has changed security + * domain. + * + * If our self_exec id doesn't match our parent_exec_id then + * we have changed execution domain as these two values started + * the same after a fork. + * + */ + + if(current->exit_signal != SIGCHLD && + ( current->parent_exec_id != t->self_exec_id || + current->self_exec_id != current->parent_exec_id) + && !capable(CAP_KILL)) + current->exit_signal = SIGCHLD; + notify_parent(current, current->exit_signal); /* diff --git a/kernel/fork.c b/kernel/fork.c index e341615f2..9f3d9f507 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -19,8 +19,8 @@ #include #include -#include #include +#include /* The idle threads do not count.. */ int nr_threads=0; @@ -157,7 +157,7 @@ int alloc_uid(struct task_struct *p) return 0; } -void __init fork_init(unsigned long memsize) +void __init fork_init(unsigned long mempages) { int i; @@ -175,7 +175,7 @@ void __init fork_init(unsigned long memsize) * value: the thread structures can take up at most half * of memory. */ - max_threads = memsize / THREAD_SIZE / 2; + max_threads = mempages / (THREAD_SIZE/PAGE_SIZE) / 2; init_task.rlim[RLIMIT_NPROC].rlim_cur = max_threads/2; init_task.rlim[RLIMIT_NPROC].rlim_max = max_threads/2; @@ -693,6 +693,11 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs) if (retval) goto bad_fork_cleanup_sighand; p->semundo = NULL; + + /* Our parent execution domain becomes current domain + These must match for thread signalling to apply */ + + p->parent_exec_id = p->self_exec_id; /* ok, now we should be set up.. */ p->swappable = 1; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 910341fc6..d4480e717 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -118,11 +119,13 @@ EXPORT_SYMBOL(in_group_p); EXPORT_SYMBOL(update_atime); EXPORT_SYMBOL(get_super); EXPORT_SYMBOL(get_fs_type); +EXPORT_SYMBOL(get_empty_super); +EXPORT_SYMBOL(remove_vfsmnt); EXPORT_SYMBOL(getname); EXPORT_SYMBOL(_fput); EXPORT_SYMBOL(igrab); EXPORT_SYMBOL(iunique); -EXPORT_SYMBOL(iget); +EXPORT_SYMBOL(iget4); EXPORT_SYMBOL(iput); EXPORT_SYMBOL(__namei); EXPORT_SYMBOL(lookup_dentry); @@ -140,6 +143,9 @@ EXPORT_SYMBOL(d_lookup); EXPORT_SYMBOL(d_path); EXPORT_SYMBOL(__mark_buffer_dirty); EXPORT_SYMBOL(__mark_inode_dirty); +EXPORT_SYMBOL(free_kiovec); +EXPORT_SYMBOL(brw_kiovec); +EXPORT_SYMBOL(alloc_kiovec); EXPORT_SYMBOL(get_empty_filp); EXPORT_SYMBOL(init_private_file); EXPORT_SYMBOL(filp_open); diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 35fa9768d..4945a0223 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include @@ -23,7 +23,9 @@ static int access_one_page(struct task_struct * tsk, struct vm_area_struct * vma pgd_t * pgdir; pmd_t * pgmiddle; pte_t * pgtable; - unsigned long page; + unsigned long mapnr; + unsigned long maddr; + struct page *page; repeat: pgdir = pgd_offset(vma->vm_mm, addr); @@ -39,27 +41,25 @@ repeat: pgtable = pte_offset(pgmiddle, addr); if (!pte_present(*pgtable)) goto fault_in_page; - page = pte_page(*pgtable); + mapnr = pte_pagenr(*pgtable); if (write && (!pte_write(*pgtable) || !pte_dirty(*pgtable))) goto fault_in_page; - if (MAP_NR(page) >= max_mapnr) + if (mapnr >= max_mapnr) return 0; + page = mem_map + mapnr; flush_cache_page(vma, addr); - { - void *src = (void *) (page + (addr & ~PAGE_MASK)); - void *dst = buf; - if (write) { - dst = src; - src = buf; - } - src = (void *) kmap((unsigned long) src, KM_READ); - dst = (void *) kmap((unsigned long) dst, KM_WRITE); - memcpy(dst, src, len); - kunmap((unsigned long) src, KM_READ); - kunmap((unsigned long) dst, KM_WRITE); + if (write) { + maddr = kmap(page, KM_WRITE); + memcpy((char *)maddr + (addr & ~PAGE_MASK), buf, len); + flush_page_to_ram(page); + kunmap(maddr, KM_WRITE); + } else { + maddr = kmap(page, KM_READ); + memcpy(buf, (char *)maddr + (addr & ~PAGE_MASK), len); + flush_page_to_ram(page); + kunmap(maddr, KM_READ); } - flush_page_to_ram(page); return len; fault_in_page: @@ -69,23 +69,25 @@ fault_in_page: return 0; bad_pgd: - printk("ptrace: bad pgd in '%s' at %08lx (%08lx)\n", tsk->comm, addr, pgd_val(*pgdir)); + pgd_ERROR(*pgdir); return 0; bad_pmd: - printk("ptrace: bad pmd in '%s' at %08lx (%08lx)\n", tsk->comm, addr, pmd_val(*pgmiddle)); + pmd_ERROR(*pgmiddle); return 0; } int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) { int copied; - struct vm_area_struct * vma = find_extend_vma(tsk, addr); - - if (!vma) - return 0; + struct vm_area_struct * vma; down(&tsk->mm->mmap_sem); + vma = find_extend_vma(tsk, addr); + if (!vma) { + up(&tsk->mm->mmap_sem); + return 0; + } copied = 0; for (;;) { unsigned long offset = addr & ~PAGE_MASK; diff --git a/kernel/time.c b/kernel/time.c index 1517d6d9d..3585e1cc8 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -54,6 +54,10 @@ void get_fast_time(struct timeval * t) do_get_fast_time(t); } +/* The xtime_lock is not only serializing the xtime read/writes but it's also + serializing all accesses to the global NTP variables now. */ +extern rwlock_t xtime_lock; + #if !defined(__alpha__) && !defined(__ia64__) /* @@ -93,14 +97,14 @@ asmlinkage long sys_stime(int * tptr) return -EPERM; if (get_user(value, tptr)) return -EFAULT; - cli(); + write_lock_irq(&xtime_lock); xtime.tv_sec = value; xtime.tv_usec = 0; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - sti(); + write_unlock_irq(&xtime_lock); return 0; } @@ -139,9 +143,9 @@ asmlinkage long sys_gettimeofday(struct timeval *tv, struct timezone *tz) */ inline static void warp_clock(void) { - cli(); + write_lock_irq(&xtime_lock); xtime.tv_sec += sys_tz.tz_minuteswest * 60; - sti(); + write_unlock_irq(&xtime_lock); } /* @@ -222,7 +226,7 @@ void (*hardpps_ptr)(struct timeval *) = (void (*)(struct timeval *))0; int do_adjtimex(struct timex *txc) { long ltemp, mtemp, save_adjust; - int result = time_state; /* mostly `TIME_OK' */ + int result; /* In order to modify anything, you gotta be super-user! */ if (txc->modes && !capable(CAP_SYS_TIME)) @@ -240,7 +244,8 @@ int do_adjtimex(struct timex *txc) if (txc->tick < 900000/HZ || txc->tick > 1100000/HZ) return -EINVAL; - cli(); /* SMP: global cli() is enough protection. */ + write_lock_irq(&xtime_lock); + result = time_state; /* mostly `TIME_OK' */ /* Save for later - semantics of adjtime is to return old value */ save_adjust = time_adjust; @@ -385,7 +390,6 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0 txc->constant = time_constant; txc->precision = time_precision; txc->tolerance = time_tolerance; - do_gettimeofday(&txc->time); txc->tick = tick; txc->ppsfreq = pps_freq; txc->jitter = pps_jitter >> PPS_AVG; @@ -395,8 +399,8 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0 txc->calcnt = pps_calcnt; txc->errcnt = pps_errcnt; txc->stbcnt = pps_stbcnt; - - sti(); + write_unlock_irq(&xtime_lock); + do_gettimeofday(&txc->time); return(result); } -- cgit v1.2.3