xref: /minix3/minix/kernel/system/do_privctl.c (revision 9624407e7addfd8b88486acfe3a0e056e2b92ee3)
1433d6423SLionel Sambuc /* The kernel call implemented in this file:
2433d6423SLionel Sambuc  *   m_type:	SYS_PRIVCTL
3433d6423SLionel Sambuc  *
4433d6423SLionel Sambuc  * The parameters for this kernel call are:
5433d6423SLionel Sambuc  *   m_lsys_krn_sys_privctl.endpt		(process endpoint of target)
6433d6423SLionel Sambuc  *   m_lsys_krn_sys_privctl.request		(privilege control request)
7433d6423SLionel Sambuc  *   m_lsys_krn_sys_privctl.arg_ptr		(pointer to request data)
8433d6423SLionel Sambuc  *   m.m_lsys_krn_sys_privctl.phys_start
9433d6423SLionel Sambuc  *   m.m_lsys_krn_sys_privctl.phys_len
10433d6423SLionel Sambuc  */
11433d6423SLionel Sambuc 
12433d6423SLionel Sambuc #include "kernel/system.h"
13433d6423SLionel Sambuc #include <signal.h>
14433d6423SLionel Sambuc #include <string.h>
15433d6423SLionel Sambuc #include <minix/endpoint.h>
16433d6423SLionel Sambuc 
17433d6423SLionel Sambuc #if USE_PRIVCTL
18433d6423SLionel Sambuc 
19433d6423SLionel Sambuc #define PRIV_DEBUG 0
20433d6423SLionel Sambuc 
21433d6423SLionel Sambuc static int update_priv(struct proc *rp, struct priv *priv);
22433d6423SLionel Sambuc 
23433d6423SLionel Sambuc /*===========================================================================*
24433d6423SLionel Sambuc  *				do_privctl				     *
25433d6423SLionel Sambuc  *===========================================================================*/
do_privctl(struct proc * caller,message * m_ptr)26433d6423SLionel Sambuc int do_privctl(struct proc * caller, message * m_ptr)
27433d6423SLionel Sambuc {
28433d6423SLionel Sambuc /* Handle sys_privctl(). Update a process' privileges. If the process is not
29433d6423SLionel Sambuc  * yet a system process, make sure it gets its own privilege structure.
30433d6423SLionel Sambuc  */
31433d6423SLionel Sambuc   struct proc *rp;
32433d6423SLionel Sambuc   proc_nr_t proc_nr;
33433d6423SLionel Sambuc   sys_id_t priv_id;
34433d6423SLionel Sambuc   sys_map_t map;
35433d6423SLionel Sambuc   int ipc_to_m, kcalls;
36433d6423SLionel Sambuc   int i, r;
37433d6423SLionel Sambuc   struct io_range io_range;
38433d6423SLionel Sambuc   struct minix_mem_range mem_range;
39433d6423SLionel Sambuc   struct priv priv;
40433d6423SLionel Sambuc   int irq;
41433d6423SLionel Sambuc 
42433d6423SLionel Sambuc   /* Check whether caller is allowed to make this call. Privileged processes
43433d6423SLionel Sambuc    * can only update the privileges of processes that are inhibited from
44433d6423SLionel Sambuc    * running by the RTS_NO_PRIV flag. This flag is set when a privileged process
45433d6423SLionel Sambuc    * forks.
46433d6423SLionel Sambuc    */
47433d6423SLionel Sambuc   if (! (priv(caller)->s_flags & SYS_PROC)) return(EPERM);
48433d6423SLionel Sambuc   if(m_ptr->m_lsys_krn_sys_privctl.endpt == SELF) okendpt(caller->p_endpoint,
49433d6423SLionel Sambuc 	&proc_nr);
50433d6423SLionel Sambuc   else if(!isokendpt(m_ptr->m_lsys_krn_sys_privctl.endpt, &proc_nr))
51433d6423SLionel Sambuc 	return(EINVAL);
52433d6423SLionel Sambuc   rp = proc_addr(proc_nr);
53433d6423SLionel Sambuc 
54433d6423SLionel Sambuc   switch(m_ptr->m_lsys_krn_sys_privctl.request)
55433d6423SLionel Sambuc   {
56433d6423SLionel Sambuc   case SYS_PRIV_ALLOW:
57433d6423SLionel Sambuc 	/* Allow process to run. Make sure its privilege structure has already
58433d6423SLionel Sambuc 	 * been set.
59433d6423SLionel Sambuc 	 */
60433d6423SLionel Sambuc 	if (!RTS_ISSET(rp, RTS_NO_PRIV) || priv(rp)->s_proc_nr == NONE) {
61433d6423SLionel Sambuc 		return(EPERM);
62433d6423SLionel Sambuc 	}
63433d6423SLionel Sambuc 	RTS_UNSET(rp, RTS_NO_PRIV);
64433d6423SLionel Sambuc 	return(OK);
65433d6423SLionel Sambuc 
66433d6423SLionel Sambuc   case SYS_PRIV_YIELD:
67433d6423SLionel Sambuc 	/* Allow process to run and suspend the caller. */
68433d6423SLionel Sambuc 	if (!RTS_ISSET(rp, RTS_NO_PRIV) || priv(rp)->s_proc_nr == NONE) {
69433d6423SLionel Sambuc 		return(EPERM);
70433d6423SLionel Sambuc 	}
71433d6423SLionel Sambuc 	RTS_SET(caller, RTS_NO_PRIV);
72433d6423SLionel Sambuc 	RTS_UNSET(rp, RTS_NO_PRIV);
73433d6423SLionel Sambuc 	return(OK);
74433d6423SLionel Sambuc 
75433d6423SLionel Sambuc   case SYS_PRIV_DISALLOW:
76433d6423SLionel Sambuc 	/* Disallow process from running. */
77433d6423SLionel Sambuc 	if (RTS_ISSET(rp, RTS_NO_PRIV)) return(EPERM);
78433d6423SLionel Sambuc 	RTS_SET(rp, RTS_NO_PRIV);
79433d6423SLionel Sambuc 	return(OK);
80433d6423SLionel Sambuc 
816fc50062SCristiano Giuffrida   case SYS_PRIV_CLEAR_IPC_REFS:
826fc50062SCristiano Giuffrida 	/* Clear pending IPC for the process. */
836fc50062SCristiano Giuffrida 	clear_ipc_refs(rp, EDEADSRCDST);
846fc50062SCristiano Giuffrida 	return(OK);
856fc50062SCristiano Giuffrida 
86433d6423SLionel Sambuc   case SYS_PRIV_SET_SYS:
87433d6423SLionel Sambuc 	/* Set a privilege structure of a blocked system process. */
88433d6423SLionel Sambuc 	if (! RTS_ISSET(rp, RTS_NO_PRIV)) return(EPERM);
89433d6423SLionel Sambuc 
90433d6423SLionel Sambuc 	/* Check whether a static or dynamic privilege id must be allocated. */
91433d6423SLionel Sambuc 	priv_id = NULL_PRIV_ID;
92433d6423SLionel Sambuc 	if (m_ptr->m_lsys_krn_sys_privctl.arg_ptr)
93433d6423SLionel Sambuc 	{
94433d6423SLionel Sambuc 		/* Copy privilege structure from caller */
95433d6423SLionel Sambuc 		if((r=data_copy(caller->p_endpoint,
96433d6423SLionel Sambuc 			m_ptr->m_lsys_krn_sys_privctl.arg_ptr, KERNEL,
97433d6423SLionel Sambuc 			(vir_bytes) &priv, sizeof(priv))) != OK)
98433d6423SLionel Sambuc 			return r;
99433d6423SLionel Sambuc 
100433d6423SLionel Sambuc 		/* See if the caller wants to assign a static privilege id. */
101433d6423SLionel Sambuc 		if(!(priv.s_flags & DYN_PRIV_ID)) {
102433d6423SLionel Sambuc 			priv_id = priv.s_id;
103433d6423SLionel Sambuc 		}
104433d6423SLionel Sambuc 	}
105433d6423SLionel Sambuc 
106433d6423SLionel Sambuc 	/* Make sure this process has its own privileges structure. This may
107433d6423SLionel Sambuc 	 * fail, since there are only a limited number of system processes.
108433d6423SLionel Sambuc 	 * Then copy privileges from the caller and restore some defaults.
109433d6423SLionel Sambuc 	 */
110433d6423SLionel Sambuc 	if ((i=get_priv(rp, priv_id)) != OK)
111433d6423SLionel Sambuc 	{
112433d6423SLionel Sambuc 		printf("do_privctl: unable to allocate priv_id %d: %d\n",
113433d6423SLionel Sambuc 			priv_id, i);
114433d6423SLionel Sambuc 		return(i);
115433d6423SLionel Sambuc 	}
116433d6423SLionel Sambuc 	priv_id = priv(rp)->s_id;		/* backup privilege id */
117433d6423SLionel Sambuc 	*priv(rp) = *priv(caller);		/* copy from caller */
118433d6423SLionel Sambuc 	priv(rp)->s_id = priv_id;		/* restore privilege id */
119433d6423SLionel Sambuc 	priv(rp)->s_proc_nr = proc_nr;		/* reassociate process nr */
120433d6423SLionel Sambuc 
121433d6423SLionel Sambuc 	for (i=0; i< NR_SYS_CHUNKS; i++)		/* remove pending: */
122*7f79fb88SDavid van Moolenbroek 	      priv(rp)->s_asyn_pending.chunk[i] = 0;	/* - incoming asyn */
123*7f79fb88SDavid van Moolenbroek 	for (i=0; i< NR_SYS_CHUNKS; i++)		/*   messages */
124433d6423SLionel Sambuc 	      priv(rp)->s_notify_pending.chunk[i] = 0;	/* - notifications */
125433d6423SLionel Sambuc 	priv(rp)->s_int_pending = 0;			/* - interrupts */
126433d6423SLionel Sambuc 	(void) sigemptyset(&priv(rp)->s_sig_pending);	/* - signals */
127433d6423SLionel Sambuc 	reset_kernel_timer(&priv(rp)->s_alarm_timer);	/* - alarm */
128433d6423SLionel Sambuc 	priv(rp)->s_asyntab= -1;			/* - asynsends */
129433d6423SLionel Sambuc 	priv(rp)->s_asynsize= 0;
130062400c0SCristiano Giuffrida 	priv(rp)->s_asynendpoint = rp->p_endpoint;
131433d6423SLionel Sambuc 	priv(rp)->s_diag_sig = FALSE;		/* no request for diag sigs */
132433d6423SLionel Sambuc 
133433d6423SLionel Sambuc 	/* Set defaults for privilege bitmaps. */
134433d6423SLionel Sambuc 	priv(rp)->s_flags= DSRV_F;           /* privilege flags */
13576bf77a2SCristiano Giuffrida 	priv(rp)->s_init_flags= DSRV_I;      /* initialization flags */
136433d6423SLionel Sambuc 	priv(rp)->s_trap_mask= DSRV_T;       /* allowed traps */
137433d6423SLionel Sambuc 	memset(&map, 0, sizeof(map));
138433d6423SLionel Sambuc 	ipc_to_m = DSRV_M;                   /* allowed targets */
139433d6423SLionel Sambuc 	if (ipc_to_m == ALL_M) {
140433d6423SLionel Sambuc 		for (i = 0; i < NR_SYS_PROCS; i++)
141433d6423SLionel Sambuc 			set_sys_bit(map, i);
142433d6423SLionel Sambuc 	}
143433d6423SLionel Sambuc 	fill_sendto_mask(rp, &map);
144433d6423SLionel Sambuc 	kcalls = DSRV_KC;                    /* allowed kernel calls */
145433d6423SLionel Sambuc 	for(i = 0; i < SYS_CALL_MASK_SIZE; i++) {
146433d6423SLionel Sambuc 		priv(rp)->s_k_call_mask[i] = (kcalls == NO_C ? 0 : (~0));
147433d6423SLionel Sambuc 	}
148433d6423SLionel Sambuc 
149433d6423SLionel Sambuc 	/* Set the default signal managers. */
150433d6423SLionel Sambuc 	priv(rp)->s_sig_mgr = DSRV_SM;
151433d6423SLionel Sambuc 	priv(rp)->s_bak_sig_mgr = NONE;
152433d6423SLionel Sambuc 
153433d6423SLionel Sambuc 	/* Set defaults for resources: no I/O resources, no memory resources,
154c8a9900bSCristiano Giuffrida 	 * no IRQs, no grant table, no ipc filter
155433d6423SLionel Sambuc 	 */
156433d6423SLionel Sambuc 	priv(rp)->s_nr_io_range= 0;
157433d6423SLionel Sambuc 	priv(rp)->s_nr_mem_range= 0;
158433d6423SLionel Sambuc 	priv(rp)->s_nr_irq= 0;
159433d6423SLionel Sambuc 	priv(rp)->s_grant_table= 0;
160433d6423SLionel Sambuc 	priv(rp)->s_grant_entries= 0;
1619e6b1315SCristiano Giuffrida 	priv(rp)->s_grant_endpoint = rp->p_endpoint;
16241022be1SCristiano Giuffrida 	priv(rp)->s_state_table= 0;
16341022be1SCristiano Giuffrida 	priv(rp)->s_state_entries= 0;
164c8a9900bSCristiano Giuffrida 	priv(rp)->s_ipcf= 0;
165433d6423SLionel Sambuc 
166433d6423SLionel Sambuc 	/* Override defaults if the caller has supplied a privilege structure. */
167433d6423SLionel Sambuc 	if (m_ptr->m_lsys_krn_sys_privctl.arg_ptr)
168433d6423SLionel Sambuc 	{
169433d6423SLionel Sambuc 		if((r = update_priv(rp, &priv)) != OK) {
170433d6423SLionel Sambuc 			return r;
171433d6423SLionel Sambuc 		}
172433d6423SLionel Sambuc 	}
173433d6423SLionel Sambuc 
174433d6423SLionel Sambuc 	return(OK);
175433d6423SLionel Sambuc 
176433d6423SLionel Sambuc   case SYS_PRIV_SET_USER:
177433d6423SLionel Sambuc 	/* Set a privilege structure of a blocked user process. */
178433d6423SLionel Sambuc 	if (!RTS_ISSET(rp, RTS_NO_PRIV)) return(EPERM);
179433d6423SLionel Sambuc 
180433d6423SLionel Sambuc 	/* Link the process to the privilege structure of the root user
181433d6423SLionel Sambuc 	 * process all the user processes share.
182433d6423SLionel Sambuc 	 */
183433d6423SLionel Sambuc 	priv(rp) = priv_addr(USER_PRIV_ID);
184433d6423SLionel Sambuc 
185433d6423SLionel Sambuc 	return(OK);
186433d6423SLionel Sambuc 
187433d6423SLionel Sambuc   case SYS_PRIV_ADD_IO:
188433d6423SLionel Sambuc 	if (RTS_ISSET(rp, RTS_NO_PRIV))
189433d6423SLionel Sambuc 		return(EPERM);
190433d6423SLionel Sambuc 
191433d6423SLionel Sambuc #if 0 /* XXX -- do we need a call for this? */
192433d6423SLionel Sambuc 	if (strcmp(rp->p_name, "fxp") == 0 ||
193433d6423SLionel Sambuc 		strcmp(rp->p_name, "rtl8139") == 0)
194433d6423SLionel Sambuc 	{
195433d6423SLionel Sambuc 		printf("setting ipc_stats_target to %d\n", rp->p_endpoint);
196433d6423SLionel Sambuc 		ipc_stats_target= rp->p_endpoint;
197433d6423SLionel Sambuc 	}
198433d6423SLionel Sambuc #endif
199433d6423SLionel Sambuc 
200433d6423SLionel Sambuc 	/* Get the I/O range */
201433d6423SLionel Sambuc 	data_copy(caller->p_endpoint, m_ptr->m_lsys_krn_sys_privctl.arg_ptr,
202433d6423SLionel Sambuc 		KERNEL, (vir_bytes) &io_range, sizeof(io_range));
20356e56d2aSCristiano Giuffrida 	/* Add the I/O range */
20456e56d2aSCristiano Giuffrida 	return priv_add_io(rp, &io_range);
205433d6423SLionel Sambuc 
206433d6423SLionel Sambuc   case SYS_PRIV_ADD_MEM:
207433d6423SLionel Sambuc 	if (RTS_ISSET(rp, RTS_NO_PRIV))
208433d6423SLionel Sambuc 		return(EPERM);
209433d6423SLionel Sambuc 
210433d6423SLionel Sambuc 	/* Get the memory range */
211433d6423SLionel Sambuc 	if((r=data_copy(caller->p_endpoint,
212433d6423SLionel Sambuc 		m_ptr->m_lsys_krn_sys_privctl.arg_ptr, KERNEL,
213433d6423SLionel Sambuc 		(vir_bytes) &mem_range, sizeof(mem_range))) != OK)
214433d6423SLionel Sambuc 		return r;
21556e56d2aSCristiano Giuffrida 	/* Add the memory range */
21656e56d2aSCristiano Giuffrida 	return priv_add_mem(rp, &mem_range);
217433d6423SLionel Sambuc 
218433d6423SLionel Sambuc   case SYS_PRIV_ADD_IRQ:
219433d6423SLionel Sambuc 	if (RTS_ISSET(rp, RTS_NO_PRIV))
220433d6423SLionel Sambuc 		return(EPERM);
221433d6423SLionel Sambuc 
2225d831176SLionel Sambuc #if 0
223433d6423SLionel Sambuc 	/* Only system processes get IRQs? */
224433d6423SLionel Sambuc 	if (!(priv(rp)->s_flags & SYS_PROC))
225433d6423SLionel Sambuc 		return EPERM;
2265d831176SLionel Sambuc #endif
227433d6423SLionel Sambuc 	data_copy(caller->p_endpoint, m_ptr->m_lsys_krn_sys_privctl.arg_ptr,
228433d6423SLionel Sambuc 		KERNEL, (vir_bytes) &irq, sizeof(irq));
22956e56d2aSCristiano Giuffrida 	/* Add the IRQ. */
23056e56d2aSCristiano Giuffrida 	return priv_add_irq(rp, irq);
231433d6423SLionel Sambuc 
232433d6423SLionel Sambuc   case SYS_PRIV_QUERY_MEM:
233433d6423SLionel Sambuc   {
234433d6423SLionel Sambuc 	phys_bytes addr, limit;
235433d6423SLionel Sambuc   	struct priv *sp;
236433d6423SLionel Sambuc 	/* See if a certain process is allowed to map in certain physical
237433d6423SLionel Sambuc 	 * memory.
238433d6423SLionel Sambuc 	 */
239433d6423SLionel Sambuc 	addr = (phys_bytes) m_ptr->m_lsys_krn_sys_privctl.phys_start;
240433d6423SLionel Sambuc 	limit = addr + (phys_bytes) m_ptr->m_lsys_krn_sys_privctl.phys_len - 1;
241433d6423SLionel Sambuc 	if(limit < addr)
242433d6423SLionel Sambuc 		return EPERM;
243433d6423SLionel Sambuc 	if(!(sp = priv(rp)))
244433d6423SLionel Sambuc 		return EPERM;
245433d6423SLionel Sambuc 	for(i = 0; i < sp->s_nr_mem_range; i++) {
246433d6423SLionel Sambuc 		if(addr >= sp->s_mem_tab[i].mr_base &&
247433d6423SLionel Sambuc 		   limit <= sp->s_mem_tab[i].mr_limit)
248433d6423SLionel Sambuc 			return OK;
249433d6423SLionel Sambuc 	}
250433d6423SLionel Sambuc 	return EPERM;
251433d6423SLionel Sambuc   }
252433d6423SLionel Sambuc 
253433d6423SLionel Sambuc   case SYS_PRIV_UPDATE_SYS:
254433d6423SLionel Sambuc 	/* Update the privilege structure of a system process. */
255433d6423SLionel Sambuc 	if(!m_ptr->m_lsys_krn_sys_privctl.arg_ptr) return EINVAL;
256433d6423SLionel Sambuc 
257433d6423SLionel Sambuc 	/* Copy privilege structure from caller */
258433d6423SLionel Sambuc 	if((r=data_copy(caller->p_endpoint,
259433d6423SLionel Sambuc 		m_ptr->m_lsys_krn_sys_privctl.arg_ptr, KERNEL,
260433d6423SLionel Sambuc 		(vir_bytes) &priv, sizeof(priv))) != OK)
261433d6423SLionel Sambuc 		return r;
262433d6423SLionel Sambuc 
263433d6423SLionel Sambuc 	/* Override settings in existing privilege structure. */
264433d6423SLionel Sambuc 	if((r = update_priv(rp, &priv)) != OK) {
265433d6423SLionel Sambuc 		return r;
266433d6423SLionel Sambuc 	}
267433d6423SLionel Sambuc 
268433d6423SLionel Sambuc 	return(OK);
269433d6423SLionel Sambuc 
270433d6423SLionel Sambuc   default:
271433d6423SLionel Sambuc 	printf("do_privctl: bad request %d\n",
272433d6423SLionel Sambuc 		m_ptr->m_lsys_krn_sys_privctl.request);
273433d6423SLionel Sambuc 	return EINVAL;
274433d6423SLionel Sambuc   }
275433d6423SLionel Sambuc }
276433d6423SLionel Sambuc 
277433d6423SLionel Sambuc /*===========================================================================*
278433d6423SLionel Sambuc  *				update_priv				     *
279433d6423SLionel Sambuc  *===========================================================================*/
update_priv(struct proc * rp,struct priv * priv)280433d6423SLionel Sambuc static int update_priv(struct proc *rp, struct priv *priv)
281433d6423SLionel Sambuc {
282433d6423SLionel Sambuc /* Update the privilege structure of a given process. */
283433d6423SLionel Sambuc 
284433d6423SLionel Sambuc   int i;
285433d6423SLionel Sambuc 
28676bf77a2SCristiano Giuffrida   /* Copy flags and signal managers. */
287433d6423SLionel Sambuc   priv(rp)->s_flags = priv->s_flags;
28876bf77a2SCristiano Giuffrida   priv(rp)->s_init_flags = priv->s_init_flags;
289433d6423SLionel Sambuc   priv(rp)->s_sig_mgr = priv->s_sig_mgr;
290433d6423SLionel Sambuc   priv(rp)->s_bak_sig_mgr = priv->s_bak_sig_mgr;
291433d6423SLionel Sambuc 
292433d6423SLionel Sambuc   /* Copy IRQs. */
293433d6423SLionel Sambuc   if(priv->s_flags & CHECK_IRQ) {
294433d6423SLionel Sambuc   	if (priv->s_nr_irq < 0 || priv->s_nr_irq > NR_IRQ)
295433d6423SLionel Sambuc   		return EINVAL;
296433d6423SLionel Sambuc   	priv(rp)->s_nr_irq= priv->s_nr_irq;
297433d6423SLionel Sambuc   	for (i= 0; i<priv->s_nr_irq; i++)
298433d6423SLionel Sambuc   	{
299433d6423SLionel Sambuc   		priv(rp)->s_irq_tab[i]= priv->s_irq_tab[i];
300433d6423SLionel Sambuc #if PRIV_DEBUG
301433d6423SLionel Sambuc   		printf("do_privctl: adding IRQ %d for %d\n",
302433d6423SLionel Sambuc   			priv(rp)->s_irq_tab[i], rp->p_endpoint);
303433d6423SLionel Sambuc #endif
304433d6423SLionel Sambuc   	}
305433d6423SLionel Sambuc   }
306433d6423SLionel Sambuc 
307433d6423SLionel Sambuc   /* Copy I/O ranges. */
308433d6423SLionel Sambuc   if(priv->s_flags & CHECK_IO_PORT) {
309433d6423SLionel Sambuc   	if (priv->s_nr_io_range < 0 || priv->s_nr_io_range > NR_IO_RANGE)
310433d6423SLionel Sambuc   		return EINVAL;
311433d6423SLionel Sambuc   	priv(rp)->s_nr_io_range= priv->s_nr_io_range;
312433d6423SLionel Sambuc   	for (i= 0; i<priv->s_nr_io_range; i++)
313433d6423SLionel Sambuc   	{
314433d6423SLionel Sambuc   		priv(rp)->s_io_tab[i]= priv->s_io_tab[i];
315433d6423SLionel Sambuc #if PRIV_DEBUG
316433d6423SLionel Sambuc   		printf("do_privctl: adding I/O range [%x..%x] for %d\n",
317433d6423SLionel Sambuc   			priv(rp)->s_io_tab[i].ior_base,
318433d6423SLionel Sambuc   			priv(rp)->s_io_tab[i].ior_limit,
319433d6423SLionel Sambuc   			rp->p_endpoint);
320433d6423SLionel Sambuc #endif
321433d6423SLionel Sambuc   	}
322433d6423SLionel Sambuc   }
323433d6423SLionel Sambuc 
324433d6423SLionel Sambuc   /* Copy memory ranges. */
325433d6423SLionel Sambuc   if(priv->s_flags & CHECK_MEM) {
326433d6423SLionel Sambuc   	if (priv->s_nr_mem_range < 0 || priv->s_nr_mem_range > NR_MEM_RANGE)
327433d6423SLionel Sambuc   		return EINVAL;
328433d6423SLionel Sambuc   	priv(rp)->s_nr_mem_range= priv->s_nr_mem_range;
329433d6423SLionel Sambuc   	for (i= 0; i<priv->s_nr_mem_range; i++)
330433d6423SLionel Sambuc   	{
331433d6423SLionel Sambuc   		priv(rp)->s_mem_tab[i]= priv->s_mem_tab[i];
332433d6423SLionel Sambuc #if PRIV_DEBUG
333433d6423SLionel Sambuc   		printf("do_privctl: adding mem range [%x..%x] for %d\n",
334433d6423SLionel Sambuc   			priv(rp)->s_mem_tab[i].mr_base,
335433d6423SLionel Sambuc   			priv(rp)->s_mem_tab[i].mr_limit,
336433d6423SLionel Sambuc   			rp->p_endpoint);
337433d6423SLionel Sambuc #endif
338433d6423SLionel Sambuc   	}
339433d6423SLionel Sambuc   }
340433d6423SLionel Sambuc 
341433d6423SLionel Sambuc   /* Copy trap mask. */
342433d6423SLionel Sambuc   priv(rp)->s_trap_mask = priv->s_trap_mask;
343433d6423SLionel Sambuc 
344433d6423SLionel Sambuc   /* Copy target mask. */
345433d6423SLionel Sambuc #if PRIV_DEBUG
346433d6423SLionel Sambuc   printf("do_privctl: Setting ipc target mask for %d:");
347433d6423SLionel Sambuc   for (i=0; i < NR_SYS_PROCS; i += BITCHUNK_BITS) {
348433d6423SLionel Sambuc   	printf(" %08x", get_sys_bits(priv->s_ipc_to, i));
349433d6423SLionel Sambuc   }
350433d6423SLionel Sambuc   printf("\n");
351433d6423SLionel Sambuc #endif
352433d6423SLionel Sambuc 
353433d6423SLionel Sambuc   fill_sendto_mask(rp, &priv->s_ipc_to);
354433d6423SLionel Sambuc 
355433d6423SLionel Sambuc #if PRIV_DEBUG
356433d6423SLionel Sambuc   printf("do_privctl: Set ipc target mask for %d:");
357433d6423SLionel Sambuc   for (i=0; i < NR_SYS_PROCS; i += BITCHUNK_BITS) {
358433d6423SLionel Sambuc   	printf(" %08x", get_sys_bits(priv(rp)->s_ipc_to, i));
359433d6423SLionel Sambuc   }
360433d6423SLionel Sambuc   printf("\n");
361433d6423SLionel Sambuc #endif
362433d6423SLionel Sambuc 
363433d6423SLionel Sambuc   /* Copy kernel call mask. */
364433d6423SLionel Sambuc   memcpy(priv(rp)->s_k_call_mask, priv->s_k_call_mask,
365433d6423SLionel Sambuc   	sizeof(priv(rp)->s_k_call_mask));
366433d6423SLionel Sambuc 
367433d6423SLionel Sambuc   return OK;
368433d6423SLionel Sambuc }
369433d6423SLionel Sambuc 
370433d6423SLionel Sambuc #endif /* USE_PRIVCTL */
371433d6423SLionel Sambuc 
372