Re: [PATCH] landlock: Document fallocate(2) as another truncation corner case

Günther Noack
2026-04-01T17:13:43Z

On Wed, Apr 01, 2026 at 06:30:28PM +0200, Mickaël Salaün wrote:
> On Wed, Apr 01, 2026 at 05:09:10PM +0200, Günther Noack wrote:
> > Reinforce the already stated policy that LANDLOCK_ACCESS_FS_TRUNCATE should
> > always go hand in hand with LANDLOCK_ACCESS_FS_WRITE_FILE, as their
> > meanings and enforcement overlap in counterintuitive ways.
> >
> > On many common file systems, fallocate(2) offers a way to shorten files as
> > long as the file is opened for writing, side-stepping the
> > LANDLOCK_ACCESS_FS_TRUNCATE right.
> >
> > Assisted-by: Gemini-CLI:gemini-3.1
> > Signed-off-by: Günther Noack <gnoack@google.com>
> > ---
> > Documentation/userspace-api/landlock.rst | 8 ++++++--
> > 1 file changed, 6 insertions(+), 2 deletions(-)
> >
> > diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst
> > index 7f86d7a37dc2..d5691ec136cc 100644
> > --- a/Documentation/userspace-api/landlock.rst
> > +++ b/Documentation/userspace-api/landlock.rst
> > @@ -378,8 +378,8 @@ Truncating files
> >
> > The operations covered by ``LANDLOCK_ACCESS_FS_WRITE_FILE`` and
> > ``LANDLOCK_ACCESS_FS_TRUNCATE`` both change the contents of a file and sometimes
> > -overlap in non-intuitive ways. It is recommended to always specify both of
> > -these together.
> > +overlap in non-intuitive ways. It is strongly recommended to always specify
> > +both of these together (either granting both, or granting none).
> >
> > A particularly surprising example is :manpage:`creat(2)`. The name suggests
> > that this system call requires the rights to create and write files. However,
> > @@ -391,6 +391,10 @@ It should also be noted that truncating files does not require the
> > system call, this can also be done through :manpage:`open(2)` with the flags
> > ``O_RDONLY | O_TRUNC``.
> >
> > +At the same time, on some filesystems, :manpage:`fallocate(2)` offers a way to
> > +shorten file contents with ``FALLOC_FL_COLLAPSE_RANGE`` when the file is opened
> > +for writing, sidestepping the ``LANDLOCK_ACCESS_FS_TRUNCATE`` right.
>
> Interesting, which filesystems? Shouldn't it be fixed in the code
> instead?

It works on ext4, and I also see mentions of FALLOC_FL_COLLAPSE_RANGE
in XFS, F2FS, SMB and NTFS3.

I should mention, it is not *exactly* the same as a truncation, but
you can remove a chunk of the file from the middle, which also leads
to a shorter file. For example, assuming a block size of 1024:

1. Make a file with 2*1024 bytes: 1024*'A', then 1024*'B'
2. fallocate(collapse range, 0, 1024)

Resulting file is 1024*'B', and the file is shortened to 1024 bytes.

So this is not *exactly* a truncation. (The man page says that an
attempt to remove the end of a file results in EINVAL, so you have to
take it from the middle, and it needs to align with block boundaries.)

But it's quite similar, also shortens the file, and it does not
require the Landlock truncation access right.

I agree, another way would potentially be to call the LSM ftruncate
hook. I suspect this would stay compatible with other LSMs, because
the LSM ftruncate hook is a relatively recent addition (but have not
checked in detail).

The implementation of fallocate is vfs_fallocate() in fs/open.c - I
only had a tentative look now; it checks that the file->f_mode is open
for writing and calls security_file_permission() with MAY_WRITE.

I always saw LANDLOCK_ACCESS_FS_WRITE_FILE and
LANDLOCK_ACCESS_FS_TRUNCATE as rights that should always go together,
so I suspect that it does not make a big difference in practice, and
that is why I am suggesting to just document it more clearly for now.

—Günther