Ticket #3124: d_reclen.diff

File d_reclen.diff, 2.4 KB (added by Adek336, 11 years ago)

trace file names; sanity check against buffer overflow

  • src/system/kernel/fs/vfs.cpp

     
    54615461fix_dirent(struct vnode *parent, struct dirent *userEntry,
    54625462    struct io_context* ioContext, uint32* _length)
    54635463{
     5464#define lnd do { ktrace_printf("fix_dirent: %d\n", __LINE__); } while(0)
     5465    static int callCount = 0;
     5466    callCount++;
    54645467    char buffer[sizeof(struct dirent) + B_FILE_NAME_LENGTH];
    54655468    struct dirent* entry;
    54665469
     5470    bzero(&buffer, sizeof(buffer));
     5471
    54675472    if (IS_USER_ADDRESS(userEntry)) {
     5473        lnd;
    54685474        entry = (struct dirent*)buffer;
    54695475        if (user_memcpy(entry, userEntry, sizeof(struct dirent) - 1) != B_OK)
    54705476            return B_BAD_ADDRESS;
    54715477
    54725478        ASSERT(entry->d_reclen >= sizeof(struct dirent));
    54735479
     5480        if ( entry->d_reclen > sizeof(buffer))
     5481        {
     5482            panic("%d = entry->d_reclen > sizeof(buffer) = %d", entry->d_reclen, (unsigned)sizeof(buffer));
     5483            return B_BAD_VALUE;
     5484        }
     5485
    54745486        if (user_memcpy(entry->d_name, userEntry->d_name,
    54755487                entry->d_reclen - sizeof(struct dirent)) != B_OK)
    54765488            return B_BAD_ADDRESS;
    54775489    } else
    54785490        entry = userEntry;
    54795491
     5492    ktrace_printf("fix_dirent(%d): _length=%p, entry=%p, parent=%p, entry->d_name=%s\n",
     5493            callCount, _length, entry,parent, entry->d_name);
    54805494    *_length = entry->d_reclen;
     5495    lnd;
    54815496
    54825497    // set d_pdev and d_pino
    54835498    entry->d_pdev = parent->device;
     5499    lnd;
    54845500    entry->d_pino = parent->id;
     5501    lnd;
    54855502
    54865503    // If this is the ".." entry and the directory is the root of a FS,
    54875504    // we need to replace d_dev and d_ino with the actual values.
     
    55295546        return user_memcpy(userEntry, entry, sizeof(struct dirent) - 1);
    55305547
    55315548    return B_OK;
     5549#undef lnd
    55325550}
    55335551
    55345552
     
    55365554dir_read(struct io_context* ioContext, struct vnode *vnode, void *cookie,
    55375555    struct dirent *buffer, size_t bufferSize, uint32 *_count)
    55385556{
     5557    static int callCount=0;
     5558    callCount ++;
    55395559    if (!HAS_FS_CALL(vnode, read_dir))
    55405560        return EOPNOTSUPP;
    55415561
     
    55495569    if (count > 0) {
    55505570        for (uint32 i = 0; i < count; i++) {
    55515571            uint32 length;
     5572            ktrace_printf("dir_read(%d): cookie=%p, _count=%p, count=%d, i=%d, bufferSize=%d\n",
     5573                    callCount, cookie, _count, (unsigned)count, (unsigned)i, (unsigned)bufferSize);
     5574            ktrace_printf("fix_dirent args: parent=%p, userEntry=%p, ioContext=%p, _length=%p\n",
     5575                    vnode, buffer, ioContext, &length);
    55525576            error = fix_dirent(vnode, buffer, ioContext, &length);
    55535577            if (error != B_OK)
    55545578                return error;