From: Thomas Veerman Date: Tue, 17 Jul 2012 08:47:51 +0000 (+0000) Subject: VFS: prevent buffer overflow X-Git-Tag: v3.2.1~450 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/Bv9ARM.ch09.html?a=commitdiff_plain;h=06f49fe1674cf62d26f586c48b23d2bc1dc9b79f;p=minix.git VFS: prevent buffer overflow If an FS returns faulty struct dirent data, VFS could overflow a buffer that holds this data. --- diff --git a/servers/vfs/path.c b/servers/vfs/path.c index b3baf5815..bb9db3a2c 100644 --- a/servers/vfs/path.c +++ b/servers/vfs/path.c @@ -10,9 +10,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -545,9 +547,11 @@ struct vnode *dirp; struct vnode *entry; char ename[NAME_MAX + 1]; { +#define DIR_ENTRIES 8 +#define DIR_ENTRY_SIZE (sizeof(struct dirent) + NAME_MAX) u64_t pos, new_pos; - int r, consumed, totalbytes; - char buf[(sizeof(struct dirent) + NAME_MAX) * 8]; + int r, consumed, totalbytes, name_len; + char buf[DIR_ENTRY_SIZE * DIR_ENTRIES]; struct dirent *cur; pos = make64(0, 0); @@ -569,9 +573,14 @@ char ename[NAME_MAX + 1]; do { cur = (struct dirent *) (buf + consumed); + name_len = cur->d_reclen - offsetof(struct dirent, d_name) - 1; + + if(cur->d_name + name_len >= &buf[DIR_ENTRIES * DIR_ENTRY_SIZE]) + return(EINVAL); /* Rubbish in dir entry */ if (entry->v_inode_nr == cur->d_ino) { /* found the entry we were looking for */ - strlcpy(ename, cur->d_name, NAME_MAX+1); + strlcpy(ename, cur->d_name, + MIN(name_len + 1, NAME_MAX + 1)); ename[NAME_MAX] = '\0'; return(OK); }