diff --git a/tsk/fs/logical_fs.cpp b/tsk/fs/logical_fs.cpp index 9aaed7e789d59f39c3afb31d57993af20bdb8fc9..620547e83612b3e85da32ae25866cb8f775cd24a 100644 --- a/tsk/fs/logical_fs.cpp +++ b/tsk/fs/logical_fs.cpp @@ -206,6 +206,17 @@ convert_wide_string_to_utf8(const wchar_t *source) { } #endif +/* + * Check if we should set the type as directory. + * We currently treat sym links as regular files to avoid + * issues trying to read then as directories. + */ +int +shouldTreatAsDirectory(DWORD dwFileAttributes) { + return ((dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + && (!(dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))); +} + /* * Use data in the WIN32_FIND_DATA to populate a TSK_FS_FILE object. * Expects a_fs_file and a_fs_file->meta to be allocated @@ -232,7 +243,7 @@ populate_fs_file_from_win_find_data(const WIN32_FIND_DATA* fd, TSK_FS_FILE * a_f //a_fs_file->meta->mtime = filetime_to_timet(fd->ftLastWriteTime); // Set the type - if (fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (shouldTreatAsDirectory(fd->dwFileAttributes)) { a_fs_file->meta->type = TSK_FS_META_TYPE_DIR; } else { @@ -298,11 +309,19 @@ load_dir_and_file_lists_win(const TSK_TCHAR *base_path, vector<wstring>& file_na return TSK_ERR; } + if (TSTRLEN(search_path_wildcard) >= MAX_PATH) { + free(search_path_wildcard); + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_FS_GENFS); + tsk_error_set_errstr("load_dir_and_file_lists: Error looking up contents of directory (path too long) %" PRIttocTSK, base_path); + return TSK_ERR; + } + // Look up all files and folders in the base directory hFind = ::FindFirstFile(search_path_wildcard, &fd); if (hFind != INVALID_HANDLE_VALUE) { do { - if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (shouldTreatAsDirectory(fd.dwFileAttributes)) { if (mode == LOGICALFS_LOAD_ALL || mode == LOGICALFS_LOAD_DIRS_ONLY) { // For the moment at least, skip . and .. if (0 != wcsncmp(fd.cFileName, L"..", 3) && 0 != wcsncmp(fd.cFileName, L".", 3)) { @@ -753,6 +772,14 @@ logicalfs_file_add_meta(TSK_FS_INFO *a_fs, TSK_FS_FILE * a_fs_file, #ifdef TSK_WIN32 // Load the file + if (TSTRLEN(path) >= MAX_PATH) { + free(path); + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_FS_GENFS); + tsk_error_set_errstr("load_dir_and_file_lists: Error looking up contents of directory (path too long) %" PRIttocTSK, path); + return TSK_ERR; + } + WIN32_FIND_DATA fd; HANDLE hFind = ::FindFirstFile(path, &fd); if (hFind != INVALID_HANDLE_VALUE) { @@ -997,6 +1024,13 @@ logicalfs_dir_open_meta(TSK_FS_INFO *a_fs, TSK_FS_DIR ** a_fs_dir, // Add the folders for (auto it = begin(dir_names); it != end(dir_names); ++it) { TSK_INUM_T dir_inum = get_inum_from_directory_path(logical_fs_info, path, *it); + if (dir_inum == LOGICAL_INVALID_INUM) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_FS_GENFS); + tsk_error_set_errstr("logicalfs_dir_open_meta: Error looking up inum from path"); + return TSK_ERR; + } + TSK_FS_NAME *fs_name; #ifdef TSK_WIN32 @@ -1076,6 +1110,7 @@ logicalfs_dir_open_meta(TSK_FS_INFO *a_fs, TSK_FS_DIR ** a_fs_dir, tsk_fs_name_free(fs_name); return TSK_ERR; } + tsk_fs_name_free(fs_name); file_inum++; } @@ -1653,5 +1688,13 @@ logical_fs_open(TSK_IMG_INFO * img_info) { // Calculate the last inum fs->last_inum = find_max_inum(logical_fs_info); + // We don't really care about the last inum, but if traversing the + // folders to calculate it fails then we're going to encounter + // the same error when using the logical file system. + if (fs->last_inum == LOGICAL_INVALID_INUM) { + logicalfs_close(fs); + return NULL; + } + return fs; } diff --git a/tsk/img/img_io.c b/tsk/img/img_io.c index a8c54b3c0b8dbf407d948598b0ade8fe73e532c3..dd84b24c6857f8f25121459239977d883de309a5 100755 --- a/tsk/img/img_io.c +++ b/tsk/img/img_io.c @@ -21,7 +21,7 @@ static ssize_t tsk_img_read_no_cache(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off, /* Some of the lower-level methods like block-sized reads. * So if the len is not that multiple, then make it. */ - if (a_len % a_img_info->sector_size) { + if ((a_img_info->sector_size > 0) && (a_len % a_img_info->sector_size)) { char *buf2 = a_buf; size_t len_tmp; @@ -91,6 +91,7 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off, // maps to an int64 we prefer it over size_t although likely checking // for ( a_len > SSIZE_MAX ) is better but the code does not seem to // use that approach. + if ((TSK_OFF_T) a_len < 0) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_ARG); @@ -212,6 +213,7 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off, // since read_count is used in the calculation it may not be negative. // Also it does not make sense to copy data when the read_count is 0. if (read_count > 0) { + TSK_OFF_T rel_off = 0; a_img_info->cache_age[cache_next] = CACHE_AGE; a_img_info->cache_len[cache_next] = read_count; diff --git a/tsk/img/logical_img.c b/tsk/img/logical_img.c index c687fe8d5eaf6d64ad53930ed269e159dcbde4b8..faf2276749c5429252d6bf0c3a01f040d77c074e 100644 --- a/tsk/img/logical_img.c +++ b/tsk/img/logical_img.c @@ -79,7 +79,9 @@ logical_close(TSK_IMG_INFO * img_info) static ssize_t logical_read(TSK_IMG_INFO * img_info, TSK_OFF_T offset, char *buf, size_t len) { - printf("Logical image read not supported\n"); + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_IMG_READ); + tsk_error_set_errstr("logical_read: Logical image read is not supported"); return 0; }