s6

Mirror/fork of https://skarnet.org/software/s6/
git clone https://ccx.te2000.cz/git/s6
Log | Files | Refs | README | LICENSE

commit 0257ca0c6ce27cc8d48323f5fc4f079c7f455b93
parent f05b37667624eb178a0d856da339d003f7d63b6e
Author: Laurent Bercot <ska-skaware@skarnet.org>
Date:   Thu, 29 Jan 2015 11:49:26 +0000

 I changed my mind. Added access control for listing to s6-fdholderd.

Diffstat:
Mdoc/s6-fdholderd.html | 17++++++++++++-----
Msrc/fdholder/s6-fdholderd.c | 6++++--
2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/doc/s6-fdholderd.html b/doc/s6-fdholderd.html @@ -186,8 +186,11 @@ rulesdir as an example, but a rulesfile works the same way): <ul> <li> Connect to the server. This is a prerequisite for doing anything. It will allow a client to perform "public" operations, -ones that do not require specific access rights other than connecting: -for instance, listing all identifiers. This right is given if an +ones that do not require specific access rights other than connecting. +(There are no such operations for now, but it could change in the +future; for now, when you allow a client to connect to the server, +make sure to give him other rights too.) + This right is given if an <tt>allow</tt> file is found in one of the subdirectories checked by <a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>. For instance, to allow everyone to connect, touch @@ -223,6 +226,11 @@ set of identifiers that the client is allowed to use to retrieve file descriptors. For instance, <tt>^unix:/tmp/</tt> indicates that a client that matches this rule will be allowed to retrieve file descriptors that are identified by strings starting with <tt>unix:/tmp/</tt>. </li> + <li> Listing rights. This will be checked for clients wanting to list +the identifiers of the descriptors currently stored in the server. This +right is given if a non-empty file named <tt>S6_FDHOLDER_LIST</tt> is +found in the <tt>env/</tt> subdirectory of one of the subdirectories checked by +<a href="libs6/accessrules.html#uidgid">s6_accessrules_keycheck_uidgid</a>. </li> <li> Dump reading rights. This will be checked for clients wanting to copy the whole state of the server. This right is given if a non-empty file named <tt>S6_FDHOLDER_GETDUMP</tt> is found is the <tt>env/</tt> @@ -298,9 +306,8 @@ hand, it makes little sense to fd-hold regular files, and if done anyway, the results can be surprising, because the read/write file offset is stored with the descriptor, and no automatic rewind is performed by the daemon. </li> - <li> Anyone that is allowed to connect is allowed to read the whole list -of identifiers. This is intentional: identifiers should be public and -well-known, and the security of the system should not depend on a client + <li> Despite there being access control for listing, the security of the +system should not depend on a client not knowing what identifier a certain descriptor is stored under. If you need to hold descriptors that only a few programs are supposed to access, you can always run a separate s6-fdholderd instance in a private directory diff --git a/src/fdholder/s6-fdholderd.c b/src/fdholder/s6-fdholderd.c @@ -316,6 +316,7 @@ static int do_list (unsigned int cc, unixmessage_t const *m) siovec_t *vp = v + 1 ; char pack[5] = "" ; if (c->dumping || m->len || m->nfds) return (errno = EPROTO, 0) ; + if (!(c->flags & 4)) return answer(c, EPERM) ; uint32_pack_big(pack + 1, (uint32)numfds) ; v[0].s = pack ; v[0].len = 5 ; genset_iter(fdstore, &fill_siovec_with_ids_iter, &vp) ; @@ -554,6 +555,7 @@ static inline int parse_env (char const *const *envp, regex_t *rre, regex_t *wre { if (str_start(*envp, "S6_FDHOLDER_GETDUMP=")) fl |= 1 ; if (str_start(*envp, "S6_FDHOLDER_SETDUMP=")) fl |= 2 ; + if (str_start(*envp, "S6_FDHOLDER_LIST=")) fl |= 4 ; if (!rre_done) { rre_done = makere(rre, *envp, "S6_FDHOLDER_RETRIEVE_REGEX") ; @@ -675,9 +677,9 @@ int main (int argc, char const *const *argv, char const *const *envp) strerr_diefu1sys(111, "getrlimit") ; if (fdlimit.rlim_cur != RLIM_INFINITY) { - if (fdlimit.rlim_cur < 6) + if (fdlimit.rlim_cur < 7) strerr_dief1x(111, "open file limit too low") ; - if (maxfds > fdlimit.rlim_cur) maxfds = fdlimit.rlim_cur - 5 ; + if (maxfds > fdlimit.rlim_cur) maxfds = fdlimit.rlim_cur - 6 ; } } if (!maxfds) maxfds = 1 ;