From b29e48276716a369cdd33473afe96b43ee39e66a Mon Sep 17 00:00:00 2001 From: Juan RP Date: Wed, 6 Jul 2011 17:02:19 +0200 Subject: [PATCH] xbps-src: improved xbps-src-chroot-capumount helper. New security enhancements have been made and now you can only umount a filesystem when the status file "._mount_bind_done" is available in the specified masterdir. The arguments have been changed and now it accepts two for and . --- xbps-src/libexec/umount.c | 62 ++++++++++++++++--- xbps-src/libexec/xbps-src-chroot-helper.sh.in | 2 +- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/xbps-src/libexec/umount.c b/xbps-src/libexec/umount.c index 91c88e94b97..23314526d60 100644 --- a/xbps-src/libexec/umount.c +++ b/xbps-src/libexec/umount.c @@ -1,8 +1,35 @@ -/* - * Umounts a previously bind mounted filesystem mountpoint, - * by using the CAP_SYS_ADMIN capability set on the file. +/*- + * Copyright (c) 2010-2011 Juan Romero Pardines. + * All rights reserved. * - * Juan RP - 2010/04/26 - Public Domain. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Umounts a mounted filesystem mountpoint as regular user thanks to + * the CAP_SYS_ADMIN capability flag set on the file. The following + * arguments are expected: . + * + * As security measure it only accepts to unmount a mount point + * when the "status" file has been previously written in the masterdir. */ #include #include @@ -10,13 +37,16 @@ #include #include #include +#include #include #include +#define _PROGNAME "xbps-src-chroot-capumount" + void usage(void) { - fprintf(stderr, "Usage: xbps-src-capbumount \n"); + fprintf(stderr, "Usage: %s \n", _PROGNAME); exit(EXIT_FAILURE); } @@ -25,9 +55,10 @@ main(int argc, char **argv) { cap_t cap; cap_flag_value_t effective, permitted; + char bindf[PATH_MAX - 1]; int rv; - if (argc != 2) + if (argc != 3) usage(); cap = cap_get_proc(); @@ -48,7 +79,24 @@ main(int argc, char **argv) } cap_free(cap); - if ((rv = umount(argv[1])) != 0) { + /* Check that status file exists in masterdir */ + rv = snprintf(bindf, sizeof(bindf), "%s/.%s_mount_bind_done", + argv[1], argv[2]); + if (rv < 0 || rv >= sizeof(bindf)) + exit(EXIT_FAILURE); + + if (access(bindf, R_OK) == -1) { + fprintf(stderr, "E: cannot umount %s/%s, missing " + "status file\n", argv[1], argv[2]); + exit(EXIT_FAILURE); + } + + /* Security check passed, continue mounting */ + rv = snprintf(bindf, sizeof(bindf), "%s/%s", argv[1], argv[2]); + if (rv < 0 || rv >= sizeof(bindf)) + exit(EXIT_FAILURE); + + if ((rv = umount(bindf)) != 0) { fprintf(stderr, "E: cannot umount %s: %s\n", argv[1], strerror(errno)); exit(EXIT_FAILURE); diff --git a/xbps-src/libexec/xbps-src-chroot-helper.sh.in b/xbps-src/libexec/xbps-src-chroot-helper.sh.in index 440b4e74a97..6e3c099e6cb 100644 --- a/xbps-src/libexec/xbps-src-chroot-helper.sh.in +++ b/xbps-src/libexec/xbps-src-chroot-helper.sh.in @@ -95,7 +95,7 @@ umount_chroot_fs() else echo -n "=> Unmounting ${fs} from chroot... " @@XBPS_INSTALL_LIBEXECDIR@@/xbps-src-chroot-capumount \ - ${XBPS_MASTERDIR}/${fs} 2>/dev/null + ${XBPS_MASTERDIR} ${fs} 2>/dev/null if [ $? -eq 0 ]; then rm -f ${XBPS_MASTERDIR}/.${fs}_mount_bind_done echo "done."