Re: updated orangefs tree at kernel.org

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Oct 09, 2015 at 12:03:33AM +0100, Al Viro wrote:

> And I haven't looked at the rest yet - some bugs I've mentioned are definitely
> still there (e.g. bogus iput() on failure of d_make_root() - it's already
> done by d_make_root() itself in that case, so what you are doing is double
> iput(); just remove it and be done with that), but I hadn't checked the
> whole list.  Will post more later tonight...

Directories:

1) I don't understand what happens to position in directory (ctx->pos).
AFAICS, you are reading directories in moderate chunks (up to 96
entries?) and use a token stored in *(file->private_data) to tell which
chunk it is.  So far, so good, but...  AFAICS ctx->pos is reset to 0
on the beginning of each such chunk.  Am I right assuming that looping
through a directory with readdir(3) and watching for return values of
telldir(3) will yield repeating offsets every time you go into the next
chunk?

2) More seriously, rewinddir(3) *must* rewind the directory.  With all
Linux libc variants it means lseek() to 0; AFAICS, orangefs directories
won't do it properly - all lseek attempts flat-out fail with ESPIPE.
Userland won't be happy...

3) ->pvfs_dirent_outcount is u32 and it comes from server with no validation
attempts ever made.  Now, look at
        readdir->dirent_array = kmalloc(readdir->pvfs_dirent_outcount *
                                        sizeof(*readdir->dirent_array),
in decode_dirents().  ->dirent_array is a structure consisting of pointer,
int and a 16-byte 64bit-aligned array.  IOW, it's size is greater than 1
and this product might wrap around.  You really should use kcalloc() there.

What's more, the loop parsing the response body is 
        for (i = 0; i < readdir->pvfs_dirent_outcount; i++) {
                dec_string(pptr, &readdir->dirent_array[i].d_name,
                           &readdir->dirent_array[i].d_length);
                readdir->dirent_array[i].khandle =
                        *(struct pvfs2_khandle *) *pptr;
                *pptr += 16;
        }
where dec_string(pptr, pbuf, plen) is defined as
        __u32 len = (*(__u32 *) *(pptr)); \
        *pbuf = *(pptr) + 4; \
        *(pptr) += roundup8(4 + len + 1); \
        if (plen) \
                *plen = len;\

Note that we do *not* validate len, so this code might end up dereferencing
any address within +-2Gb from the buffer.  You really can't assume that
server is neither insane nor compromised; this is a blatant security hole.

And please, drop these macros - you are not using enc_string() at all while
dec_string() is used only in decode_dirents() and would be easier to
understand if it had been spelled out right there.  Especially since you
need to add sanity checks (and buggering off should they fail) to it.

4)
	if (pos == 0) {
                ino = get_ino_from_khandle(dentry->d_inode);
                gossip_debug(GOSSIP_DIR_DEBUG,
                             "%s: calling dir_emit of \".\" with pos = %llu\n",
                             __func__,
                             llu(pos));
                ret = dir_emit(ctx, ".", 1, ino, DT_DIR);
                pos += 1;
        }
in pvfs2_readdir() is bloody odd.  What's wrong with emit_dot(), or,
for that matter, dir_emit_dots() to cover both that and .. right after
it.  You *are* setting ->i_ino to the same hash of khandle you are
using here anyway, so why not use the standard helpers?
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux