diff --git a/vfs/ChangeLog b/vfs/ChangeLog index a2137e136..4f91b2c7a 100644 --- a/vfs/ChangeLog +++ b/vfs/ChangeLog @@ -1,5 +1,8 @@ 2003-10-26 Pavel Roskin + * direntry.c (vfs_s_find_inode): Only allow search from root. + Change second argument to superblock to prevent abuse. + * direntry.c (vfs_s_find_entry_tree): Eliminate buffer of fixed size. Don't prepare path for vfs_s_resolve_symlink(). (vfs_s_resolve_symlink): Remove unused argument "path". diff --git a/vfs/cpio.c b/vfs/cpio.c index 1ca17e7ef..7a294c147 100644 --- a/vfs/cpio.c +++ b/vfs/cpio.c @@ -432,7 +432,7 @@ static int cpio_create_entry(struct vfs_class *me, struct vfs_s_super *super, st while(name[strlen(name)-1] == PATH_SEP) name[strlen(name)-1] = 0; if((tn = strrchr(name, PATH_SEP))) { *tn = 0; - root = vfs_s_find_inode(me, root, name, LINK_FOLLOW, FL_MKDIR); /* CHECKME! What function here? */ + root = vfs_s_find_inode(me, super, name, LINK_FOLLOW, FL_MKDIR); *tn = PATH_SEP; tn++; } else diff --git a/vfs/direntry.c b/vfs/direntry.c index ae1f1596e..5e4047f6d 100644 --- a/vfs/direntry.c +++ b/vfs/direntry.c @@ -307,7 +307,7 @@ vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root, char *p char *dirname, *name, *save; struct vfs_s_inode *ino; split_dir_name (me, path, &dirname, &name, &save); - ino = vfs_s_find_inode (me, root, dirname, follow, flags | FL_DIR); + ino = vfs_s_find_inode (me, root->super, dirname, follow, flags | FL_DIR); if (save) *save = PATH_SEP; return vfs_s_find_entry_tree (me, ino, name, follow, flags); @@ -350,12 +350,13 @@ vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root, char *p } struct vfs_s_inode * -vfs_s_find_inode (struct vfs_class *me, struct vfs_s_inode *root, char *path, int follow, int flags) +vfs_s_find_inode (struct vfs_class *me, const struct vfs_s_super *super, + char *path, int follow, int flags) { struct vfs_s_entry *ent; if ((MEDATA->find_entry == vfs_s_find_entry_tree) && (!*path)) - return root; - ent = (MEDATA->find_entry)(me, root, path, follow, flags); + return super->root; + ent = (MEDATA->find_entry) (me, super->root, path, follow, flags); if (!ent) return NULL; return ent->ino; @@ -541,13 +542,20 @@ vfs_s_inode_from_path (struct vfs_class *me, char *name, int flags) struct vfs_s_inode *ino; char *q; - if (!(q = vfs_s_get_path_mangle (me, name, &super, 0))) + if (!(q = vfs_s_get_path_mangle (me, name, &super, 0))) return NULL; - ino = vfs_s_find_inode (me, super->root, q, flags & FL_FOLLOW ? LINK_FOLLOW : LINK_NO_FOLLOW, flags & ~FL_FOLLOW); + ino = + vfs_s_find_inode (me, super, q, + flags & FL_FOLLOW ? LINK_FOLLOW : LINK_NO_FOLLOW, + flags & ~FL_FOLLOW); if ((!ino) && (!*q)) /* We are asking about / directory of ftp server: assume it exists */ - ino = vfs_s_find_inode (me, super->root, q, flags & FL_FOLLOW ? LINK_FOLLOW : LINK_NO_FOLLOW, FL_DIR | (flags & ~FL_FOLLOW)); + ino = + vfs_s_find_inode (me, super, q, + flags & FL_FOLLOW ? LINK_FOLLOW : + LINK_NO_FOLLOW, + FL_DIR | (flags & ~FL_FOLLOW)); return ino; } @@ -686,7 +694,7 @@ vfs_s_open (struct vfs_class *me, char *file, int flags, int mode) if ((q = vfs_s_get_path_mangle (me, file, &super, 0)) == NULL) return NULL; - ino = vfs_s_find_inode (me, super->root, q, LINK_FOLLOW, FL_NONE); + ino = vfs_s_find_inode (me, super, q, LINK_FOLLOW, FL_NONE); if (ino && ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) ERRNOR (EEXIST, NULL); if (!ino){ @@ -700,9 +708,8 @@ vfs_s_open (struct vfs_class *me, char *file, int flags, int mode) return NULL; split_dir_name (me, q, &dirname, &name, &save); -/* FIXME: if vfs_s_find_inode returns NULL, this will do rather bad - things. */ - dir = vfs_s_find_inode (me, super->root, dirname, LINK_FOLLOW, FL_DIR); + /* FIXME: check if vfs_s_find_inode returns NULL */ + dir = vfs_s_find_inode (me, super, dirname, LINK_FOLLOW, FL_DIR); if (save) *save = PATH_SEP; ent = vfs_s_generate_entry (me, name, dir, 0755); diff --git a/vfs/tar.c b/vfs/tar.c index 5203cf597..f62cafef1 100644 --- a/vfs/tar.c +++ b/vfs/tar.c @@ -455,14 +455,14 @@ read_header (struct vfs_class *me, struct vfs_s_super *archive, int tard) q = current_file_name; } - parent = vfs_s_find_inode (me, archive->root, q, LINK_NO_FOLLOW, FL_MKDIR); + parent = vfs_s_find_inode (me, archive, q, LINK_NO_FOLLOW, FL_MKDIR); if (parent == NULL) { message (1, MSG_ERROR, _("Inconsistent tar archive")); return STATUS_BADCHECKSUM; } if (header->header.linkflag == LF_LINK) { - inode = vfs_s_find_inode (me, archive->root, current_link_name, LINK_NO_FOLLOW, 0); + inode = vfs_s_find_inode (me, archive, current_link_name, LINK_NO_FOLLOW, 0); if (inode == NULL) { message (1, MSG_ERROR, _("Inconsistent tar archive")); } else { diff --git a/vfs/xdirentry.h b/vfs/xdirentry.h index da0f1cf9e..f2f982bec 100644 --- a/vfs/xdirentry.h +++ b/vfs/xdirentry.h @@ -173,8 +173,8 @@ struct vfs_s_entry *vfs_s_find_entry_linear (struct vfs_class *me, char *path, int follow, int flags); struct vfs_s_inode *vfs_s_find_inode (struct vfs_class *me, - struct vfs_s_inode *root, char *path, - int follow, int flags); + const struct vfs_s_super *super, + char *path, int follow, int flags); struct vfs_s_inode *vfs_s_find_root (struct vfs_class *me, struct vfs_s_entry *entry);