summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app-admin/testdisk/files/fix_rare_crash-6.14.patch')
-rw-r--r--app-admin/testdisk/files/fix_rare_crash-6.14.patch227
1 files changed, 227 insertions, 0 deletions
diff --git a/app-admin/testdisk/files/fix_rare_crash-6.14.patch b/app-admin/testdisk/files/fix_rare_crash-6.14.patch
new file mode 100644
index 00000000000..913be7e32eb
--- /dev/null
+++ b/app-admin/testdisk/files/fix_rare_crash-6.14.patch
@@ -0,0 +1,227 @@
+From a2676d349a975a142f1119c0aecb435e1b0db8b8 Mon Sep 17 00:00:00 2001
+From: Christophe Grenier <grenier@cgsecurity.org>
+Date: Sat, 14 Jun 2014 12:08:59 +0200
+Subject: TestDisk: fix rare crash when listing NTFS directories
+
+
+diff --git a/src/ntfs_dir.c b/src/ntfs_dir.c
+index d416cea..b51c63d 100644
+--- a/src/ntfs_dir.c
++++ b/src/ntfs_dir.c
+@@ -167,7 +167,15 @@ static int ntfs_td_list_entry( struct ntfs_dir_struct *ls, const ntfschar *name
+ const MFT_REF mref, const unsigned dt_type)
+ {
+ int result = 0;
+- char *filename = (char *)calloc (1, MAX_PATH);
++ char *filename;
++ ntfs_inode *ni;
++ ntfs_attr_search_ctx *ctx_si = NULL;
++ file_info_t *new_file=NULL;
++ /* Keep FILE_NAME_WIN32 and FILE_NAME_POSIX */
++ if ((name_type & FILE_NAME_WIN32_AND_DOS) == FILE_NAME_DOS)
++ return 0;
++
++ filename = (char *)calloc (1, MAX_PATH);
+ if (!filename)
+ {
+ log_critical("ntfs_td_list_entry calloc failed\n");
+@@ -178,118 +186,111 @@ static int ntfs_td_list_entry( struct ntfs_dir_struct *ls, const ntfschar *name
+ if (ntfs_ucstoutf8(ls->cd, name, name_len, &filename, MAX_PATH) < 0 &&
+ ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) {
+ log_error("Cannot represent filename in current locale.\n");
+- goto free;
++ goto freefn;
+ }
+ #else
+ if (ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) {
+ log_error("Cannot represent filename in current locale.\n");
+- goto free;
++ goto freefn;
+ }
+ #endif
+
+ result = 0; /* These are successful */
+ if (MREF(mref) < FILE_first_user && filename[0] == '$') /* Hide system file */
+- goto free;
+- /* Keep FILE_NAME_WIN32 and FILE_NAME_POSIX */
+- if ((name_type & FILE_NAME_WIN32_AND_DOS) == FILE_NAME_DOS)
+- goto free;
+- {
+- ntfs_inode *ni;
+- ntfs_attr_search_ctx *ctx_si = NULL;
+- file_info_t *new_file=NULL;
++ goto freefn;
++ result = -1; /* Everything else is bad */
+
+- result = -1; /* Everything else is bad */
++ ni = ntfs_inode_open(ls->vol, mref);
++ if (!ni)
++ goto freefn;
++ new_file=(file_info_t*)MALLOC(sizeof(*new_file));
++ new_file->status=0;
++ new_file->st_ino=MREF(mref);
++ new_file->st_uid=0;
++ new_file->st_gid=0;
+
+- ni = ntfs_inode_open(ls->vol, mref);
+- if (!ni)
+- goto release;
+- new_file=(file_info_t*)MALLOC(sizeof(*new_file));
+- new_file->status=0;
+- td_list_add_tail(&new_file->list, &ls->dir_list->list);
+- new_file->st_ino=MREF(mref);
+- new_file->st_uid=0;
+- new_file->st_gid=0;
+-
+- ctx_si = ntfs_attr_get_search_ctx(ni, ni->mrec);
+- if (ctx_si)
++ ctx_si = ntfs_attr_get_search_ctx(ni, ni->mrec);
++ if (ctx_si)
++ {
++ if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 0, CASE_SENSITIVE, 0, NULL, 0, ctx_si)==0)
+ {
+- if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 0, CASE_SENSITIVE, 0, NULL, 0, ctx_si)==0)
++ const ATTR_RECORD *attr = ctx_si->attr;
++ const STANDARD_INFORMATION *si = (const STANDARD_INFORMATION*)((const char*)attr +
++ le16_to_cpu(attr->value_offset));
++ if(si)
+ {
+- const ATTR_RECORD *attr = ctx_si->attr;
+- const STANDARD_INFORMATION *si = (const STANDARD_INFORMATION*)((const char*)attr +
+- le16_to_cpu(attr->value_offset));
+- if(si)
+- {
+- new_file->td_atime=td_ntfs2utc(sle64_to_cpu(si->last_access_time));
+- new_file->td_mtime=td_ntfs2utc(sle64_to_cpu(si->last_data_change_time));
+- new_file->td_ctime=td_ntfs2utc(sle64_to_cpu(si->creation_time));
+- }
++ new_file->td_atime=td_ntfs2utc(sle64_to_cpu(si->last_access_time));
++ new_file->td_mtime=td_ntfs2utc(sle64_to_cpu(si->last_data_change_time));
++ new_file->td_ctime=td_ntfs2utc(sle64_to_cpu(si->creation_time));
+ }
+- ntfs_attr_put_search_ctx(ctx_si);
+ }
++ ntfs_attr_put_search_ctx(ctx_si);
++ }
++ {
++ ATTR_RECORD *rec;
++ int first=1;
++ ntfs_attr_search_ctx *ctx = NULL;
++ if (dt_type == NTFS_DT_DIR)
+ {
+- ATTR_RECORD *rec;
+- int first=1;
+- ntfs_attr_search_ctx *ctx = NULL;
+- if (dt_type == NTFS_DT_DIR)
++ new_file->name=strdup(filename);
++ new_file->st_mode = LINUX_S_IFDIR| LINUX_S_IRUGO | LINUX_S_IXUGO;
++ new_file->st_size=0;
++ td_list_add_tail(&new_file->list, &ls->dir_list->list);
++ first=0;
++ }
++ ctx = ntfs_attr_get_search_ctx(ni, ni->mrec);
++ /* A file has always an unnamed date stream and
++ * may have named alternate data streams (ADS) */
++ while((rec = find_attribute(AT_DATA, ctx)))
++ {
++ const s64 filesize = ntfs_get_attribute_value_length(ctx->attr);
++ if(rec->name_length &&
++ (ls->dir_data->param & FLAG_LIST_ADS)!=FLAG_LIST_ADS)
++ continue;
++ if(first==0)
+ {
+- new_file->name=strdup(filename);
+- new_file->st_mode = LINUX_S_IFDIR| LINUX_S_IRUGO | LINUX_S_IXUGO;
+- new_file->st_size=0;
+- td_list_add_tail(&new_file->list, &ls->dir_list->list);
+- first=0;
++ const file_info_t *old_file=new_file;
++ new_file=(file_info_t *)MALLOC(sizeof(*new_file));
++ memcpy(new_file, old_file, sizeof(*new_file));
+ }
+- ctx = ntfs_attr_get_search_ctx(ni, ni->mrec);
+- /* A file has always an unnamed date stream and
+- * may have named alternate data streams (ADS) */
+- while((rec = find_attribute(AT_DATA, ctx)))
++ new_file->st_mode = LINUX_S_IFREG | LINUX_S_IRUGO;
++ new_file->st_size=filesize;
++ if (rec->name_length)
+ {
+- const s64 filesize = ntfs_get_attribute_value_length(ctx->attr);
+- if(rec->name_length &&
+- (ls->dir_data->param & FLAG_LIST_ADS)!=FLAG_LIST_ADS)
+- continue;
+- if(first==0)
+- {
+- const file_info_t *old_file=new_file;
+- new_file=(file_info_t *)MALLOC(sizeof(*new_file));
+- memcpy(new_file, old_file, sizeof(*new_file));
+- }
+- new_file->st_mode = LINUX_S_IFREG | LINUX_S_IRUGO;
+- new_file->st_size=filesize;
+- if (rec->name_length)
++ char *stream_name=NULL;
++ new_file->status=FILE_STATUS_ADS;
++ new_file->name = (char *)MALLOC(MAX_PATH);
++ if (ntfs_ucstombs((ntfschar *) ((char *) rec + le16_to_cpu(rec->name_offset)),
++ rec->name_length, &stream_name, 0) < 0)
+ {
+- char *stream_name=NULL;
+- new_file->status=FILE_STATUS_ADS;
+- new_file->name = (char *)MALLOC(MAX_PATH);
+- if (ntfs_ucstombs((ntfschar *) ((char *) rec + le16_to_cpu(rec->name_offset)),
+- rec->name_length, &stream_name, 0) < 0)
+- {
+- log_error("ERROR: Cannot translate name into current locale.\n");
+- snprintf(new_file->name, MAX_PATH, "%s:???", filename);
+- }
+- else
+- {
+- snprintf(new_file->name, MAX_PATH, "%s:%s", filename, stream_name);
+- }
+- free(stream_name);
++ log_error("ERROR: Cannot translate name into current locale.\n");
++ snprintf(new_file->name, MAX_PATH, "%s:???", filename);
+ }
+ else
+ {
+- new_file->name=strdup(filename);
++ snprintf(new_file->name, MAX_PATH, "%s:%s", filename, stream_name);
+ }
+- td_list_add_tail(&new_file->list, &ls->dir_list->list);
+- first=0;
++ free(stream_name);
+ }
+- ntfs_attr_put_search_ctx(ctx);
++ else
++ {
++ new_file->name=strdup(filename);
++ }
++ td_list_add_tail(&new_file->list, &ls->dir_list->list);
++ first=0;
++ }
++ ntfs_attr_put_search_ctx(ctx);
++ if(first)
++ {
++ free(new_file);
+ }
+-
+- result = 0;
+-release:
+- /* close the inode. */
+- if (ni)
+- ntfs_inode_close(ni);
+ }
+-free:
++
++ result = 0;
++ /* close the inode. */
++ if (ni)
++ ntfs_inode_close(ni);
++freefn:
+ free (filename);
+ return result;
+ }
+--
+cgit v0.10.2
+