Avoided allocating and reading an attribute beyond its full size

Before reading a full attribute value for internal use, its expected
length has been checked to be < 0x40000. However the allocated size
in the runlist may be much bigger as a consequence of a bug or malice.
To prevent malloc'ing excessive size, restrict the size of the last
run to read to the needed length.
pull/40/head
Jean-Pierre André 2021-09-21 10:56:06 +02:00
parent 838b6e35b4
commit 60717a846d
1 changed files with 18 additions and 6 deletions

View File

@ -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;