patch-2.1.116 linux/fs/ext2/namei.c
Next file: linux/fs/nfsd/vfs.c
Previous file: linux/fs/exec.c
Back to the patch index
Back to the overall index
- Lines: 58
- Date:
Sat Aug 15 11:16:10 1998
- Orig file:
v2.1.115/linux/fs/ext2/namei.c
- Orig date:
Fri May 8 23:14:53 1998
diff -u --recursive --new-file v2.1.115/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
@@ -41,14 +41,17 @@
/*
* NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
+ *
+ * `len <= EXT2_NAME_LEN' is guaranteed by caller.
+ * `de != NULL' is guaranteed by caller.
*/
static inline int ext2_match (int len, const char * const name,
struct ext2_dir_entry_2 * de)
{
- if (!de || !le32_to_cpu(de->inode) || len > EXT2_NAME_LEN)
- return 0;
if (len != de->name_len)
return 0;
+ if (!de->inode)
+ return 0;
return !memcmp(name, de->name, len);
}
@@ -121,10 +124,17 @@
de = (struct ext2_dir_entry_2 *) bh->b_data;
dlimit = bh->b_data + sb->s_blocksize;
while ((char *) de < dlimit) {
- if (!ext2_check_dir_entry ("ext2_find_entry", dir,
- de, bh, offset))
- goto failure;
- if (ext2_match (namelen, name, de)) {
+ /* this code is executed quadratically often */
+ /* do minimal checking `by hand' */
+ int de_len;
+
+ if ((char *) de + namelen <= dlimit &&
+ ext2_match (namelen, name, de)) {
+ /* found a match -
+ just to be sure, do a full check */
+ if (!ext2_check_dir_entry("ext2_find_entry",
+ dir, de, bh, offset))
+ goto failure;
for (i = 0; i < NAMEI_RA_SIZE; ++i) {
if (bh_use[i] != bh)
brelse (bh_use[i]);
@@ -132,9 +142,13 @@
*res_dir = de;
return bh;
}
- offset += le16_to_cpu(de->rec_len);
+ /* prevent looping on a bad block */
+ de_len = le16_to_cpu(de->rec_len);
+ if (de_len <= 0)
+ goto failure;
+ offset += de_len;
de = (struct ext2_dir_entry_2 *)
- ((char *) de + le16_to_cpu(de->rec_len));
+ ((char *) de + de_len);
}
brelse (bh);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov