Add pivot_root() and unpivot_root() to switch the root dir and restore it.
This will be used to more accurately handling command resolution and path matching when a new root directory is specified.
This commit is contained in:
1
MANIFEST
1
MANIFEST
@@ -661,6 +661,7 @@ plugins/sudoers/mkdefaults
|
|||||||
plugins/sudoers/parse.c
|
plugins/sudoers/parse.c
|
||||||
plugins/sudoers/parse.h
|
plugins/sudoers/parse.h
|
||||||
plugins/sudoers/parse_ldif.c
|
plugins/sudoers/parse_ldif.c
|
||||||
|
plugins/sudoers/pivot.c
|
||||||
plugins/sudoers/po/README
|
plugins/sudoers/po/README
|
||||||
plugins/sudoers/po/ast.mo
|
plugins/sudoers/po/ast.mo
|
||||||
plugins/sudoers/po/ast.po
|
plugins/sudoers/po/ast.po
|
||||||
|
@@ -176,7 +176,7 @@ AUTH_OBJS = sudo_auth.lo @AUTH_OBJS@
|
|||||||
LIBPARSESUDOERS_OBJS = alias.lo b64_decode.lo defaults.lo digestname.lo \
|
LIBPARSESUDOERS_OBJS = alias.lo b64_decode.lo defaults.lo digestname.lo \
|
||||||
exptilde.lo filedigest.lo gentime.lo gram.lo \
|
exptilde.lo filedigest.lo gentime.lo gram.lo \
|
||||||
match.lo match_addr.lo match_command.lo \
|
match.lo match_addr.lo match_command.lo \
|
||||||
match_digest.lo pwutil.lo pwutil_impl.lo \
|
match_digest.lo pivot.lo pwutil.lo pwutil_impl.lo \
|
||||||
redblack.lo strlist.lo sudoers_debug.lo timeout.lo \
|
redblack.lo strlist.lo sudoers_debug.lo timeout.lo \
|
||||||
timestr.lo toke.lo toke_util.lo
|
timestr.lo toke.lo toke_util.lo
|
||||||
|
|
||||||
@@ -2378,6 +2378,26 @@ passwd.i: $(authdir)/passwd.c $(authdir)/sudo_auth.h $(devdir)/def_data.h \
|
|||||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
passwd.plog: passwd.i
|
passwd.plog: passwd.i
|
||||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/passwd.c --i-file $< --output-file $@
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(authdir)/passwd.c --i-file $< --output-file $@
|
||||||
|
pivot.lo: $(srcdir)/pivot.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||||
|
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||||
|
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
||||||
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
|
||||||
|
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
|
||||||
|
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||||
|
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||||
|
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/pivot.c
|
||||||
|
pivot.i: $(srcdir)/pivot.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
|
||||||
|
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||||
|
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||||
|
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
||||||
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
|
||||||
|
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
|
||||||
|
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||||
|
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||||
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
|
pivot.plog: pivot.i
|
||||||
|
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/pivot.c --i-file $< --output-file $@
|
||||||
policy.lo: $(srcdir)/policy.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
|
policy.lo: $(srcdir)/policy.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
|
||||||
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
|
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
|
||||||
$(incdir)/sudo_debug.h $(incdir)/sudo_eventlog.h \
|
$(incdir)/sudo_debug.h $(incdir)/sudo_eventlog.h \
|
||||||
@@ -2925,8 +2945,9 @@ sudoreplay.o: $(srcdir)/sudoreplay.c $(incdir)/compat/getopt.h \
|
|||||||
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||||
$(incdir)/sudo_event.h $(incdir)/sudo_eventlog.h \
|
$(incdir)/sudo_event.h $(incdir)/sudo_eventlog.h \
|
||||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
|
$(incdir)/sudo_iolog.h $(incdir)/sudo_lbuf.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/logging.h \
|
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||||
|
$(incdir)/sudo_util.h $(srcdir)/logging.h \
|
||||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/sudoreplay.c
|
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/sudoreplay.c
|
||||||
sudoreplay.i: $(srcdir)/sudoreplay.c $(incdir)/compat/getopt.h \
|
sudoreplay.i: $(srcdir)/sudoreplay.c $(incdir)/compat/getopt.h \
|
||||||
@@ -2934,8 +2955,9 @@ sudoreplay.i: $(srcdir)/sudoreplay.c $(incdir)/compat/getopt.h \
|
|||||||
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||||
$(incdir)/sudo_event.h $(incdir)/sudo_eventlog.h \
|
$(incdir)/sudo_event.h $(incdir)/sudo_eventlog.h \
|
||||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||||
$(incdir)/sudo_iolog.h $(incdir)/sudo_plugin.h \
|
$(incdir)/sudo_iolog.h $(incdir)/sudo_lbuf.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/logging.h \
|
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
|
||||||
|
$(incdir)/sudo_util.h $(srcdir)/logging.h \
|
||||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
sudoreplay.plog: sudoreplay.i
|
sudoreplay.plog: sudoreplay.i
|
||||||
|
90
plugins/sudoers/pivot.c
Normal file
90
plugins/sudoers/pivot.c
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: ISC
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||||
|
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "sudoers.h"
|
||||||
|
|
||||||
|
#define OLD_ROOT 0
|
||||||
|
#define OLD_CWD 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pivot to a new root directory, storing the old root and old cwd
|
||||||
|
* in fds[2]. Changes current working directory to the new root.
|
||||||
|
* Returns true on success, else false.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
pivot_root(const char *new_root, int fds[2])
|
||||||
|
{
|
||||||
|
debug_decl(pivot_root, SUDOERS_DEBUG_UTIL);
|
||||||
|
|
||||||
|
fds[OLD_ROOT] = open("/", O_RDONLY);
|
||||||
|
fds[OLD_CWD] = open(".", O_RDONLY);
|
||||||
|
if (fds[OLD_ROOT] == -1 || fds[OLD_CWD] == -1 || chroot(new_root) == -1) {
|
||||||
|
if (fds[OLD_ROOT] != -1) {
|
||||||
|
close(fds[OLD_ROOT]);
|
||||||
|
fds[OLD_ROOT] = -1;
|
||||||
|
}
|
||||||
|
if (fds[OLD_CWD] != -1) {
|
||||||
|
close(fds[OLD_CWD]);
|
||||||
|
fds[OLD_CWD] = -1;
|
||||||
|
}
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
debug_return_bool(chdir("/") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pivot back to the stored root directory and restore the old cwd.
|
||||||
|
* Returns true on success, else false.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
unpivot_root(int fds[2])
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
debug_decl(unpivot_root, SUDOERS_DEBUG_UTIL);
|
||||||
|
|
||||||
|
/* Order is imporant: restore old root, *then* change cwd. */
|
||||||
|
if (fds[OLD_ROOT] != -1) {
|
||||||
|
if (fchdir(fds[OLD_ROOT]) == -1 || chroot(".") == -1) {
|
||||||
|
sudo_warn("%s", U_("unable to restore root directory"));
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
close(fds[OLD_ROOT]);
|
||||||
|
fds[OLD_ROOT] = -1;
|
||||||
|
}
|
||||||
|
if (fds[OLD_CWD] != -1) {
|
||||||
|
if (fchdir(fds[OLD_CWD]) == -1) {
|
||||||
|
sudo_warn("%s", U_("unable to restore current working directory"));
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
close(fds[OLD_CWD]);
|
||||||
|
fds[OLD_CWD] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_return_bool(ret);
|
||||||
|
}
|
@@ -489,4 +489,8 @@ void unescape_string(char *str);
|
|||||||
/* serialize_list.c */
|
/* serialize_list.c */
|
||||||
char *serialize_list(const char *varname, struct list_members *members);
|
char *serialize_list(const char *varname, struct list_members *members);
|
||||||
|
|
||||||
|
/* pivot_root.c */
|
||||||
|
bool pivot_root(const char *new_root, int fds[2]);
|
||||||
|
bool unpivot_root(int fds[2]);
|
||||||
|
|
||||||
#endif /* SUDOERS_SUDOERS_H */
|
#endif /* SUDOERS_SUDOERS_H */
|
||||||
|
Reference in New Issue
Block a user