aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-17 15:17:59 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:56:38 -0400
commit663f4deca76cc99ac7bf800a925fc5e5eb70dbb3 (patch)
treef381b4bc475b2bca9ee8d995484e32de0165f38c
parent9fd4d05949d58786d4453191b2b203b8a691c476 (diff)
[readdir] convert qnx4
... and use strnlen() instead of strlen() - it's done on untrusted data, after all. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/qnx4/dir.c66
1 files changed, 31 insertions, 35 deletions
diff --git a/fs/qnx4/dir.c b/fs/qnx4/dir.c
index 28ce014b3cef..b218f965817b 100644
--- a/fs/qnx4/dir.c
+++ b/fs/qnx4/dir.c
@@ -14,9 +14,9 @@
14#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
15#include "qnx4.h" 15#include "qnx4.h"
16 16
17static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) 17static int qnx4_readdir(struct file *file, struct dir_context *ctx)
18{ 18{
19 struct inode *inode = file_inode(filp); 19 struct inode *inode = file_inode(file);
20 unsigned int offset; 20 unsigned int offset;
21 struct buffer_head *bh; 21 struct buffer_head *bh;
22 struct qnx4_inode_entry *de; 22 struct qnx4_inode_entry *de;
@@ -26,48 +26,44 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
26 int size; 26 int size;
27 27
28 QNX4DEBUG((KERN_INFO "qnx4_readdir:i_size = %ld\n", (long) inode->i_size)); 28 QNX4DEBUG((KERN_INFO "qnx4_readdir:i_size = %ld\n", (long) inode->i_size));
29 QNX4DEBUG((KERN_INFO "filp->f_pos = %ld\n", (long) filp->f_pos)); 29 QNX4DEBUG((KERN_INFO "pos = %ld\n", (long) ctx->pos));
30 30
31 while (filp->f_pos < inode->i_size) { 31 while (ctx->pos < inode->i_size) {
32 blknum = qnx4_block_map( inode, filp->f_pos >> QNX4_BLOCK_SIZE_BITS ); 32 blknum = qnx4_block_map(inode, ctx->pos >> QNX4_BLOCK_SIZE_BITS);
33 bh = sb_bread(inode->i_sb, blknum); 33 bh = sb_bread(inode->i_sb, blknum);
34 if(bh==NULL) { 34 if (bh == NULL) {
35 printk(KERN_ERR "qnx4_readdir: bread failed (%ld)\n", blknum); 35 printk(KERN_ERR "qnx4_readdir: bread failed (%ld)\n", blknum);
36 break; 36 return 0;
37 } 37 }
38 ix = (int)(filp->f_pos >> QNX4_DIR_ENTRY_SIZE_BITS) % QNX4_INODES_PER_BLOCK; 38 ix = (ctx->pos >> QNX4_DIR_ENTRY_SIZE_BITS) % QNX4_INODES_PER_BLOCK;
39 while (ix < QNX4_INODES_PER_BLOCK) { 39 for (; ix < QNX4_INODES_PER_BLOCK; ix++, ctx->pos += QNX4_DIR_ENTRY_SIZE) {
40 offset = ix * QNX4_DIR_ENTRY_SIZE; 40 offset = ix * QNX4_DIR_ENTRY_SIZE;
41 de = (struct qnx4_inode_entry *) (bh->b_data + offset); 41 de = (struct qnx4_inode_entry *) (bh->b_data + offset);
42 size = strlen(de->di_fname); 42 if (!de->di_fname[0])
43 if (size) { 43 continue;
44 if ( !( de->di_status & QNX4_FILE_LINK ) && size > QNX4_SHORT_NAME_MAX ) 44 if (!(de->di_status & (QNX4_FILE_USED|QNX4_FILE_LINK)))
45 size = QNX4_SHORT_NAME_MAX; 45 continue;
46 else if ( size > QNX4_NAME_MAX ) 46 if (!(de->di_status & QNX4_FILE_LINK))
47 size = QNX4_NAME_MAX; 47 size = QNX4_SHORT_NAME_MAX;
48 48 else
49 if ( ( de->di_status & (QNX4_FILE_USED|QNX4_FILE_LINK) ) != 0 ) { 49 size = QNX4_NAME_MAX;
50 QNX4DEBUG((KERN_INFO "qnx4_readdir:%.*s\n", size, de->di_fname)); 50 size = strnlen(de->di_fname, size);
51 if ( ( de->di_status & QNX4_FILE_LINK ) == 0 ) 51 QNX4DEBUG((KERN_INFO "qnx4_readdir:%.*s\n", size, de->di_fname));
52 ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1; 52 if (!(de->di_status & QNX4_FILE_LINK))
53 else { 53 ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1;
54 le = (struct qnx4_link_info*)de; 54 else {
55 ino = ( le32_to_cpu(le->dl_inode_blk) - 1 ) * 55 le = (struct qnx4_link_info*)de;
56 QNX4_INODES_PER_BLOCK + 56 ino = ( le32_to_cpu(le->dl_inode_blk) - 1 ) *
57 le->dl_inode_ndx; 57 QNX4_INODES_PER_BLOCK +
58 } 58 le->dl_inode_ndx;
59 if (filldir(dirent, de->di_fname, size, filp->f_pos, ino, DT_UNKNOWN) < 0) { 59 }
60 brelse(bh); 60 if (!dir_emit(ctx, de->di_fname, size, ino, DT_UNKNOWN)) {
61 goto out; 61 brelse(bh);
62 } 62 return 0;
63 }
64 } 63 }
65 ix++;
66 filp->f_pos += QNX4_DIR_ENTRY_SIZE;
67 } 64 }
68 brelse(bh); 65 brelse(bh);
69 } 66 }
70out:
71 return 0; 67 return 0;
72} 68}
73 69
@@ -75,7 +71,7 @@ const struct file_operations qnx4_dir_operations =
75{ 71{
76 .llseek = generic_file_llseek, 72 .llseek = generic_file_llseek,
77 .read = generic_read_dir, 73 .read = generic_read_dir,
78 .readdir = qnx4_readdir, 74 .iterate = qnx4_readdir,
79 .fsync = generic_file_fsync, 75 .fsync = generic_file_fsync,
80}; 76};
81 77