diff options
-rw-r--r-- | bash-completion/unshare | 6 | ||||
-rw-r--r-- | libblkid/src/superblocks/lvm.c | 2 | ||||
-rw-r--r-- | sys-utils/unshare.1 | 13 | ||||
-rw-r--r-- | sys-utils/unshare.c | 62 | ||||
-rw-r--r-- | term-utils/agetty.c | 8 |
5 files changed, 80 insertions, 11 deletions
diff --git a/bash-completion/unshare b/bash-completion/unshare index 3fda4a194..10afffe19 100644 --- a/bash-completion/unshare +++ b/bash-completion/unshare @@ -33,7 +33,11 @@ _unshare_module() --propagation --setgroups --help - --version" + --version + --root + --wd + --setuid + --setgid" COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) ) return 0 ;; diff --git a/libblkid/src/superblocks/lvm.c b/libblkid/src/superblocks/lvm.c index 17731a8fd..c7e456fa9 100644 --- a/libblkid/src/superblocks/lvm.c +++ b/libblkid/src/superblocks/lvm.c @@ -193,7 +193,7 @@ static int probe_integrity(blkid_probe pr, const struct blkid_idmag *mag) if (sb == NULL) return errno ? -errno : 1; - if (sb->version != 1) + if (sb->version !=1 && sb->version != 2) return 1; blkid_probe_sprintf_version(pr, "%u", sb->version); diff --git a/sys-utils/unshare.1 b/sys-utils/unshare.1 index 746c41152..d2ba6c3a5 100644 --- a/sys-utils/unshare.1 +++ b/sys-utils/unshare.1 @@ -186,6 +186,19 @@ the GID map becomes writable by unprivileged processes when .BR \%setgroups (2) is permanently disabled (with \fBdeny\fR). .TP +.BR \-R, "\-\-root=\fIdir" +run the command with root directory set to \fIdir\fP. +.TP +.BR \-w, "\-\-wd=\fIdir" +change working directory to \fIdir\fP. +.TP +.BR \-S, "\-\-setuid \fIuid" +Set the user ID which will be used in the entered namespace. +.TP +.BR \-G, "\-\-setgid \fIgid" +Set the group ID which will be used in the entered namespace and drop +supplementary groups. +.TP .BR \-V , " \-\-version" Display version information and exit. .TP diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c index 661665aeb..e9ddb09de 100644 --- a/sys-utils/unshare.c +++ b/sys-utils/unshare.c @@ -29,6 +29,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/prctl.h> +#include <grp.h> /* we only need some defines missing in sys/mount.h, no libmount linkage */ #include <libmount.h> @@ -42,6 +43,7 @@ #include "pathnames.h" #include "all-io.h" #include "signames.h" +#include "strutils.h" /* synchronize parent and child by pipe */ #define PIPE_SYNC_BYTE 0x06 @@ -269,6 +271,11 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" --propagation slave|shared|private|unchanged\n" " modify mount propagation in mount namespace\n"), out); fputs(_(" --setgroups allow|deny control the setgroups syscall in user namespaces\n"), out); + fputs(USAGE_SEPARATOR, out); + fputs(_(" -R, --root=<dir> run the command with root directory set to <dir>\n"), out); + fputs(_(" -w, --wd=<dir> change working directory to <dir>\n"), out); + fputs(_(" -S, --setuid <uid> set uid in entered namespace\n"), out); + fputs(_(" -G, --setgid <gid> set gid in entered namespace\n"), out); fputs(USAGE_SEPARATOR, out); printf(USAGE_HELP_OPTIONS(27)); @@ -283,7 +290,7 @@ int main(int argc, char *argv[]) OPT_MOUNTPROC = CHAR_MAX + 1, OPT_PROPAGATION, OPT_SETGROUPS, - OPT_KILLCHILD + OPT_KILLCHILD, }; static const struct option longopts[] = { { "help", no_argument, NULL, 'h' }, @@ -303,6 +310,10 @@ int main(int argc, char *argv[]) { "map-root-user", no_argument, NULL, 'r' }, { "propagation", required_argument, NULL, OPT_PROPAGATION }, { "setgroups", required_argument, NULL, OPT_SETGROUPS }, + { "setuid", required_argument, NULL, 'S' }, + { "setgid", required_argument, NULL, 'G' }, + { "root", required_argument, NULL, 'R' }, + { "wd", required_argument, NULL, 'w' }, { NULL, 0, NULL, 0 } }; @@ -311,19 +322,22 @@ int main(int argc, char *argv[]) int c, forkit = 0, maproot = 0; int kill_child_signo = 0; /* 0 means --kill-child was not used */ const char *procmnt = NULL; + const char *newroot = NULL; + const char *newdir = NULL; pid_t pid = 0; int fds[2]; int status; unsigned long propagation = UNSHARE_PROPAGATION_DEFAULT; - uid_t real_euid = geteuid(); - gid_t real_egid = getegid(); + int force_uid = 0, force_gid = 0; + uid_t uid = 0, real_euid = geteuid(); + gid_t gid = 0, real_egid = getegid(); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); - while ((c = getopt_long(argc, argv, "+fhVmuinpCUr", longopts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "+fhVmuinpCUrR:w:S:G:", longopts, NULL)) != -1) { switch (c) { case 'f': forkit = 1; @@ -392,6 +406,20 @@ int main(int argc, char *argv[]) kill_child_signo = SIGKILL; } break; + case 'S': + uid = strtoul_or_err(optarg, _("failed to parse uid")); + force_uid = 1; + break; + case 'G': + gid = strtoul_or_err(optarg, _("failed to parse gid")); + force_gid = 1; + break; + case 'R': + newroot = optarg; + break; + case 'w': + newdir = optarg; + break; default: errtryhelp(EXIT_FAILURE); } @@ -471,10 +499,30 @@ int main(int argc, char *argv[]) if ((unshare_flags & CLONE_NEWNS) && propagation) set_propagation(propagation); - if (procmnt && - (mount("none", procmnt, NULL, MS_PRIVATE|MS_REC, NULL) != 0 || - mount("proc", procmnt, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) != 0)) + if (newroot) { + if (chroot(newroot) != 0) + err(EXIT_FAILURE, + _("cannot change root directory to '%s'"), newroot); + newdir = newdir ?: "/"; + } + if (newdir && chdir(newdir)) + err(EXIT_FAILURE, _("cannot chdir to '%s'"), newdir); + + if (procmnt) { + if (!newroot && mount("none", procmnt, NULL, MS_PRIVATE|MS_REC, NULL) != 0) + err(EXIT_FAILURE, _("umount %s failed"), procmnt); + if (mount("proc", procmnt, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) != 0) err(EXIT_FAILURE, _("mount %s failed"), procmnt); + } + + if (force_gid) { + if (setgroups(0, NULL) != 0) /* drop supplementary groups */ + err(EXIT_FAILURE, _("setgroups failed")); + if (setgid(gid) < 0) /* change GID */ + err(EXIT_FAILURE, _("setgid failed")); + } + if (force_uid && setuid(uid) < 0) /* change UID */ + err(EXIT_FAILURE, _("setuid failed")); if (optind < argc) { execvp(argv[optind], argv + optind); diff --git a/term-utils/agetty.c b/term-utils/agetty.c index 05a269abb..615db2c78 100644 --- a/term-utils/agetty.c +++ b/term-utils/agetty.c @@ -1768,6 +1768,7 @@ static void eval_issue_file(struct issue *ie __attribute__((__unused__)), } #else /* ISSUE_SUPPORT */ +#ifdef AGETTY_RELOAD static int issue_is_changed(struct issue *ie) { if (ie->mem_old && ie->mem @@ -1780,6 +1781,7 @@ static int issue_is_changed(struct issue *ie) return 1; } +#endif static void print_issue_file(struct issue *ie, struct options *op, @@ -2066,8 +2068,8 @@ static char *get_logname(struct issue *ie, struct options *op, struct termios *t /* Write issue file and prompt */ do_prompt(ie, op, tp); -#ifdef AGETTY_RELOAD no_reload: +#ifdef AGETTY_RELOAD if (!wait_for_term_input(STDIN_FILENO)) { /* refresh prompt -- discard input data, clear terminal * and call do_prompt() again @@ -2731,6 +2733,7 @@ static void output_special_char(struct issue *ie, fprintf (ie->output, "%d ", users); break; } +#if defined(RTMGRP_IPV4_IFADDR) && defined(RTMGRP_IPV6_IFADDR) case '4': case '6': { @@ -2754,8 +2757,9 @@ static void output_special_char(struct issue *ie, netlink_groups |= RTMGRP_IPV6_IFADDR; break; } +#endif default: - putchar(c); + putc(c, ie->output); break; } } |