Subject: port-powerpc/7243: copyin()/copyout() do not always clear the pcb_onfault handler
To: None <gnats-bugs@gnats.netbsd.org>
From: None <mbrinico@nc.com>
List: netbsd-bugs
Date: 03/25/1999 19:43:49
>Number: 7243
>Category: port-powerpc
>Synopsis: copyin()/copyout() do not always clear the pcb_onfault handler
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: port-powerpc-maintainer (NetBSD/powerpc Portmasters)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Mar 25 19:50:03 1999
>Last-Modified:
>Originator: Mark Brinicombe
>Organization:
Network Computer Inc
>Release: NetBSD-current 1999/03/25
>Environment:
System: NetBSD p2.devlab.nc.com 1.3I-NCOS NetBSD 1.3I-NCOS (P2) #1: Wed Mar 17 16:37:17 PST 1999 mark@p2.devlab.nc.com:/usr/export/mark/NCOS/os-src/sys/arch/i386/compile/P2 i386
>Description:
The copyin() and copyout() functions only clear the pcb_onfault handler
on a successful copy. In the case where the onfault handler catches
a fault EFAULT is returned but the onfault handler is not cleared.
>How-To-Repeat:
Look at the code for copyin() and copyout().
>Fix:
clear the pcb_onfault variable in the EFAULT case.
*** trap.c.orig Thu Mar 25 19:15:36 1999
--- trap.c Thu Mar 25 19:36:49 1999
***************
*** 396,403 ****
size_t l;
faultbuf env;
! if (setfault(env))
return EFAULT;
while (len > 0) {
p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
--- 396,405 ----
size_t l;
faultbuf env;
! if (setfault(env)) {
! curpcb->pcb_onfault = 0;
return EFAULT;
+ }
while (len > 0) {
p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
***************
*** 425,432 ****
size_t l;
faultbuf env;
! if (setfault(env))
return EFAULT;
while (len > 0) {
p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
--- 427,436 ----
size_t l;
faultbuf env;
! if (setfault(env)) {
! curpcb->pcb_onfault = 0;
return EFAULT;
+ }
while (len > 0) {
p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
>Audit-Trail:
>Unformatted: