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) >=
|
if (total + (rl[i].length << vol->cluster_size_bits) >=
|
||||||
sle64_to_cpu(a->data_size)) {
|
sle64_to_cpu(a->data_size)) {
|
||||||
unsigned char *intbuf = NULL;
|
unsigned char *intbuf = NULL;
|
||||||
|
s64 intlth;
|
||||||
/*
|
/*
|
||||||
* We have reached the last run so we were going to
|
* We have reached the last run so we were going to
|
||||||
* overflow when executing the ntfs_pread() which is
|
* 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
|
* We have reached the end of data size so we were
|
||||||
* going to overflow in the same fashion.
|
* going to overflow in the same fashion.
|
||||||
* Temporary fix: same as above.
|
* 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) {
|
if (!intbuf) {
|
||||||
free(rl);
|
free(rl);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -246,14 +257,15 @@ s64 ntfs_get_attribute_value(const ntfs_volume *vol,
|
|||||||
* - Yes we can, in sparse files! But not necessarily
|
* - Yes we can, in sparse files! But not necessarily
|
||||||
* size of 16, just run length.
|
* size of 16, just run length.
|
||||||
*/
|
*/
|
||||||
r = ntfs_pread(vol->dev, rl[i].lcn <<
|
r = ntfs_pread(vol->dev,
|
||||||
vol->cluster_size_bits, rl[i].length <<
|
rl[i].lcn << vol->cluster_size_bits,
|
||||||
vol->cluster_size_bits, intbuf);
|
intlth << vol->cluster_size_bits,
|
||||||
if (r != rl[i].length << vol->cluster_size_bits) {
|
intbuf);
|
||||||
|
if (r != intlth << vol->cluster_size_bits) {
|
||||||
#define ESTR "Error reading attribute value"
|
#define ESTR "Error reading attribute value"
|
||||||
if (r == -1)
|
if (r == -1)
|
||||||
ntfs_log_perror(ESTR);
|
ntfs_log_perror(ESTR);
|
||||||
else if (r < rl[i].length <<
|
else if (r < intlth <<
|
||||||
vol->cluster_size_bits) {
|
vol->cluster_size_bits) {
|
||||||
ntfs_log_debug(ESTR ": Ran out of input data.\n");
|
ntfs_log_debug(ESTR ": Ran out of input data.\n");
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
@@ -414,7 +426,15 @@ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type,
|
|||||||
na = ntfs_calloc(sizeof(ntfs_attr));
|
na = ntfs_calloc(sizeof(ntfs_attr));
|
||||||
if (!na)
|
if (!na)
|
||||||
goto out;
|
goto out;
|
||||||
|
if (!name_len)
|
||||||
|
name = (ntfschar*)NULL;
|
||||||
if (name && name != AT_UNNAMED && name != NTFS_INDEX_I30) {
|
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);
|
name = ntfs_ucsndup(name, name_len);
|
||||||
if (!name)
|
if (!name)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
@@ -432,8 +452,19 @@ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type,
|
|||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
if (a->name_length) {
|
if (a->name_length) {
|
||||||
name = ntfs_ucsndup((ntfschar*)((u8*)a + le16_to_cpu(
|
ntfschar *attr_name;
|
||||||
a->name_offset)), a->name_length);
|
|
||||||
|
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)
|
if (!name)
|
||||||
goto put_err_out;
|
goto put_err_out;
|
||||||
newname = name;
|
newname = name;
|
||||||
|
|||||||
@@ -287,9 +287,19 @@ static BOOL ntfs_check_log_client_array(RESTART_PAGE_HEADER *rp)
|
|||||||
LOG_CLIENT_RECORD *ca, *cr;
|
LOG_CLIENT_RECORD *ca, *cr;
|
||||||
u16 nr_clients, idx;
|
u16 nr_clients, idx;
|
||||||
BOOL in_free_list, idx_is_first;
|
BOOL in_free_list, idx_is_first;
|
||||||
|
u32 offset_clients;
|
||||||
|
|
||||||
ntfs_log_trace("Entering.\n");
|
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));
|
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 +
|
ca = (LOG_CLIENT_RECORD*)((u8*)ra +
|
||||||
le16_to_cpu(ra->client_array_offset));
|
le16_to_cpu(ra->client_array_offset));
|
||||||
/*
|
/*
|
||||||
@@ -308,6 +318,10 @@ check_list:
|
|||||||
idx = le16_to_cpu(cr->next_client)) {
|
idx = le16_to_cpu(cr->next_client)) {
|
||||||
if (!nr_clients || idx >= le16_to_cpu(ra->log_clients))
|
if (!nr_clients || idx >= le16_to_cpu(ra->log_clients))
|
||||||
goto err_out;
|
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. */
|
/* Set @cr to the current log client record. */
|
||||||
cr = ca + idx;
|
cr = ca + idx;
|
||||||
/* The first log client record must not have a prev_client. */
|
/* 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
|
* Allocate a buffer to store the whole restart page so we can multi
|
||||||
* sector transfer deprotect it.
|
* 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));
|
trp = ntfs_malloc(le32_to_cpu(rp->system_page_size));
|
||||||
if (!trp)
|
if (!trp)
|
||||||
return errno;
|
return errno;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* Copyright (c) 2004-2005 Richard Russon
|
* Copyright (c) 2004-2005 Richard Russon
|
||||||
* Copyright (c) 2004-2008 Szabolcs Szakacsits
|
* Copyright (c) 2004-2008 Szabolcs Szakacsits
|
||||||
* Copyright (c) 2005 Yura Pakhuchiy
|
* 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
|
* 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
|
* modify it under the terms of the GNU General Public License as published
|
||||||
@@ -1529,8 +1529,17 @@ found_free_rec:
|
|||||||
goto undo_mftbmp_alloc;
|
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;
|
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)) {
|
if (ntfs_mft_record_layout(vol, bit, m)) {
|
||||||
ntfs_log_error("Failed to re-format mft record.\n");
|
ntfs_log_error("Failed to re-format mft record.\n");
|
||||||
free(m);
|
free(m);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* Copyright (c) 2002-2005 Richard Russon
|
* Copyright (c) 2002-2005 Richard Russon
|
||||||
* Copyright (c) 2002-2008 Szabolcs Szakacsits
|
* Copyright (c) 2002-2008 Szabolcs Szakacsits
|
||||||
* Copyright (c) 2004 Yura Pakhuchiy
|
* 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
|
* 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
|
* modify it under the terms of the GNU General Public License as published
|
||||||
@@ -918,10 +918,17 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
|
|||||||
"array.\n");
|
"array.\n");
|
||||||
goto err_out;
|
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. */
|
/* Enter the current lcn into the runlist element. */
|
||||||
rl[rlpos].lcn = lcn;
|
rl[rlpos].lcn = lcn;
|
||||||
}
|
}
|
||||||
/* Get to the next runlist element. */
|
/* Get to the next runlist element, skipping zero-sized holes */
|
||||||
|
if (rl[rlpos].length)
|
||||||
rlpos++;
|
rlpos++;
|
||||||
/* Increment the buffer position to the next mapping pair. */
|
/* Increment the buffer position to the next mapping pair. */
|
||||||
buf += (*buf & 0xf) + ((*buf >> 4) & 0xf) + 1;
|
buf += (*buf & 0xf) + ((*buf >> 4) & 0xf) + 1;
|
||||||
@@ -987,13 +994,18 @@ mpa_err:
|
|||||||
rl[rlpos].vcn = vcn;
|
rl[rlpos].vcn = vcn;
|
||||||
rl[rlpos].length = (s64)0;
|
rl[rlpos].length = (s64)0;
|
||||||
/* If no existing runlist was specified, we are done. */
|
/* 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_log_debug("Mapping pairs array successfully decompressed:\n");
|
||||||
ntfs_debug_runlist_dump(rl);
|
ntfs_debug_runlist_dump(rl);
|
||||||
|
if (old_rl)
|
||||||
|
free(old_rl);
|
||||||
return rl;
|
return rl;
|
||||||
}
|
}
|
||||||
/* Now combine the new and old runlists checking for overlaps. */
|
/* Now combine the new and old runlists checking for overlaps. */
|
||||||
|
if (rl[0].length)
|
||||||
old_rl = ntfs_runlists_merge(old_rl, rl);
|
old_rl = ntfs_runlists_merge(old_rl, rl);
|
||||||
|
else
|
||||||
|
free(rl);
|
||||||
if (old_rl)
|
if (old_rl)
|
||||||
return old_rl;
|
return old_rl;
|
||||||
err = errno;
|
err = errno;
|
||||||
|
|||||||
@@ -77,7 +77,7 @@
|
|||||||
#include "security.h"
|
#include "security.h"
|
||||||
|
|
||||||
const char *ntfs_home =
|
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 =
|
static const char *invalid_ntfs_msg =
|
||||||
"The device '%s' doesn't seem to have a valid NTFS.\n"
|
"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 =
|
static const char *access_denied_msg =
|
||||||
"Please check '%s' and the ntfs-3g binary permissions,\n"
|
"Please check '%s' and the ntfs-3g binary permissions,\n"
|
||||||
"and the mounting user ID. More explanation is provided at\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
|
* ntfs_volume_alloc - Create an NTFS volume object and initialise it
|
||||||
|
|||||||
Reference in New Issue
Block a user