Return to BSD News archive
Path: sserve!newshost.anu.edu.au!munnari.oz.au!spool.mu.edu!howland.reston.ans.net!zaphod.mps.ohio-state.edu!cs.utexas.edu!uunet!news.univie.ac.at!fstgds15.tu-graz.ac.at!fstgds01.tu-graz.ac.at!not-for-mail From: chmr@edvz.tu-graz.ac.at (Christoph Robitschko) Newsgroups: comp.os.386bsd.bugs Subject: copyout family fixed Date: 12 May 1993 09:20:57 +0200 Organization: Technical University of Graz, Austria Lines: 955 Message-ID: <1sq8gpINNnbb@fstgds01.tu-graz.ac.at> NNTP-Posting-Host: fstgds01.tu-graz.ac.at X-Newsreader: TIN [version 1.1 PL7] Description: The copyin/copyout and fubyte/subyte functions as they are in stock 386bsd do not check for the page protections, allowing the user to read/overwrite memory areas where a user program should not have access to (kernel memory etc). There is some code #ifdef'ed out in the original locore.s file, but this code only checks for write permission, and not whether the user has permissions to access this memory at all, and the code is very buggy. There is patch00137 in patchkit 0.2.3, which fixes these problems with ptrace, but it does not fix the problems with read, write and ioctl(). My patch should fix all of these situations. With Testprogram 2, I have had interesting side effects when using the original versions of copyin and subyte: When I modify the text segment, the changes are paged back to the executable file, regardless of write permissions, even if the filesystem is mounted read-only ! Repeat-By: Testprogram 1: test copyin. Tries to read a kernel memory region. Start with: "nm -g /386bsd | awk '/copyright1/ { printf "0x%s\n", $1 }' | xargs ./cpitest" cpitest.c: main(argc, argv) char **argv; { void *v1; v1 = strtoul(argv[1], 0, 0); if (write(1, v1, 20) < 0) perror("copyin"); } Testprogram 2: test copyin/subyte. Tries to write to read-only memory. Start with: echo -n no | ./cpotest # to test copyout ./cpotest # type "no^D" to test subyte cpotest.c: const char v1[] = {"hallihallo !"}; main() { printf("v1 is %s\n", v1); if (read(0, v1, 5) < 0) perror("copyout/subyte"); printf("v1 is %s\n", v1); } Testcase 3: use gdb to read/modify a kernel memory region. Note that this is fixed when patch00137 is installed. gdbtest.csh: #!/bin/csh -f set verbose set address=`nm -g /386bsd | awk '/copyright1/ { print $1 }'` cd /tmp; cat << EOF1 > copyout$$.c main() { char *s = (char *)0x$address; } EOF1 cc -g copyout$$.c -o copyout$$ gdb copyout$$ << EOF2 b main run n p s set (*s)++ p s c q EOF2 rm -f copyout$$ copyout$$.c Fix: I have rewritten the routines copyout, copyin, fubyte, fusword, fuword, subyte, susword, suword. For performance reasons I have also replaced the C versions of copyinstr, copyoutstr and copystr in machdep.c with assembler versions (in locore.s). Here are context diffs for locore.s (long !), which includes the fixed routines, for trap.c which now contains another support function for copyin (named trapread), and for machdep.c to #ifdef out the C versions on copy[in/out]str. All patches are taken from the Patchkit-0.2.3 versions. === CUT HERE === locore.s.patch follows ======================================== *** /sys/i386/i386/locore.s.pk023 Wed May 12 07:42:57 1993 --- /sys/i386/i386/locore.s Wed May 12 07:51:53 1993 *************** *** 551,616 **** cld ret ! #ifdef notdef .globl _copyout ALIGN32 _copyout: movl _curpcb, %eax movl $cpyflt, PCB_ONFAULT(%eax) # in case we page/protection violate ! pushl %esi ! pushl %edi pushl %ebx movl 16(%esp), %esi movl 20(%esp), %edi movl 24(%esp), %ebx ! /* first, check to see if "write fault" */ ! 1: movl %edi, %eax ! #ifdef notyet ! shrl $IDXSHIFT, %eax /* fetch pte associated with address */ ! andb $0xfc, %al ! movl _PTmap(%eax), %eax ! andb $7, %al /* if we are the one case that won't trap... */ ! cmpb $5, %al ! jne 2f ! /* ... then simulate the trap! */ ! pushl %edi ! call _trapwrite /* trapwrite(addr) */ popl %edx ! cmpl $0, %eax /* if not ok, return */ ! jne cpyflt ! /* otherwise, continue with reference */ 2: ! movl %edi, %eax /* calculate remainder this pass */ ! andl $0xfffff000, %eax ! movl $NBPG, %ecx ! subl %eax, %ecx ! cmpl %ecx, %ebx ! jle 3f ! movl %ebx, %ecx ! 3: subl %ecx, %ebx ! movl %ecx, %edx ! #else ! movl %ebx, %ecx ! movl %ebx, %edx ! #endif ! shrl $2,%ecx /* movem */ cld rep movsl ! movl %edx, %ecx /* don't depend on ecx here! */ ! andl $3, %ecx rep movsb - #ifdef notyet - cmpl $0, %ebx - jl 1b - #endif - popl %ebx popl %edi popl %esi --- 552,625 ---- cld ret ! ! /* ! * copyout (src, dst, len) ! * to is in userspace, so each page must be checked for ! * user addressability and write protections. ! * first check all pages, then copy it over. ! * Apr 1993 Christoph Robitschko <chmr@edvz.tu-graz.ac.at> ! */ .globl _copyout ALIGN32 _copyout: movl _curpcb, %eax movl $cpyflt, PCB_ONFAULT(%eax) # in case we page/protection violate ! pushl %esi /* Note: The same registers must be */ ! pushl %edi /* pushed/popped in copyout, copyin and copyflt */ pushl %ebx movl 16(%esp), %esi movl 20(%esp), %edi movl 24(%esp), %ebx ! /* compute number of pages */ ! movl %edi, %ecx ! andl $0x0fff, %ecx ! addl %ebx, %ecx ! shrl $12, %ecx /* IDXSHIFT+2 */ ! incl %ecx ! /* compute PTE offset for start address */ ! movl %edi, %edx ! shrl $IDXSHIFT, %edx ! andb $0xfc, %dl ! ! 1: /* check PTE for each page */ ! movb _PTmap(%edx), %al ! andb $0x07, %al /* Pages must be VALID + USERACC + WRITABLE */ ! cmpb $0x07, %al ! je 2f ! ! /* simulate a trap */ ! pushl %edx ! pushl %ecx ! shll $IDXSHIFT, %edx ! pushl %edx ! call _trapwrite /* XXX trapwrite(addr) */ popl %edx + popl %ecx + popl %edx ! orl %eax, %eax /* if not ok, return EFAULT */ ! jnz cpyflt ! 2: ! addl $4, %edx ! decl %ecx ! jnz 1b /* check next page */ ! do_copyio: /* now copy it over */ ! /* bcopy (%esi, %edi, %ebx) */ cld + movl %ebx, %ecx + shrl $2, %ecx rep movsl ! movb %bl, %cl ! andb $3, %cl rep movsb popl %ebx popl %edi popl %esi *************** *** 619,651 **** movl %eax,PCB_ONFAULT(%edx) ret .globl _copyin ALIGN32 _copyin: ! movl _curpcb,%eax ! movl $cpyflt,PCB_ONFAULT(%eax) # in case we page/protection violate pushl %esi pushl %edi pushl %ebx ! movl 12(%esp),%esi ! movl 16(%esp),%edi ! movl 20(%esp),%ecx ! shrl $2,%ecx ! cld ! rep ! movsl ! movl 20(%esp),%ecx ! andl $3,%ecx ! rep ! movsb ! popl %ebx ! popl %edi ! popl %esi ! xorl %eax,%eax ! movl _curpcb,%edx ! movl %eax,PCB_ONFAULT(%edx) ! ret ALIGN32 cpyflt: popl %ebx --- 628,698 ---- movl %eax,PCB_ONFAULT(%edx) ret + + /* + * copyin(src, dst, len) + * src is in user space; check if user-addressable. + * This is the same code as copyout, but here the src is checked, + * and only for READ protection + * Apr 1993 Christoph Robitschko <chmr@edvz.tu-graz.ac.at> + */ .globl _copyin ALIGN32 _copyin: ! movl _curpcb, %eax ! movl $cpyflt, PCB_ONFAULT(%eax) # in case we page/protection violate pushl %esi pushl %edi pushl %ebx ! movl 16(%esp), %esi ! movl 20(%esp), %edi ! movl 24(%esp), %ebx + /* compute number of pages */ + movl %esi, %ecx + andl $0x0fff, %ecx + addl %ebx, %ecx + shrl $12, %ecx + incl %ecx + + /* compute PTE offset for start address */ + movl %esi, %edx + shrl $IDXSHIFT, %edx + andb $0xfc, %dl + + 1: /* check PTE for each page */ + movb _PTmap(%edx), %al + andb $0x05, %al /* Pages must be VALID + USERACC */ + cmpb $0x05, %al + je 2f + + /* simulate a trap */ + pushl %edx + pushl %ecx + shll $IDXSHIFT, %edx + pushl %edx + call _trapread /* XXX trapread(addr) */ + popl %edx + popl %ecx + popl %edx + + orl %eax, %eax /* if not ok, return EFAULT */ + jnz cpyflt + + 2: + addl $4, %edx + decl %ecx + jnz 1b /* check next page */ + + jmp do_copyio /* do the copy operation */ + + + /* + * copyflt + * is jumped to either directly from copyin/copyout, or when a + * protection fault is handled while in copyin/out. + * Simply returns EFAULT to the caller of copyin/out. + */ ALIGN32 cpyflt: popl %ebx *************** *** 655,721 **** movl $0,PCB_ONFAULT(%edx) movl $ EFAULT,%eax ret ! #else ! .globl _copyout ALIGN32 ! _copyout: ! movl _curpcb,%eax ! movl $cpyflt,PCB_ONFAULT(%eax) # in case we page/protection violate pushl %esi pushl %edi ! movl 12(%esp),%esi ! movl 16(%esp),%edi ! movl 20(%esp),%ecx ! shrl $2,%ecx ! cld ! rep ! movsl ! movl 20(%esp),%ecx ! andl $3,%ecx ! rep ! movsb popl %edi ! popl %esi ! xorl %eax,%eax ! movl _curpcb,%edx ! movl %eax,PCB_ONFAULT(%edx) ! ret ! .globl _copyin ALIGN32 ! _copyin: ! movl _curpcb,%eax ! movl $cpyflt,PCB_ONFAULT(%eax) # in case we page/protection violate pushl %esi pushl %edi ! movl 12(%esp),%esi ! movl 16(%esp),%edi ! movl 20(%esp),%ecx ! shrl $2,%ecx ! cld ! rep ! movsl ! movl 20(%esp),%ecx ! andl $3,%ecx ! rep ! movsb popl %edi popl %esi - xorl %eax,%eax - movl _curpcb,%edx - movl %eax,PCB_ONFAULT(%edx) ret ! ALIGN32 ! cpyflt: popl %edi ! popl %esi ! movl _curpcb,%edx ! movl $0,PCB_ONFAULT(%edx) ! movl $ EFAULT,%eax ret - #endif # insb(port,addr,cnt) .globl _insb ALIGN32 --- 702,903 ---- movl $0,PCB_ONFAULT(%edx) movl $ EFAULT,%eax ret ! ! /* ! * copyoutstr(from, to, maxlen, int *lencopied) ! * copy a string from from to to, stop when a 0 character is reached. ! * return ENAMETOOLONG if string is longer than maxlen, and ! * EFAULT on protection violations. If lencopied is non-zero, ! * return the actual length in *lencopied. ! * May 93 Christoph Robitschko <chmr@edvz.tu-graz.ac.at> ! */ ! .globl _copyoutstr ALIGN32 ! _copyoutstr: pushl %esi pushl %edi ! pushl %ebx ! movl _curpcb, %ecx ! movl $cpystrflt, PCB_ONFAULT(%ecx) ! ! movl 16(%esp), %esi # %esi = from ! movl 20(%esp), %edi # %edi = to ! movl 24(%esp), %ebx # %ebx = maxlen ! 1: ! movl %edi, %edx ! shrl $IDXSHIFT, %edx ! andb $0xfc, %dl ! movb _PTmap(%edx), %al ! andb $7, %al ! cmpb $7, %al ! je 2f ! ! /* simulate trap */ ! pushl %edi ! call _trapwrite popl %edi ! orl %eax, %eax ! jnz cpystrflt ! 2: /* copy up to end of this page */ ! movl %edi, %eax ! andl $0x0fff, %eax ! movl $NBPG, %ecx ! subl %eax, %ecx /* ecx = NBPG - (src % NBPG) */ ! cmpl %ecx, %ebx ! jge 3f ! movl %ebx, %ecx /* ecx = min (ecx, ebx) */ ! 3: ! orl %ecx, %ecx ! jz 4f ! decl %ecx ! decl %ebx ! movb 0(%esi), %al ! movb %al, 0(%edi) ! incl %esi ! incl %edi ! orb %al, %al ! jnz 3b ! ! /* Success -- 0 byte reached */ ! xorl %eax, %eax ! jmp 6f ! ! 4: /* next page */ ! orl %ebx, %ebx ! jnz 1b ! /* ebx is zero -- return ENAMETOOLONG */ ! movl $ENAMETOOLONG, %eax ! jmp 6f ! ! ! /* ! * copyinstr(from, to, maxlen, int *lencopied) ! * copy a string from from to to, stop when a 0 character is reached. ! * return ENAMETOOLONG if string is longer than maxlen, and ! * EFAULT on protection violations. If lencopied is non-zero, ! * return the actual length in *lencopied. ! * May 93 Christoph Robitschko <chmr@edvz.tu-graz.ac.at> ! */ ! .globl _copyinstr ALIGN32 ! _copyinstr: pushl %esi pushl %edi ! pushl %ebx ! movl _curpcb, %ecx ! movl $cpystrflt, PCB_ONFAULT(%ecx) ! ! movl 16(%esp), %esi # %esi = from ! movl 20(%esp), %edi # %edi = to ! movl 24(%esp), %ebx # %ebx = maxlen ! 1: ! movl %esi, %edx ! shrl $IDXSHIFT, %edx ! andb $0xfc, %dl ! movb _PTmap(%edx), %al ! andb $5, %al ! cmpb $5, %al ! je 2f ! ! /* simulate trap */ ! pushl %esi ! call _trapread ! popl %esi ! orl %eax, %eax ! jnz cpystrflt ! ! 2: /* copy up to end of this page */ ! movl %esi, %eax ! andl $0x0fff, %eax ! movl $NBPG, %ecx ! subl %eax, %ecx /* ecx = NBPG - (src % NBPG) */ ! cmpl %ecx, %ebx ! jge 3f ! movl %ebx, %ecx /* ecx = min (ecx, ebx) */ ! 3: ! orl %ecx, %ecx ! jz 4f ! decl %ecx ! decl %ebx ! movb 0(%esi), %al ! movb %al, 0(%edi) ! incl %esi ! incl %edi ! orb %al, %al ! jnz 3b ! ! /* Success -- 0 byte reached */ ! xorl %eax, %eax ! jmp 6f ! ! 4: /* next page */ ! orl %ebx, %ebx ! jnz 1b ! /* ebx is zero -- return ENAMETOOLONG */ ! movl $ENAMETOOLONG, %eax ! jmp 6f ! ! cpystrflt: ! movl $EFAULT, %eax ! 6: /* set *lencopied and return %eax */ ! movl _curpcb, %ecx ! movl $0, PCB_ONFAULT(%ecx) ! movl 28(%esp), %edx ! orl %edx, %edx ! jz 7f ! movl 24(%esp), %ecx ! subl %ebx, %ecx ! movl %ecx, 0(%edx) ! 7: ! popl %ebx popl %edi popl %esi ret ! ! /* ! * copystr(from, to, maxlen, int *lencopied) ! */ ! .globl _copystr ! ALIGN32 ! _copystr: ! pushl %ebx ! ! movl 8(%esp), %edx # %edx = from ! movl 12(%esp), %ecx # %ecx = to ! movl 16(%esp), %ebx # %ebx = maxlen ! 1: ! orl %ebx, %ebx ! jz 4f ! decl %ebx ! movb 0(%edx), %al ! movb %al, 0(%ecx) ! incl %edx ! incl %ecx ! orb %al, %al ! jnz 1b ! ! /* Success -- 0 byte reached */ ! xorl %eax, %eax ! jmp 6f ! ! 4: /* ebx is zero -- return ENAMETOOLONG */ ! movl $ENAMETOOLONG, %eax ! ! 6: /* set *lencopied and return %eax */ ! movl 20(%esp), %edx ! orl %edx, %edx ! jz 7f ! movl 16(%esp), %ecx ! subl %ebx, %ecx ! movl %ecx, 0(%edx) ! 7: ! popl %ebx ret + # insb(port,addr,cnt) .globl _insb ALIGN32 *************** *** 918,1056 **** popl %ebx ret /* ! * {fu,su},{byte,word} */ ALIGN32 ! ALTENTRY(fuiword) ! ENTRY(fuword) ! movl _curpcb,%ecx ! movl $fusufault,PCB_ONFAULT(%ecx) ! movl 4(%esp),%edx ! .byte 0x65 # use gs ! movl 0(%edx),%eax ! movl $0,PCB_ONFAULT(%ecx) ! ret ! ALIGN32 ! ENTRY(fusword) ! movl _curpcb,%ecx ! movl $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate ! movl 4(%esp),%edx ! .byte 0x65 # use gs ! movzwl 0(%edx),%eax ! movl $0,PCB_ONFAULT(%ecx) ! ret ! ALIGN32 ! ALTENTRY(fuibyte) ! ENTRY(fubyte) ! movl _curpcb,%ecx ! movl $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate ! movl 4(%esp),%edx ! .byte 0x65 # use gs ! movzbl 0(%edx),%eax ! movl $0,PCB_ONFAULT(%ecx) ret ! ! ALIGN32 ! fusufault: ! movl _curpcb,%ecx ! xorl %eax,%eax ! movl %eax,PCB_ONFAULT(%ecx) #in case we page/protection violate decl %eax ret - ALIGN32 - ALTENTRY(suiword) - ENTRY(suword) - movl _curpcb,%ecx - movl $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate - movl 4(%esp),%edx - movl 8(%esp),%eax ! #ifdef notdef ! shrl $IDXSHIFT, %edx /* fetch pte associated with address */ andb $0xfc, %dl ! movl _PTmap(%edx), %edx ! ! andb $7, %dl /* if we are the one case that won't trap... */ ! cmpb $5 , %edx ! jne 1f ! /* ... then simulate the trap! */ ! pushl %edi ! call _trapwrite /* trapwrite(addr) */ popl %edx ! cmpl $0, %eax /* if not ok, return */ ! jne fusufault ! movl 8(%esp),%eax /* otherwise, continue with reference */ 1: ! movl 4(%esp),%edx ! #endif ! .byte 0x65 # use gs ! movl %eax,0(%edx) ! xorl %eax,%eax ! movl %eax,PCB_ONFAULT(%ecx) #in case we page/protection violate ret ! ALIGN32 ! ENTRY(susword) ! movl _curpcb,%ecx ! movl $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate ! movl 4(%esp),%edx ! movl 8(%esp),%eax ! #ifdef notdef ! shrl $IDXSHIFT, %edx /* calculate pte address */ ! andb $0xfc, %dl ! movl _PTmap(%edx), %edx ! andb $7, %edx /* if we are the one case that won't trap... */ ! cmpb $5 , %edx ! jne 1f ! /* ..., then simulate the trap! */ ! pushl %edi ! call _trapwrite /* trapwrite(addr) */ popl %edx ! movl _curpcb, %ecx # restore trashed registers ! cmpl $0, %eax /* if not ok, return */ ! jne fusufault ! movl 8(%esp),%eax ! 1: movl 4(%esp),%edx ! #endif ! .byte 0x65 # use gs ! movw %ax,0(%edx) ! xorl %eax,%eax ! movl %eax,PCB_ONFAULT(%ecx) #in case we page/protection violate ret ALIGN32 ! ALTENTRY(suibyte) ! ENTRY(subyte) ! movl _curpcb,%ecx ! movl $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate ! movl 4(%esp),%edx ! movl 8(%esp),%eax ! #ifdef notdef ! shrl $IDXSHIFT, %edx /* calculate pte address */ ! andb $0xfc, %dl ! movl _PTmap(%edx), %edx ! andb $7, %edx /* if we are the one case that won't trap... */ ! cmpb $5 , %edx ! jne 1f ! /* ..., then simulate the trap! */ ! pushl %edi ! call _trapwrite /* trapwrite(addr) */ popl %edx ! movl _curpcb, %ecx # restore trashed registers ! cmpl $0, %eax /* if not ok, return */ ! jne fusufault ! movl 8(%esp),%eax ! 1: movl 4(%esp),%edx ! #endif ! .byte 0x65 # use gs ! movb %eax,0(%edx) ! xorl %eax,%eax ! movl %eax,PCB_ONFAULT(%ecx) #in case we page/protection violate ret ALIGN32 ENTRY(setjmp) --- 1100,1253 ---- popl %ebx ret + /* ! * fubyte family: get a byte/word from userspace. ! * May 1993 Christoph Robitschko <chmr@edvz.tu-graz.ac.at> */ ALIGN32 ! .globl _fubyte, _fuibyte ! _fubyte: ! _fuibyte: ! movl _curpcb, %ecx ! movl $fusufault, PCB_ONFAULT(%ecx) ! movl 4(%esp), %edx ! movzbl 0(%edx), %eax ! jmp fu_checkpte ! ALIGN32 ! .globl _fusword ! _fusword: ! movl _curpcb, %ecx ! movl $fusufault, PCB_ONFAULT(%ecx) ! movl 4(%esp), %edx ! movzwl 0(%edx), %eax ! jmp fu_checkpte ! ALIGN32 ! .globl _fuword, _fuiword ! _fuword: ! _fuiword: ! movl _curpcb, %ecx ! movl $fusufault, PCB_ONFAULT(%ecx) ! movl 4(%esp), %edx ! movl 0(%edx), %eax ! ! fu_checkpte: ! shrl $IDXSHIFT, %edx /* check PTE of address */ ! andb $0xfc, %dl ! movb _PTmap(%edx), %dl ! andb $0x5, %dl /* Page must be VALID + USERACC */ ! cmpb $0x5, %dl ! jne 1f ! movl $0, PCB_ONFAULT(%ecx) ret ! ! 1: ! /* should we call trapread here ? */ ! fusufault: ! xorl %eax, %eax ! movl _curpcb, %ecx ! movl %eax, PCB_ONFAULT(%ecx) decl %eax ret ! /* ! * subyte family: write a byte/word to userspace. ! * These routines differ only in one instruction (the data move). ! * May 1993 Christoph Robitschko <chmr@edvz.tu-graz.ac.at> ! */ ! ALIGN32 ! .globl _subyte, _suibyte ! _subyte: ! _suibyte: ! movl _curpcb, %ecx ! movl $fusufault, PCB_ONFAULT(%ecx) ! movl 4(%esp), %edx ! movl %edx, %ecx ! shrl $IDXSHIFT, %edx andb $0xfc, %dl ! movb _PTmap(%edx), %dl ! andb $0x7, %dl /* must be VALID + USERACC + WRITE */ ! cmpb $0x7, %dl ! je 1f ! /* simulate a trap */ ! pushl %ecx ! call _trapwrite popl %edx ! orl %eax, %eax ! jnz fusufault 1: ! movl 4(%esp), %edx ! movl 8(%esp), %eax ! movb %al, 0(%edx) ! xorl %eax, %eax ! movl _curpcb, %ecx ! movl %eax, PCB_ONFAULT(%ecx) ret ! ! ! ALIGN32 ! .globl _susword ! _susword: ! movl _curpcb, %ecx ! movl $fusufault, PCB_ONFAULT(%ecx) ! movl 4(%esp), %edx ! movl %edx, %ecx ! shrl $IDXSHIFT, %edx ! andb $0xfc, %dl ! movb _PTmap(%edx), %dl ! andb $0x7, %dl /* must be VALID + USERACC + WRITE */ ! cmpb $0x7, %dl ! je 1f ! /* simulate a trap */ ! pushl %ecx ! call _trapwrite popl %edx ! orl %eax, %eax ! jnz fusufault ! 1: ! movl 4(%esp), %edx ! movl 8(%esp), %eax ! movw %ax, 0(%edx) ! xorl %eax, %eax ! movl _curpcb, %ecx ! movl %eax, PCB_ONFAULT(%ecx) ret + + ALIGN32 ! .globl _suword, _suiword ! _suword: ! _suiword: ! movl _curpcb, %ecx ! movl $fusufault, PCB_ONFAULT(%ecx) ! movl 4(%esp), %edx ! movl %edx, %ecx ! shrl $IDXSHIFT, %edx ! andb $0xfc, %dl ! movb _PTmap(%edx), %dl ! andb $0x7, %dl /* must be VALID + USERACC + WRITE */ ! cmpb $0x7, %dl ! je 1f ! /* simulate a trap */ ! pushl %ecx ! call _trapwrite popl %edx ! orl %eax, %eax ! jnz fusufault ! 1: ! movl 4(%esp), %edx ! movl 8(%esp), %eax ! movl %eax, 0(%edx) ! xorl %eax, %eax ! movl _curpcb, %ecx ! movl %eax, PCB_ONFAULT(%ecx) ret + ALIGN32 ENTRY(setjmp) === CUT HERE === trap.c.patch follows ========================================== *** /sys/i386/i386/trap.c.pk023 Wed May 12 07:42:58 1993 --- /sys/i386/i386/trap.c Wed May 12 07:59:53 1993 *************** *** 410,415 **** --- 410,427 ---- else return(1); } + int trapread(unsigned addr) { + int rv; + vm_offset_t va; + + va = trunc_page((vm_offset_t)addr); + if (va > VM_MAXUSER_ADDRESS) return(1); + rv = vm_fault(&curproc->p_vmspace->vm_map, va, + VM_PROT_READ, FALSE); + if (rv == KERN_SUCCESS) return(0); + else return(1); + } + /* * syscall(frame): * System call request from POSIX system call gate interface to kernel. === CUT HERE === machdep.c.patch follows ======================================= *** /sys/i386/i386/machdep.c.pk023 Wed May 12 07:42:57 1993 --- /sys/i386/i386/machdep.c Wed May 12 07:56:27 1993 *************** *** 1059,1064 **** --- 1059,1066 ---- vmunaccess() {} + #ifdef notanymore + /* assembler versions now in locore.s */ /* * Below written in C to allow access to debugging code */ *************** *** 1119,1121 **** --- 1121,1124 ---- if(lencopied) *lencopied = tally; return(ENAMETOOLONG); } + #endif === CUT HERE === End of patches ================================================