From owner-freebsd-current Fri Dec 19 04:37:40 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id EAA14802 for current-outgoing; Fri, 19 Dec 1997 04:37:40 -0800 (PST) (envelope-from owner-freebsd-current) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id EAA14797 for ; Fri, 19 Dec 1997 04:37:32 -0800 (PST) (envelope-from bde@zeta.org.au) Received: (from bde@localhost) by godzilla.zeta.org.au (8.8.7/8.6.9) id XAA12685; Fri, 19 Dec 1997 23:32:20 +1100 Date: Fri, 19 Dec 1997 23:32:20 +1100 From: Bruce Evans Message-Id: <199712191232.XAA12685@godzilla.zeta.org.au> To: hasty@rah.star-gate.com, pb@fasterix.freenix.org Subject: Re: cvs commit: src/sys/i386/linux linux.h linux_ioctl.c Cc: current@FreeBSD.ORG, gjp@erols.com, gjp@erols.net Sender: owner-freebsd-current@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk >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