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 ================================================