summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrtm <rtm>2006-08-26 16:31:05 +0000
committerrtm <rtm>2006-08-26 16:31:05 +0000
commit03c70cc2e629e2ad8dcd5718be0132f17b9b8328 (patch)
tree222574119db147dfb92dce4f1740c0a908216dda
parenta6c28c9779da5f0b98a1698d66eae0708e395e7d (diff)
downloadxv6-labs-03c70cc2e629e2ad8dcd5718be0132f17b9b8328.tar.gz
xv6-labs-03c70cc2e629e2ad8dcd5718be0132f17b9b8328.tar.bz2
xv6-labs-03c70cc2e629e2ad8dcd5718be0132f17b9b8328.zip
consistently ignore more than 14 chars in path component
forbid create or write of existing directory mkdir("d1/d2/d3"), .. should refer to d2, not cwd mkdir increase parent link count
-rw-r--r--fs.c5
-rw-r--r--fstests.c66
-rw-r--r--syscall.c30
3 files changed, 91 insertions, 10 deletions
diff --git a/fs.c b/fs.c
index a83e937..6c552e6 100644
--- a/fs.c
+++ b/fs.c
@@ -499,7 +499,10 @@ namei(char *path, int mode, uint *ret_off, char **ret_last, struct inode **ret_i
for(i = 0; i < DIRSIZ && cp[i] != '/' && cp[i]; i++)
if(cp[i] != ep->name[i])
break;
- if((cp[i] == '\0' || cp[i] == '/') && (i >= DIRSIZ || ep->name[i] == '\0')){
+ if((cp[i] == '\0' || cp[i] == '/' || i >= DIRSIZ) &&
+ (i >= DIRSIZ || ep->name[i] == '\0')){
+ while(cp[i] != '\0' && cp[i] != '/')
+ i++;
off += (uchar*)ep - bp->data;
ninum = ep->inum;
brelse(bp);
diff --git a/fstests.c b/fstests.c
index d6356ac..ac9478e 100644
--- a/fstests.c
+++ b/fstests.c
@@ -412,8 +412,9 @@ bigdir()
void
subdir()
{
- int fd;
+ int fd, cc;
+ unlink("ff");
if(mkdir("dd") != 0){
puts("subdir mkdir dd failed\n");
exit();
@@ -440,6 +441,18 @@ subdir()
write(fd, "FF", 2);
close(fd);
+ fd = open("dd/dd/../ff", 0);
+ if(fd < 0){
+ puts("open dd/dd/../ff failed\n");
+ exit();
+ }
+ cc = read(fd, buf, sizeof(buf));
+ if(cc != 2 || buf[0] != 'f'){
+ puts("dd/dd/../ff wrong content\n");
+ exit();
+ }
+ close(fd);
+
if(link("dd/dd/ff", "dd/dd/ffff") != 0){
puts("link dd/dd/ff dd/dd/ffff failed\n");
exit();
@@ -487,6 +500,18 @@ subdir()
puts("create dd/xx/ff succeeded!\n");
exit();
}
+ if(open("dd", O_CREATE) >= 0){
+ puts("create dd succeeded!\n");
+ exit();
+ }
+ if(open("dd", O_RDWR) >= 0){
+ puts("open dd rdwr succeeded!\n");
+ exit();
+ }
+ if(open("dd", O_WRONLY) >= 0){
+ puts("open dd wronly succeeded!\n");
+ exit();
+ }
if(link("dd/ff/ff", "dd/dd/xx") == 0){
puts("link dd/ff/ff dd/dd/xx succeeded!\n");
exit();
@@ -597,11 +622,50 @@ bigfile()
puts("bigfile ok\n");
}
+void
+fourteen()
+{
+ int fd;
+
+ if(mkdir("12345678901234") != 0){
+ puts("mkdir 12345678901234 failed\n");
+ exit();
+ }
+ if(mkdir("12345678901234/123456789012345") != 0){
+ puts("mkdir 12345678901234/123456789012345 failed\n");
+ exit();
+ }
+ fd = open("123456789012345/123456789012345/123456789012345", O_CREATE);
+ if(fd < 0){
+ puts("create 123456789012345/123456789012345/123456789012345 failed\n");
+ exit();
+ }
+ close(fd);
+ fd = open("12345678901234/12345678901234/12345678901234", 0);
+ if(fd < 0){
+ puts("open 12345678901234/12345678901234/12345678901234 failed\n");
+ exit();
+ }
+ close(fd);
+
+ if(mkdir("12345678901234/12345678901234") == 0){
+ puts("mkdir 12345678901234/12345678901234 succeeded!\n");
+ exit();
+ }
+ if(mkdir("123456789012345/12345678901234") == 0){
+ puts("mkdir 12345678901234/123456789012345 succeeded!\n");
+ exit();
+ }
+
+ puts("fourteen ok\n");
+}
+
int
main(int argc, char *argv[])
{
puts("fstests starting\n");
+ fourteen();
bigfile();
subdir();
// bigdir(); // slow
diff --git a/syscall.c b/syscall.c
index 9e256a8..b0933db 100644
--- a/syscall.c
+++ b/syscall.c
@@ -240,12 +240,19 @@ sys_open(void)
return -1;
} else if(ip == 0){
return -1;
+ } else if(ip->type == T_DIR){
+ iput(ip);
+ return -1;
}
} else {
ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0);
if(ip == 0)
return -1;
}
+ if(ip->type == T_DIR && ((arg1 & O_RDWR) || (arg1 & O_WRONLY))){
+ iput(ip);
+ return -1;
+ }
if((fd = fd_alloc()) == 0){
iput(ip);
@@ -305,10 +312,11 @@ sys_mkdir(void)
{
struct proc *cp = curproc[cpu()];
struct inode *nip;
- struct inode *pip;
+ struct inode *dp;
uint arg0;
int l;
struct dirent de;
+ char *last;
if(fetcharg(0, &arg0) < 0)
return -1;
@@ -316,26 +324,32 @@ sys_mkdir(void)
if((l = checkstring(arg0)) < 0)
return -1;
- if(l >= DIRSIZ)
+ dp = namei(cp->mem + arg0, NAMEI_CREATE, 0, &last, 0);
+ if(dp == 0)
return -1;
- nip = mknod (cp->mem + arg0, T_DIR, 0, 0);
- if(nip == 0)
+ nip = mknod1(dp, last, T_DIR, 0, 0);
+ if(nip == 0){
+ iput(dp);
return -1;
+ }
+
+ dp->nlink += 1;
+ iupdate(dp);
memset (de.name, '\0', DIRSIZ);
de.name[0] = '.';
de.inum = nip->inum;
writei (nip, (char *) &de, 0, sizeof(de));
- pip = namei(".", NAMEI_LOOKUP, 0, 0, 0);
- de.inum = pip->inum;
+ de.inum = dp->inum;
de.name[1] = '.';
- iput(pip);
writei (nip, (char *) &de, sizeof(de), sizeof(de));
+ iput(dp);
iput(nip);
- return (nip == 0) ? -1 : 0;
+
+ return 0;
}