When either_copyin/out fails, return an error from write/read

Add a test to check that read/write return an error
This commit is contained in:
Frans Kaashoek 2020-09-24 13:18:54 -04:00
parent 8c67f96b72
commit 6750608824
2 changed files with 50 additions and 0 deletions

View file

@ -468,6 +468,7 @@ readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n)
m = min(n - tot, BSIZE - off%BSIZE); m = min(n - tot, BSIZE - off%BSIZE);
if(either_copyout(user_dst, dst, bp->data + (off % BSIZE), m) == -1) { if(either_copyout(user_dst, dst, bp->data + (off % BSIZE), m) == -1) {
brelse(bp); brelse(bp);
tot = -1;
break; break;
} }
brelse(bp); brelse(bp);
@ -495,6 +496,7 @@ writei(struct inode *ip, int user_src, uint64 src, uint off, uint n)
m = min(n - tot, BSIZE - off%BSIZE); m = min(n - tot, BSIZE - off%BSIZE);
if(either_copyin(bp->data + (off % BSIZE), user_src, src, m) == -1) { if(either_copyin(bp->data + (off % BSIZE), user_src, src, m) == -1) {
brelse(bp); brelse(bp);
n = -1;
break; break;
} }
log_write(bp); log_write(bp);

View file

@ -233,6 +233,53 @@ copyinstr3(char *s)
} }
} }
// See if the kernel refuses to read/write user memory that the
// application doesn't have anymore, because it returned it.
void
rwsbrk()
{
int fd, n;
uint64 a = (uint64) sbrk(8192);
if(a == 0xffffffffffffffffLL) {
printf("sbrk(rwsbrk) failed\n");
exit(1);
}
if ((uint64) sbrk(-8192) == 0xffffffffffffffffLL) {
printf("sbrk(rwsbrk) shrink failed\n");
exit(1);
}
fd = open("rwsbrk", O_CREATE|O_WRONLY);
if(fd < 0){
printf("open(rwsbrk) failed\n");
exit(1);
}
n = write(fd, (void*)(a+4096), 1024);
if(n >= 0){
printf("write(fd, %p, 1024) returned %d, not -1\n", a+4096, n);
exit(1);
}
close(fd);
unlink("rwsbrk");
fd = open("README", O_RDONLY);
if(fd < 0){
printf("open(rwsbrk) failed\n");
exit(1);
}
n = read(fd, (void*)(a+4096), 10);
if(n >= 0){
printf("read(fd, %p, 10) returned %d, not -1\n", a+4096, n);
exit(1);
}
close(fd);
exit(0);
}
// test O_TRUNC. // test O_TRUNC.
void void
truncate1(char *s) truncate1(char *s)
@ -2644,6 +2691,7 @@ main(int argc, char *argv[])
{copyinstr1, "copyinstr1"}, {copyinstr1, "copyinstr1"},
{copyinstr2, "copyinstr2"}, {copyinstr2, "copyinstr2"},
{copyinstr3, "copyinstr3"}, {copyinstr3, "copyinstr3"},
{rwsbrk, "rwsbrk" },
{truncate1, "truncate1"}, {truncate1, "truncate1"},
{truncate2, "truncate2"}, {truncate2, "truncate2"},
{truncate3, "truncate3"}, {truncate3, "truncate3"},