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
This commit is contained in:
rtm 2006-08-26 16:31:05 +00:00
parent a6c28c9779
commit 03c70cc2e6
3 changed files with 91 additions and 10 deletions

5
fs.c
View file

@ -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++) for(i = 0; i < DIRSIZ && cp[i] != '/' && cp[i]; i++)
if(cp[i] != ep->name[i]) if(cp[i] != ep->name[i])
break; 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; off += (uchar*)ep - bp->data;
ninum = ep->inum; ninum = ep->inum;
brelse(bp); brelse(bp);

View file

@ -412,8 +412,9 @@ bigdir()
void void
subdir() subdir()
{ {
int fd; int fd, cc;
unlink("ff");
if(mkdir("dd") != 0){ if(mkdir("dd") != 0){
puts("subdir mkdir dd failed\n"); puts("subdir mkdir dd failed\n");
exit(); exit();
@ -440,6 +441,18 @@ subdir()
write(fd, "FF", 2); write(fd, "FF", 2);
close(fd); 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){ if(link("dd/dd/ff", "dd/dd/ffff") != 0){
puts("link dd/dd/ff dd/dd/ffff failed\n"); puts("link dd/dd/ff dd/dd/ffff failed\n");
exit(); exit();
@ -487,6 +500,18 @@ subdir()
puts("create dd/xx/ff succeeded!\n"); puts("create dd/xx/ff succeeded!\n");
exit(); 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){ if(link("dd/ff/ff", "dd/dd/xx") == 0){
puts("link dd/ff/ff dd/dd/xx succeeded!\n"); puts("link dd/ff/ff dd/dd/xx succeeded!\n");
exit(); exit();
@ -597,11 +622,50 @@ bigfile()
puts("bigfile ok\n"); 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 int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
puts("fstests starting\n"); puts("fstests starting\n");
fourteen();
bigfile(); bigfile();
subdir(); subdir();
// bigdir(); // slow // bigdir(); // slow

View file

@ -240,12 +240,19 @@ sys_open(void)
return -1; return -1;
} else if(ip == 0){ } else if(ip == 0){
return -1; return -1;
} else if(ip->type == T_DIR){
iput(ip);
return -1;
} }
} else { } else {
ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0); ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0);
if(ip == 0) if(ip == 0)
return -1; return -1;
} }
if(ip->type == T_DIR && ((arg1 & O_RDWR) || (arg1 & O_WRONLY))){
iput(ip);
return -1;
}
if((fd = fd_alloc()) == 0){ if((fd = fd_alloc()) == 0){
iput(ip); iput(ip);
@ -305,10 +312,11 @@ sys_mkdir(void)
{ {
struct proc *cp = curproc[cpu()]; struct proc *cp = curproc[cpu()];
struct inode *nip; struct inode *nip;
struct inode *pip; struct inode *dp;
uint arg0; uint arg0;
int l; int l;
struct dirent de; struct dirent de;
char *last;
if(fetcharg(0, &arg0) < 0) if(fetcharg(0, &arg0) < 0)
return -1; return -1;
@ -316,26 +324,32 @@ sys_mkdir(void)
if((l = checkstring(arg0)) < 0) if((l = checkstring(arg0)) < 0)
return -1; return -1;
if(l >= DIRSIZ) dp = namei(cp->mem + arg0, NAMEI_CREATE, 0, &last, 0);
if(dp == 0)
return -1; return -1;
nip = mknod (cp->mem + arg0, T_DIR, 0, 0); nip = mknod1(dp, last, T_DIR, 0, 0);
if(nip == 0) if(nip == 0){
iput(dp);
return -1; return -1;
}
dp->nlink += 1;
iupdate(dp);
memset (de.name, '\0', DIRSIZ); memset (de.name, '\0', DIRSIZ);
de.name[0] = '.'; de.name[0] = '.';
de.inum = nip->inum; de.inum = nip->inum;
writei (nip, (char *) &de, 0, sizeof(de)); writei (nip, (char *) &de, 0, sizeof(de));
pip = namei(".", NAMEI_LOOKUP, 0, 0, 0); de.inum = dp->inum;
de.inum = pip->inum;
de.name[1] = '.'; de.name[1] = '.';
iput(pip);
writei (nip, (char *) &de, sizeof(de), sizeof(de)); writei (nip, (char *) &de, sizeof(de), sizeof(de));
iput(dp);
iput(nip); iput(nip);
return (nip == 0) ? -1 : 0;
return 0;
} }