lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<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

Powered by Openwall GNU/*/Linux Powered by OpenVZ