Re: [PATCH] ovl: fortify ovl_copy_xattr() against underlying layer modifications

Fahad Alharbi <[email protected]>
Newsgroups org.kernel.vger.linux-unionfs,org.kernel.vger.linux-fsdevel
Message-ID <[email protected]>
TL;DR: your patch fixes it.  On v7.2-rc6, FUSE probe LEAK -> NO LEAK, and the
unprivileged tmpfs racer goes from 78 of 5,000,000 copy-ups leaking (5 of 5
boots) to 0 of 5,000,000 (0 of 5 boots).  51 of 51 functional xattr checks
unchanged.  One behaviour change worth a look: under a racing lower fs about
6% of copy-ups now fail with EIO.  Tested-by below.

Your three earlier points are taken; hence the shape of this mail.

Setup: v7.2-rc6 (075b74841bd0), your patch applied clean, both kernels built
from a byte-identical config so the patch is the only variable.  I checked it
reached the binary rather than trusting the build: ovl_copy_xattr shrinks from
0x504 to 0x443 bytes as the grow loop moves into the helper.

Results
-------

  test                              base            patched
  FUSE probe (hostile lower)        LEAK            NO LEAK
  unprivileged tmpfs racer          5/5 boots       0/5 boots
                                    78 of 5e6       0 of 5e6
  functional, 51 xattr checks       51 of 51        51 of 51
  termination probe                 0.100 s         0.101 s, EIO

Before, the upper file receives 6b6b..6ba5; after, the real value.

The EIO path works as designed: against a lower fs that shrinks the xattr
between the two getxattr calls, the copy-up now returns -EIO in 0.101 s
instead of copying out the unfilled buffer.

The behaviour change
--------------------

Under the racer, on 1,000,000 copy-ups per boot:

  base      ok=1000000  other=0
  patched   ok=939548   other=60452  (errno 5)

So ~6% of copy-ups now fail rather than silently copying wrong bytes.  I read
overlayfs.rst as saying that is exactly right -- modifying a lower layer of a
mounted overlay is undefined behaviour, and EIO is the defined detection --
but it is a real, unprivileged-triggerable failure rate for anything doing
copy-up over a changing lower fs, so I would rather you saw the number.

EAGAIN=0 on every patched boot.  Copy-up latency max 44-48 ms, nothing over
100 ms.  No BUG, WARNING, stall or oops attributable to the patch; the one
"Attempted to kill init!" trace in some logs is my harness shutting down and
appears on both kernels.

Two limits: these builds are CONFIG_SLUB_DEBUG_ON=y, so the leaked bytes are
poison -- proof the memory was never written, but no kernel pointers in this
run; those came from a separate non-debug build.  And the racer is a
size-flapping tmpfs lower, not a general workload.

Tested-by: Fahad Alharbi <[email protected]>

Reproducers and full logs on request.

Fahad
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.