NTFS-3G: Update to 2022.10.3.

Bug fixes only.
This commit is contained in:
Augustin Cavalier
2023-03-27 21:56:10 -04:00
parent 95de7f50ea
commit 4cb9408437
5 changed files with 90 additions and 17 deletions
@@ -216,6 +216,7 @@ s64 ntfs_get_attribute_value(const ntfs_volume *vol,
if (total + (rl[i].length << vol->cluster_size_bits) >=
sle64_to_cpu(a->data_size)) {
unsigned char *intbuf = NULL;
s64 intlth;
/*
* We have reached the last run so we were going to
* overflow when executing the ntfs_pread() which is
@@ -229,8 +230,18 @@ s64 ntfs_get_attribute_value(const ntfs_volume *vol,
* We have reached the end of data size so we were
* going to overflow in the same fashion.
* Temporary fix: same as above.
*
* For safety, limit the amount to read to the
* needed size, knowing that the whole attribute
* size has been checked to be <= 0x40000.
*/
intbuf = ntfs_malloc(rl[i].length << vol->cluster_size_bits);
intlth = (sle64_to_cpu(a->data_size) - total
+ vol->cluster_size - 1)
>> vol->cluster_size_bits;
if (rl[i].length < intlth)
intlth = rl[i].length;
intbuf = (u8*)ntfs_malloc(intlth
<< vol->cluster_size_bits);
if (!intbuf) {
free(rl);
return 0;
@@ -246,14 +257,15 @@ s64 ntfs_get_attribute_value(const ntfs_volume *vol,
* - Yes we can, in sparse files! But not necessarily
* size of 16, just run length.
*/
r = ntfs_pread(vol->dev, rl[i].lcn <<
vol->cluster_size_bits, rl[i].length <<
vol->cluster_size_bits, intbuf);
if (r != rl[i].length << vol->cluster_size_bits) {
r = ntfs_pread(vol->dev,
rl[i].lcn << vol->cluster_size_bits,
intlth << vol->cluster_size_bits,
intbuf);
if (r != intlth << vol->cluster_size_bits) {
#define ESTR "Error reading attribute value"
if (r == -1)
ntfs_log_perror(ESTR);
else if (r < rl[i].length <<
else if (r < intlth <<
vol->cluster_size_bits) {
ntfs_log_debug(ESTR ": Ran out of input data.\n");
errno = EIO;
@@ -414,7 +426,15 @@ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type,
na = ntfs_calloc(sizeof(ntfs_attr));
if (!na)
goto out;
if (!name_len)
name = (ntfschar*)NULL;
if (name && name != AT_UNNAMED && name != NTFS_INDEX_I30) {
/* A null char leads to a short name and unallocated bytes */
if (ntfs_ucsnlen(name, name_len) != name_len) {
ntfs_log_error("Null character in attribute name"
" of inode %lld\n",(long long)ni->mft_no);
goto err_out;
}
name = ntfs_ucsndup(name, name_len);
if (!name)
goto err_out;
@@ -432,8 +452,19 @@ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type,
if (!name) {
if (a->name_length) {
name = ntfs_ucsndup((ntfschar*)((u8*)a + le16_to_cpu(
a->name_offset)), a->name_length);
ntfschar *attr_name;
attr_name = (ntfschar*)((u8*)a
+ le16_to_cpu(a->name_offset));
/* A null character leads to illegal memory access */
if (ntfs_ucsnlen(attr_name, a->name_length)
!= a->name_length) {
ntfs_log_error("Null character in attribute"
" name in inode %lld\n",
(long long)ni->mft_no);
goto put_err_out;
}
name = ntfs_ucsndup(attr_name, a->name_length);
if (!name)
goto put_err_out;
newname = name;
@@ -287,9 +287,19 @@ static BOOL ntfs_check_log_client_array(RESTART_PAGE_HEADER *rp)
LOG_CLIENT_RECORD *ca, *cr;
u16 nr_clients, idx;
BOOL in_free_list, idx_is_first;
u32 offset_clients;
ntfs_log_trace("Entering.\n");
/* The restart area must be fully within page */
if ((le16_to_cpu(rp->restart_area_offset) + sizeof(RESTART_AREA))
> le32_to_cpu(rp->system_page_size))
goto err_out;
ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
offset_clients = le16_to_cpu(rp->restart_area_offset)
+ le16_to_cpu(ra->client_array_offset);
/* The clients' records must begin within page */
if (offset_clients >= le32_to_cpu(rp->system_page_size))
goto err_out;
ca = (LOG_CLIENT_RECORD*)((u8*)ra +
le16_to_cpu(ra->client_array_offset));
/*
@@ -308,6 +318,10 @@ check_list:
idx = le16_to_cpu(cr->next_client)) {
if (!nr_clients || idx >= le16_to_cpu(ra->log_clients))
goto err_out;
/* The client record must be fully within page */
if ((offset_clients + (idx + 1)*sizeof(LOG_CLIENT_RECORD))
> le32_to_cpu(rp->system_page_size))
goto err_out;
/* Set @cr to the current log client record. */
cr = ca + idx;
/* The first log client record must not have a prev_client. */
@@ -380,7 +394,14 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
/*
* Allocate a buffer to store the whole restart page so we can multi
* sector transfer deprotect it.
* For safety, make sure this is consistent with the usa_count
* and shorter than the full log size
*/
if ((le32_to_cpu(rp->system_page_size)
> (u32)(le16_to_cpu(rp->usa_count) - 1)*NTFS_BLOCK_SIZE)
|| (le32_to_cpu(rp->system_page_size)
> le64_to_cpu(log_na->data_size)))
return (EINVAL);
trp = ntfs_malloc(le32_to_cpu(rp->system_page_size));
if (!trp)
return errno;
@@ -5,7 +5,7 @@
* Copyright (c) 2004-2005 Richard Russon
* Copyright (c) 2004-2008 Szabolcs Szakacsits
* Copyright (c) 2005 Yura Pakhuchiy
* Copyright (c) 2014-2018 Jean-Pierre Andre
* Copyright (c) 2014-2021 Jean-Pierre Andre
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@@ -1529,8 +1529,17 @@ found_free_rec:
goto undo_mftbmp_alloc;
}
/*
* Retrieve the former seq_no and usn so that the new record
* cannot be mistaken for the former one.
* However the original record may just be garbage, so
* use some sensible value when they cannot be retrieved.
*/
seq_no = m->sequence_number;
usn = *(le16*)((u8*)m + le16_to_cpu(m->usa_ofs));
if (le16_to_cpu(m->usa_ofs) <= (NTFS_BLOCK_SIZE - 2))
usn = *(le16*)((u8*)m + (le16_to_cpu(m->usa_ofs) & -2));
else
usn = const_cpu_to_le16(1);
if (ntfs_mft_record_layout(vol, bit, m)) {
ntfs_log_error("Failed to re-format mft record.\n");
free(m);
@@ -5,7 +5,7 @@
* Copyright (c) 2002-2005 Richard Russon
* Copyright (c) 2002-2008 Szabolcs Szakacsits
* Copyright (c) 2004 Yura Pakhuchiy
* Copyright (c) 2007-2010 Jean-Pierre Andre
* Copyright (c) 2007-2022 Jean-Pierre Andre
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@@ -918,11 +918,18 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
"array.\n");
goto err_out;
}
/* chkdsk accepts zero-sized runs only for holes */
if ((lcn != (LCN)-1) && !rl[rlpos].length) {
ntfs_log_debug(
"Invalid zero-sized data run.\n");
goto err_out;
}
/* Enter the current lcn into the runlist element. */
rl[rlpos].lcn = lcn;
}
/* Get to the next runlist element. */
rlpos++;
/* Get to the next runlist element, skipping zero-sized holes */
if (rl[rlpos].length)
rlpos++;
/* Increment the buffer position to the next mapping pair. */
buf += (*buf & 0xf) + ((*buf >> 4) & 0xf) + 1;
}
@@ -987,13 +994,18 @@ mpa_err:
rl[rlpos].vcn = vcn;
rl[rlpos].length = (s64)0;
/* If no existing runlist was specified, we are done. */
if (!old_rl) {
if (!old_rl || !old_rl[0].length) {
ntfs_log_debug("Mapping pairs array successfully decompressed:\n");
ntfs_debug_runlist_dump(rl);
if (old_rl)
free(old_rl);
return rl;
}
/* Now combine the new and old runlists checking for overlaps. */
old_rl = ntfs_runlists_merge(old_rl, rl);
if (rl[0].length)
old_rl = ntfs_runlists_merge(old_rl, rl);
else
free(rl);
if (old_rl)
return old_rl;
err = errno;
@@ -77,7 +77,7 @@
#include "security.h"
const char *ntfs_home =
"News, support and information: http://tuxera.com\n";
"News, support and information: https://github.com/tuxera/ntfs-3g/\n";
static const char *invalid_ntfs_msg =
"The device '%s' doesn't seem to have a valid NTFS.\n"
@@ -121,7 +121,7 @@ static const char *fakeraid_msg =
static const char *access_denied_msg =
"Please check '%s' and the ntfs-3g binary permissions,\n"
"and the mounting user ID. More explanation is provided at\n"
"http://tuxera.com/community/ntfs-3g-faq/#unprivileged\n";
"https://github.com/tuxera/ntfs-3g/wiki/NTFS-3G-FAQ\n";
/**
* ntfs_volume_alloc - Create an NTFS volume object and initialise it