Yes, it would. Unless there is some case where dd is available but cat
is, dd works.

Thanks for your help,
Ethan

On Tue, Mar 25, 2025 at 1:11 PM Pádraig Brady <p...@draigbrady.com> wrote:
>
> On 25/03/2025 14:19, Ethan Heilman wrote:
> > Howdy coreutils,
> >
> > I would like to add a O_NOFOLLOW flag to cat so that users can specify
> > if cat should follow a symlink at the final file in a path. This is
> > motivated by the need to atomically read a file while ensuring it is
> > not a symlink. This functionality is absent from coreutils, as far as
> > I am aware.
> >
> > I’d be grateful for any feedback, criticism, ideas on this proposed
> > change. Is this something coreutils would be interested in merging if
> > I wrote code + tests.
> >
> > Rationale
> > ====
> >
> > Without this functionality in cat, users are likely to do the next
> > easiest option which is to use two separate commands to first check if
> > the file is a symlink and then read the file. This can be a source of
> > bugs and harm security because using two commands introduces a TOCTOU
> > (Time-of-Check to Time-of-Use) issue. This is because it is always
> > possible after the symlink check has occurred, but before cat is run
> > the file is replaced with symlink. Such race condition bugs are
> > especially dangerous because the harmful behavior is triggered only in
> > rare circumstances, allowing them to enter production and be hard to
> > debug.
> >
> > When might one encounter this:
> >
> > 1. Having privileged services or sudoer commands where a symlink be
> > might be maliciously or accidentally substituted as the final file in
> > the path (often called the confused deputy problem[0]).
> >
> > `serviceuser ALL=(ALL) NOPASSWD: cat /home/[0-9a-z_-]/file123`
> >
> > 2. Different scripts or users reading and writing to a shared
> > directory. This need not be a security issue. If files are being
> > created and destroyed frequently, a user may just wish to ensure they
> > don’t accidentally read from a symlink when they don’t expect the file
> > to be a symlink. For instance ensuring that a read does not leave the
> > current directory.
> >
> > This is not a problem for directories because one can check if a
> > directory is a symlink safely with any later action because you can
> > compare the expected file path after traversing into that directory
> > but before taking the action. This is safe because someone can’t
> > change the directory you are already in into a symlink after you have
> > transverse it. Thus, this change would strictly maintain the behavior
> > of the O_NOFOLLOW flag in following directory symlinks prior to the
> > last part of a path.
> >
> > While this can be solved by creating a binary or using python, I
> > believe enabling reads to be atomic with symlink checks is an
> > important building block that should be available at the level of
> > coreutils. Allowing cat to support O_NOFOLLOW via a flag would be a
> > simple way to add this functionality.
> >
> > Thanks for taking the time to read this,
> > Ethan
> >
> > [0]: https://en.wikipedia.org/wiki/Confused_deputy_problem
>
>
> Would dd suffice for such fine grained control?
>
>    $ dd iflag=nofollow if=symlink
>    dd: failed to open 'symlink': Too many levels of symbolic links
>
> cheers,
> Pádraig

Reply via email to