Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 19 Dec 1997 23:32:20 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        hasty@rah.star-gate.com, pb@fasterix.freenix.org
Cc:        current@FreeBSD.ORG, gjp@erols.com, gjp@erols.net
Subject:   Re: cvs commit: src/sys/i386/linux linux.h linux_ioctl.c
Message-ID:  <199712191232.XAA12685@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>With respect to ioperm , I moved linux_ioperm from linux_dummy.c to 
>linux_misc.c and just have this for now:
>
>
>int
>linux_ioperm(struct proc *p, struct linux_ioperm_args *args)
>{
>        int error;
> 
>        error = suser(p->p_ucred, &p->p_acflag);
>        if (error != 0)
>                return error;
>        if (securelevel > 0)
>                return EPERM;
>        p->p_md.md_regs->tf_eflags |= PSL_IOPL;
>        return 0;
>}

That's not what Linux ioperm does.  Linux ioperm sets or clears bits in
the i/o permissions bitmap.  It is like FreeBSD ioperm except it has a
cleaner interface and is presumably less buggy.  FreeBSD ioperm is not
completely implemented.  It is only available if the kernel was configured
with `options "VM86"'.  It is a subcall of sysarch(undocumented).  You
have to pass it a pointer to a poorly laid out struct giving the args,
something like this:

Linux: int ioperm(u_long from, u_long num, int turn_on);
FreeBSD: struct i386_ioperm_args { u_short from, num; u_char turn_on; } foo;
         sysarch(I386_SET_IOPERM, /* XXX 1970's interface */ (char *)&foo);

Here are some fixes for the bugs.  They are untested.

diff -c2 sys_machdep.c~ sys_machdep.c
*** sys_machdep.c~	Fri Nov 28 14:37:35 1997
--- sys_machdep.c	Fri Nov 28 17:28:16 1997
***************
*** 181,185 ****
  	char *args;
  {
! 	int i, error = 0;
  	struct i386_ioperm_args ua;
  	char *iomap;
--- 181,185 ----
  	char *args;
  {
! 	int i, error;
  	struct i386_ioperm_args ua;
  	char *iomap;
***************
*** 188,194 ****
  		return (error);
  
-         /* Only root can do this */
          if (error = suser(p->p_ucred, &p->p_acflag))
                  return (error);
  	/*
  	 * XXX 
--- 188,195 ----
  		return (error);
  
          if (error = suser(p->p_ucred, &p->p_acflag))
                  return (error);
+ 	if (securelevel > 0)
+ 		return (EPERM);
  	/*
  	 * XXX 
***************
*** 203,207 ****
  	iomap = (char *)p->p_addr->u_pcb.pcb_ext->ext_iomap;
  
! 	if ((int)(ua.start + ua.length) > 0xffff)
  		return (EINVAL);
  
--- 204,208 ----
  	iomap = (char *)p->p_addr->u_pcb.pcb_ext->ext_iomap;
  
! 	if (ua.start + ua.length > IOPAGES * PAGE_SIZE * NBBY)
  		return (EINVAL);
  
***************
*** 220,224 ****
  	char *args;
  {
! 	int i, state, error = 0;
  	struct i386_ioperm_args ua;
  	char *iomap;
--- 221,225 ----
  	char *args;
  {
! 	int i, state, error;
  	struct i386_ioperm_args ua;
  	char *iomap;
***************
*** 226,229 ****
--- 227,232 ----
  	if (error = copyin(args, &ua, sizeof(struct i386_ioperm_args)))
  		return (error);
+ 	if (ua.start >= IOPAGES * PAGE_SIZE * NBBY)
+ 		return (EINVAL);
  
  	if (p->p_addr->u_pcb.pcb_ext == 0) {
***************
*** 234,237 ****
--- 237,242 ----
  	iomap = (char *)p->p_addr->u_pcb.pcb_ext->ext_iomap;
  
+ 	i = ua.start;
+ 	state = (iomap[i >> 3] >> (i & 7)) & 1;
  	ua.enable = !state;
  	ua.length = 1;

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199712191232.XAA12685>