[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAHk-=whGUxtcL8Z67y4A6_diSmtQdnOq1p_gyBAMzpKD9yk+gw@mail.gmail.com>
Date: Thu, 4 Nov 2021 16:48:19 -0700
From: Linus Torvalds <torvalds@...ux-foundation.org>
To: David Sterba <dsterba@...e.cz>, Qu Wenruo <wqu@...e.com>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
Linux-MM <linux-mm@...ck.org>
Subject: Re: Kmap-related crashes and memory leaks on 32bit arch (5.15+)
On Thu, Nov 4, 2021 at 4:37 PM Linus Torvalds
<torvalds@...ux-foundation.org> 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
Powered by blists - more mailing lists