minix/kernel/arch/i386/do_iopenable.c
David van Moolenbroek c51cd5fe91 Server/driver protocols: no longer allow third-party copies.
Before safecopies, the IO_ENDPT and DL_ENDPT message fields were needed
to know which actual process to copy data from/to, as that process may
not always be the caller. Now that we have full safecopy support, these
fields have become useless for that purpose: the owner of the grant is
*always* the caller. Allowing the caller to supply another endpoint is
in fact dangerous, because the callee may then end up using a grant
from a third party. One could call this a variant of the confused
deputy problem.

From now on, safecopy calls should always use the caller's endpoint as
grant owner. This fully obsoletes the DL_ENDPT field in the
inet/ethernet protocol. IO_ENDPT has other uses besides identifying the
grant owner though. This patch renames IO_ENDPT to USER_ENDPT, not only
because that is a more fitting name (it should never be used for I/O
after all), but also in order to intentionally break any old system
source code outside the base system. If this patch breaks your code,
fixing it is fairly simple:

- DL_ENDPT should be replaced with m_source;
- IO_ENDPT should be replaced with m_source when used for safecopies;
- IO_ENDPT should be replaced with USER_ENDPT for any other use, e.g.
  when setting REP_ENDPT, matching requests in CANCEL calls, getting
  DEV_SELECT flags, and retrieving of the real user process's endpoint
  in DEV_OPEN.

The changes in this patch are binary backward compatible.
2011-04-11 17:35:05 +00:00

37 lines
908 B
C

/* The system call implemented in this file:
* m_type: SYS_IOPENABLE
*
* The parameters for this system call are:
* m2_i2: IOP_ENDPT (process to give I/O Protection Level bits)
*
* Author:
* Jorrit N. Herder <jnherder@cs.vu.nl>
*/
#include "kernel/system.h"
#include "kernel/kernel.h"
#include <minix/endpoint.h>
#include "arch_proto.h"
/*===========================================================================*
* do_iopenable *
*===========================================================================*/
PUBLIC int do_iopenable(struct proc * caller, message * m_ptr)
{
int proc_nr;
#if 1 /* ENABLE_USERPRIV && ENABLE_USERIOPL */
if (m_ptr->IOP_ENDPT == SELF) {
proc_nr = _ENDPOINT_P(caller->p_endpoint);
} else if(!isokendpt(m_ptr->IOP_ENDPT, &proc_nr))
return(EINVAL);
enable_iop(proc_addr(proc_nr));
return(OK);
#else
return(EPERM);
#endif
}