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:
parent
a6c28c9779
commit
03c70cc2e6
3 changed files with 91 additions and 10 deletions
5
fs.c
5
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);
|
||||
|
|
66
fstests.c
66
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
|
||||
|
|
30
syscall.c
30
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue