memory leak on ntfs volume

Using TestDisk to undelete files
Forum rules
When asking for technical support:
- Search for posts on the same topic before posting a new question.
- Give clear, specific information in the title of your post.
- Include as many details as you can, MOST POSTS WILL GET ONLY ONE OR TWO ANSWERS.
- Post a follow up with a "Thank you" or "This worked!"
- When you learn something, use that knowledge to HELP ANOTHER USER LATER.
Before posting, please read https://www.cgsecurity.org/testdisk.pdf
Locked
Message
Author
mesajflaviu
Posts: 37
Joined: 12 Sep 2019, 19:54

memory leak on ntfs volume

#1 Post by mesajflaviu »

I ran the code in the debugger, tested on NTFS device, by calling ntfs_undelete_part function. In the step by step debugging, I arrived on volume.c file, at line:

Code: Select all

br = ntfs_pread(dev, 0, sizeof(NTFS_BOOT_SECTOR), bs);
if I call this function, I got the following memory leak:

Code: Select all

Dumping objects ->
{26571} normal block at 0x034B8020, 65536 bytes long.
 Data: < R NTFS         > EB 52 90 4E 54 46 53 20 20 20 20 00 02 08 00 00 
Object dump complete.
I don't know from where come this memory leak, but the garbage value is a little bit interesting: EB 52 90 4E 54 46 53 20 20 20 20 00 02 08 00 00 ... what can I know this ML source for sure ?

Update:
The code is run like this:

Code: Select all

1. volume.c / br = ntfs_pread(dev, 0, sizeof(NTFS_BOOT_SECTOR), bs);
2. device.c / br = dops->pread(dev, (char*)b + total, count, pos + total);
3. ntfs_io.c / 
static s64 ntfs_device_testdisk_io_pread(struct ntfs_device* dev, void *buf, s64 count, s64 offset)
{
	my_data_t* my_data = (my_data_t*)dev->d_private;
	return my_data->disk_car->pread(my_data->disk_car, buf, (int)count, my_data->partition->part_offset + offset);
}

4. hdaccess.c / 
static int file_pread(disk_t* disk_car, void *buf, const unsigned int count, const uint64_t offset)
{
	return align_pread(&file_pread_aux, disk_car, buf, count, offset);
}

5. align.c / 
static int align_pread(int(*fnct_pread)(disk_t *disk_car, void *buf, const unsigned int count, const uint64_t offset),
	disk_t* disk_car, void*buf, const unsigned int count, const uint64_t offset)
{
	const uint64_t offset_new = offset + disk_car->offset;
	const unsigned int count_new = ((offset_new%disk_car->sector_size) + count + disk_car->sector_size - 1) / disk_car->sector_size*disk_car->sector_size;
	if (count != count_new ||
		((disk_car->access_mode & TESTDISK_O_DIRECT) != 0 && 
		(((size_t)(buf) & (disk_car->sector_size - 1)) != 0) && 
			(buf != disk_car->rbuffer || disk_car->rbuffer_size < count_new))
		)
	{
		if (disk_car->rbuffer == NULL)
			disk_car->rbuffer_size = 128 * 512;
		while (disk_car->rbuffer_size < count_new)
		{
			free(disk_car->rbuffer);
			disk_car->rbuffer = NULL;
			disk_car->rbuffer_size *= 2;
		}
		if (disk_car->rbuffer == NULL)
			disk_car->rbuffer = MALLOC(disk_car->rbuffer_size);
		TRACE(" bad case: %p|%p %d|%d\n", disk_car, disk_car->rbuffer, count_new, offset_new / disk_car->sector_size*disk_car->sector_size);
		int res = fnct_pread(disk_car, disk_car->rbuffer, count_new, offset_new / disk_car->sector_size*disk_car->sector_size);
		memcpy(buf, (char*)disk_car->rbuffer + (offset_new%disk_car->sector_size), count);
		return (res < (signed)count ? res : (signed)count);
	}
	TRACE("good case: %p|%p %d|%d\n", disk_car, buf, count, offset_new);
	return fnct_pread(disk_car, buf, count, offset_new);
}

User avatar
cgrenier
Site Admin
Posts: 5432
Joined: 18 Feb 2012, 15:08
Location: Le Perreux Sur Marne, France
Contact:

Re: memory leak on ntfs volume

#2 Post by cgrenier »

disk_car->rbuffer is allocated by align_pread()
generic_clean() in hdaccess.c calls "free(disk_car->rbuffer);"

mesajflaviu
Posts: 37
Joined: 12 Sep 2019, 19:54

Re: memory leak on ntfs volume

#3 Post by mesajflaviu »

Thank you Grenier !!! To see how important is your words, I can say: I found/solved memory leaks. At least, I guess so. Might be a little bug, I am not sure, you can check yourself. Here was the problem:
In alignio.h (sorry, not alignio.c), in function align_pread

Code: Select all

static int align_pread(int(*fnct_pread)(disk_t *disk_car, void *buf, const unsigned int count, const uint64_t offset),
	disk_t* disk_car, void*buf, const unsigned int count, const uint64_t offset)
{
	const uint64_t offset_new = offset + disk_car->offset;
	const unsigned int count_new = ((offset_new%disk_car->sector_size) + count + disk_car->sector_size - 1) / disk_car->sector_size*disk_car->sector_size;
	if (count != count_new ||
		((disk_car->access_mode & TESTDISK_O_DIRECT) != 0 && 
		(((size_t)(buf) & (disk_car->sector_size - 1)) != 0) && 
			(buf != disk_car->rbuffer || disk_car->rbuffer_size < count_new))
		)
	{
		if (disk_car->rbuffer == NULL)
			disk_car->rbuffer_size = 128 * 512;
		while (disk_car->rbuffer_size < count_new)
		{
			free(disk_car->rbuffer);
			disk_car->rbuffer = NULL;
			disk_car->rbuffer_size *= 2;
		}
		if (disk_car->rbuffer == NULL)
			disk_car->rbuffer = MALLOC(disk_car->rbuffer_size);
		int res = fnct_pread(disk_car, disk_car->rbuffer, count_new, offset_new / disk_car->sector_size * disk_car->sector_size);
		memcpy(buf, (char*)disk_car->rbuffer + (offset_new % disk_car->sector_size), count);
		free(disk_car->rbuffer);   // this is the my code !!! I hope to be ok
		return (res < (signed)count ? res : (signed)count);
	}
	return fnct_pread(disk_car, buf, count, offset_new);
}
still, the code doesn't found any deleted files from USB NTFS drives. this could be another issue. Again, kindly thank you Grenier !!!!

Locked