From: Philip Homburg Date: Fri, 20 Oct 2006 14:42:48 +0000 (+0000) Subject: Initialize priv from user supplied priv structure in SYS_PRIV_INIT. X-Git-Tag: v3.1.3~167 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/doc/spin.js?a=commitdiff_plain;h=dd3ee082b2ef24db6e244753a8a4c713cc14017f;p=minix.git Initialize priv from user supplied priv structure in SYS_PRIV_INIT. Added SYS_PRIV_USER call to downgrade a privileged process to a user process. --- diff --git a/include/minix/com.h b/include/minix/com.h index 39edd36d2..1705d128b 100755 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -315,6 +315,9 @@ #define SYS_PRIV_ADD_MEM 3 /* Add memory range (struct mem_range) */ #define SYS_PRIV_ADD_IRQ 4 /* Add IRQ */ +#define SYS_PRIV_USER 5 /* Make a process an oridinary user + * process. + */ /* Subfunctions for SYS_SETGRANT */ #define SYS_PARAM_SET_GRANT 1 /* Set address and size of grant table */ diff --git a/kernel/system/do_privctl.c b/kernel/system/do_privctl.c index b84ca435b..b9943e66b 100644 --- a/kernel/system/do_privctl.c +++ b/kernel/system/do_privctl.c @@ -32,6 +32,7 @@ message *m_ptr; /* pointer to request message */ phys_bytes caller_phys, kernel_phys; struct io_range io_range; struct mem_range mem_range; + struct priv priv; /* Check whether caller is allowed to make this call. Privileged proceses * can only update the privileges of processes that are inhibited from @@ -87,11 +88,70 @@ message *m_ptr; /* pointer to request message */ priv(rp)->s_grant_table= 0; priv(rp)->s_grant_entries= 0; + if (m_ptr->CTL_ARG_PTR) + { + /* Copy privilege structure from caller */ + caller_phys = umap_local(caller_ptr, D, + (vir_bytes) m_ptr->CTL_ARG_PTR, sizeof(priv)); + if (caller_phys == 0) + return EFAULT; + kernel_phys = vir2phys(&priv); + phys_copy(caller_phys, kernel_phys, sizeof(priv)); + + /* Copy the call mask */ + for (i= 0; is_k_call_mask[i]= priv.s_k_call_mask[i]; + + /* Copy IRQs */ + if (priv.s_nr_irq < 0 || priv.s_nr_irq > NR_IRQ) + return EINVAL; + priv(rp)->s_nr_irq= priv.s_nr_irq; + for (i= 0; is_irq_tab[i]= priv.s_irq_tab[i]; + kprintf("do_privctl: adding IRQ %d\n", + priv(rp)->s_irq_tab[i]); + } + + priv(rp)->s_flags |= CHECK_IRQ; /* Check requests for IRQs */ + + /* Copy I/O ranges */ + if (priv.s_nr_io_range < 0 || priv.s_nr_io_range > NR_IO_RANGE) + return EINVAL; + priv(rp)->s_nr_io_range= priv.s_nr_io_range; + for (i= 0; is_io_tab[i]= priv.s_io_tab[i]; + kprintf("do_privctl: adding I/O range [%x..%x]\n", + priv(rp)->s_io_tab[i].ior_base, + priv(rp)->s_io_tab[i].ior_limit); + } + + /* Check requests for IRQs */ + priv(rp)->s_flags |= CHECK_IO_PORT; + + memcpy(priv(rp)->s_k_call_mask, priv.s_k_call_mask, + sizeof(priv(rp)->s_k_call_mask)); + } + + /* Done. Privileges have been set. Allow process to run again. */ + old_flags = rp->p_rts_flags; /* save value of the flags */ + rp->p_rts_flags &= ~NO_PRIV; + if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp); + return(OK); + case SYS_PRIV_USER: + if (! (rp->p_rts_flags & NO_PRIV)) return(EPERM); + + /* Make this process an ordinary user process. + */ + if ((i=get_priv(rp, 0)) != OK) return(i); + /* Done. Privileges have been set. Allow process to run again. */ old_flags = rp->p_rts_flags; /* save value of the flags */ rp->p_rts_flags &= ~NO_PRIV; if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp); return(OK); + case SYS_PRIV_ADD_IO: if (rp->p_rts_flags & NO_PRIV) return(EPERM);