Re: Kmap-related crashes and memory leaks on 32bit arch (5.15+)

From: Linus Torvalds
Date: Thu Nov 04 2021 - 19:48:50 EST


On Thu, Nov 4, 2021 at 4:37 PM Linus Torvalds
<torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> Having looked at it once more, it still looks "ObviouslyCorrect(tm)"
> to me, but I suspect I'm just being blind to some obvious bug.

Oh, I was just looking at the pattern of kmap/kunmap, but there does
seem to be a questionable pattern outside of that:

This pattern looks odd:

kaddr = kmap(cur_page);
write_compress_length(kaddr + offset_in_page(*cur_out),
compressed_size);
...

(and then whether you kunmap immediately, or you leave it kmap'ed and
use it again at the end is a different issue)

In particular, what if "offset_in_page(*cur_out)" is very close to the
end of the page?

That write_compress_length() always writes out a word-sized length (ie
LZO_LEN bytes), and the above pattern seems to have no model to handle
the "oh, this 4-byte write crosses a page boundary"

The other writes in that function seem to do it properly, and you have

u32 copy_len = min_t(u32, sectorsize - *cur_out % sectorsize,
orig_out + compressed_size - *cur_out);

so doing the memcpy() of size 'copy_len' should never cross a page
boundary as long as sectorsize is a power-of-2 smaller or equal to a
page size. But those 4-byte length writes seem like they could be page
crossers.

The same situation exists on the reading side, I think.

Maybe there's some reason why the read/write_compress_length() can
never cross a page boundary, but it did strike me as odd.

Linus