NTFS-3G: Update to 2022.10.3.
Bug fixes only.
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user