unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Maxime Devos <maximedevos@telenet.be>
Cc: "Andy Wingo" <wingo@pobox.com>, "Ludovic Courtès" <ludo@gnu.org>,
	guile-devel@gnu.org, "Leo Famulari" <leo@famulari.name>
Subject: Re: [PATCH] Bindings to *at  functions & allowing more functions to operate on ports
Date: Sat, 27 Mar 2021 22:19:20 +0100	[thread overview]
Message-ID: <b7e4f08b295400de79173bd61011eab0b4d42262.camel@telenet.be> (raw)
In-Reply-To: <175c3a6572e832d84927937b309a3095cadf5702.camel@telenet.be>

[-- Attachment #1: Type: text/plain, Size: 2513 bytes --]

Hi,

[CC'ing some Guile and Guix maintainers because this is
important for the security of Guix System.]

I want to explain why these patches (and the O_FLAGS (*)
patch) should be included in Guile.  Functions like "openat"
are important to avoid TOCTTOU (time-of-check to time-of-use)
vulnerabilities involving symbolic links.

For example, suppose we have a web server implemented in
Guile.  Suppose the address is https://web.gnu.  It allows
a local user U (and some others) to define their own web
pages to host at http://web.gnu/~U, by writing files to
/home/U/www.  As there are multiple users, the server has
to run as root.

Now suppose U is the malicious kind of user.  Then $U
could create a symlink at /home/U/www/maliciousity pointing
to /home/other-user/.gnupg/private-keys-v1.d/FINGERPRINT.key.

Now U could download other-user's gpg key, for example
with "wget http://web.gnu/~U/maliciousity".  Oops!

How can this vulnerability be avoided?

* Use O_NOFOLLOW to *not* follow the symbolic link.
  Patch for adding O_NOFOLLOW to guile:
  <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=46220>.

And why do we need openat?  Well, suppose the web server
is not read-only, and supports (say) WebDAV or FTP for
modifying files remotely (I mean U can remotely modify
http://web.gnu/~U).  Then U could create a symlink
at /home/U/www/maliciousity pointing to /home/other-user.
Now U can peek into other-user's home directory and overwrite
files.  Oops!

How can the web server avoid this?

* First open "/home/U" as usual, resulting in a port $1.
  Then use (openat $1 "maliciousity" O_NOFOLLOW), resulting
  in a port $2.  Use (stat $2) to see if $2 is a directory
  or a regular file **and** to see if $2 is owned by $2!
  If necessary, recurse, etc.  Display a directory listing
  or display the file, etc.

How does this matter for Guix?

Guix has a TOCTTOU race:
<https://lists.gnu.org/archive/html/guix-devel/2021-01/msg00388.html>.
It has been partially fixed:
<https://git.savannah.gnu.org/cgit/guix.git/commit/?id=520bac7ed00a949a0391ad680de65a1498105c2b>.
However, a complete fix requires bindings to "openat".

I found another similar issue in Guix lately (not yet disclosed publicly).
While I think the conditions for this other potential security issue
to be exploitable don't ever happen in practice, I would still like
to fix this issue, and to be able to prevent similar issues from appearing
in the future.

Greetings,
Maxime.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 260 bytes --]

  reply	other threads:[~2021-03-27 21:19 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-12 21:59 [PATCH] Bindings to *at functions & allowing more functions to operate on ports Maxime Devos
2021-03-27 21:19 ` Maxime Devos [this message]
2021-03-28 11:17   ` tomas
2021-05-04 22:58     ` rob piko
2021-05-05 10:11       ` Maxime Devos
2021-11-16 11:06 ` [PATCH v2 00/14] Bindings to *at functions Maxime Devos
2021-11-16 11:06   ` [PATCH v2 01/14] Allow file ports in ‘chdir’ when supported Maxime Devos
2021-11-16 12:18     ` Maxime Devos
2021-11-16 17:10       ` Maxime Devos
2021-11-16 11:06   ` [PATCH v2 02/14] Allow file ports in ‘readlink’ Maxime Devos
2021-11-16 11:06   ` [PATCH v2 03/14] Allow file ports in ‘utime’ Maxime Devos
2021-11-16 11:06   ` [PATCH v2 04/14] Define ‘symlinkat’ wrapper when supported Maxime Devos
2021-11-16 11:06   ` [PATCH v2 05/14] Define bindings to ‘mkdirat’ when the C function exists Maxime Devos
2021-11-16 11:06   ` [PATCH v2 06/14] Correct documentation of ‘mkdir’ w.r.t. the umask Maxime Devos
2021-11-16 11:06   ` [PATCH v2 07/14] Define AT_REMOVEDIR and others when available Maxime Devos
2021-11-16 11:06   ` [PATCH v2 08/14] Define a Scheme binding to ‘renameat’ when it exists Maxime Devos
2021-11-16 11:06   ` [PATCH v2 09/14] Define a Scheme binding to ‘fchmodat’ " Maxime Devos
2021-11-16 11:06   ` [PATCH v2 10/14] Define a Scheme binding to ‘unlinkat’ " Maxime Devos
2021-11-16 11:06   ` [PATCH v2 11/14] Define a Scheme binding to ‘fchownat’ " Maxime Devos
2021-11-16 11:06   ` [PATCH v2 12/14] Define a Scheme binding to ‘fstatat’ when available Maxime Devos
2021-11-16 11:06   ` [PATCH v2 13/14] Define Scheme bindings to ‘openat’ " Maxime Devos
2021-11-16 11:06   ` [PATCH v2 14/14] Update NEWS Maxime Devos
2021-11-16 12:16     ` Maxime Devos
2022-06-16  8:42   ` [PATCH v2 00/14] Bindings to *at functions Ludovic Courtès
2022-10-21 15:59     ` Ludovic Courtès
2022-10-21 16:03       ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b7e4f08b295400de79173bd61011eab0b4d42262.camel@telenet.be \
    --to=maximedevos@telenet.be \
    --cc=guile-devel@gnu.org \
    --cc=leo@famulari.name \
    --cc=ludo@gnu.org \
    --cc=wingo@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).