diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2021-04-23 14:56:00 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2021-04-23 14:56:00 +0000 |
commit | 27f1ba99521c4bdf081e6364ca4bea841aee8557 (patch) | |
tree | 87e37daeb930903a16341c6b42ff5f0fadc24c66 | |
parent | 3bde455795bb3273922ec7be293e3911913576c2 (diff) | |
download | s6-linux-init-27f1ba99521c4bdf081e6364ca4bea841aee8557.tar.xz |
Hack s6-l-i-m so it doesn't fail when run as non-root
-rw-r--r-- | doc/s6-linux-init-maker.html | 5 | ||||
-rw-r--r-- | package/modes | 2 | ||||
-rw-r--r-- | src/init/s6-linux-init-maker.c | 56 |
3 files changed, 41 insertions, 22 deletions
diff --git a/doc/s6-linux-init-maker.html b/doc/s6-linux-init-maker.html index 9bf44ac..9b148de 100644 --- a/doc/s6-linux-init-maker.html +++ b/doc/s6-linux-init-maker.html @@ -68,8 +68,11 @@ machine</em>. If it is not the case, the system will fail to boot. </pre> <ul> - <li> s6-linux-init-maker must be run as root, on the machine + <li> s6-linux-init-maker must be run on the machine that will boot an s6-based system. </li> + <li> It normally should be <em>run as root</em>. It supports +not running as root for a small amount of very specific cases; but +you should run it as root unless you know exactly what you are doing. </li> <li> s6-linux-init-maker parses options on its command line. </li> <li> It writes data into a directory <em>dir</em>, which must not exist beforehand. </li> diff --git a/package/modes b/package/modes index 0cc7f74..395d000 100644 --- a/package/modes +++ b/package/modes @@ -7,4 +7,4 @@ s6-linux-init-logouthookd 0744 s6-linux-init-echo 0755 s6-linux-init-nuke 0744 s6-linux-init-umountall 0744 -s6-linux-init-maker 0744 +s6-linux-init-maker 0755 diff --git a/src/init/s6-linux-init-maker.c b/src/init/s6-linux-init-maker.c index c505e04..af67bf7 100644 --- a/src/init/s6-linux-init-maker.c +++ b/src/init/s6-linux-init-maker.c @@ -46,7 +46,7 @@ static char const *initial_path = INITPATH ; static char const *env_store = 0 ; static char const *early_getty = 0 ; static char const *slashdev = 0 ; -static char const *log_user = "root" ; +static char const *log_user = 0 ; static char const *initdefault = 0 ; static char const *skeldir = S6_LINUX_INIT_SKELDIR ; static unsigned int initial_umask = 0022 ; @@ -57,9 +57,11 @@ static int console = 0 ; static int logouthookd = 0 ; static int inns = 0 ; static int nologger = 0 ; +static uid_t myuid = -1 ; +static gid_t mygid = -1 ; #ifdef S6_LINUX_INIT_UTMPD_PATH -static char const *utmp_user = "" ; +static char const *utmp_user = 0 ; #endif typedef int writetobuf_func_t (buffer *, char const *) ; @@ -153,7 +155,7 @@ static int s6_svscan_log_script (buffer *b, char const *data) EXECLINE_EXTBINPREFIX "redirfd -w 1 /dev/null") < 0 || buffer_puts(b, "\n" EXECLINE_EXTBINPREFIX "redirfd -rnb 0 " LOGGER_FIFO "\n") < 0) return 0 ; - if (strcmp(log_user, "root")) + if (log_user && strcmp(log_user, "root")) { size_t sabase = satmp.len ; if (buffer_puts(b, S6_EXTBINPREFIX "s6-setuidgid ") < 0 @@ -323,7 +325,7 @@ static void auto_dir_internal (char const *base, char const *dir, uid_t uid, gid } else { - if (chown(fn, uid, gid) < 0) goto err ; + if (!myuid && !mygid && chown(fn, uid, gid) < 0) goto err ; if (mode & 07000 && chmod(fn, mode) < 0) goto err ; } return ; @@ -469,17 +471,25 @@ static void make_env (char const *base, char const *envname, char *modif, size_t static void getug (char const *base, char const *s, uid_t *uid, gid_t *gid) { - struct passwd *pw ; - errno = 0 ; - pw = getpwnam(s) ; - if (!pw) + if (!s || myuid || mygid) { - cleanup(base) ; - if (!errno) strerr_diefu3x(100, "find user ", s, " in passwd database") ; - else strerr_diefu2sys(111, "getpwnam for ", s) ; + *uid = myuid ; + *gid = mygid ; + } + else + { + struct passwd *pw ; + errno = 0 ; + pw = getpwnam(s) ; + if (!pw) + { + cleanup(base) ; + if (!errno) strerr_diefu3x(100, "find user ", s, " in passwd database") ; + else strerr_diefu2sys(111, "getpwnam for ", s) ; + } + *uid = pw->pw_uid ; + *gid = pw->pw_gid ; } - *uid = pw->pw_uid ; - *gid = pw->pw_gid ; } #ifdef S6_LINUX_INIT_UTMPD_PATH @@ -504,12 +514,16 @@ static int utmpd_script (buffer *b, char const *aux) size_t sabase = satmp.len ; if (!put_shebang(b) || buffer_puts(b, - EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n" - S6_EXTBINPREFIX "s6-setuidgid ") < 0 - || !string_quote(&satmp, utmp_user, strlen(utmp_user))) return 0 ; - if (buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0) goto err ; - satmp.len = sabase ; - if (buffer_puts(b, "\n" + EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n") < 0) return 0 ; + if (utmp_user) + { + if (!buffer_puts(b, S6_EXTBINPREFIX "s6-setuidgid ") < 0 + || !string_quote(&satmp, utmp_user, strlen(utmp_user))) return 0 ; + if (buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0) goto err ; + satmp.len = sabase ; + if (buffer_put(b, "\n", 1) < 0) return 0 ; + } + if (buffer_puts(b, EXECLINE_EXTBINPREFIX "cd " S6_LINUX_INIT_TMPFS "/" UTMPS_DIR "\n" EXECLINE_EXTBINPREFIX "fdmove 1 3\n" S6_EXTBINPREFIX "s6-ipcserver -1 -c 1000 -- " UTMPS_UTMPD_PATH "\n" @@ -597,7 +611,7 @@ static inline void make_image (char const *base) } #ifdef S6_LINUX_INIT_UTMPD_PATH - if (utmp_user[0]) make_utmps(base) ; + if (utmp_user) make_utmps(base) ; #endif } @@ -676,6 +690,8 @@ int main (int argc, char const *const *argv, char const *const *envp) if (inns && slashdev) strerr_warnw1x("both -C and -d options given; are you sure your container does not come with a pre-mounted /dev?") ; + myuid = getuid() ; + mygid = getgid() ; umask(0) ; if (mkdir(argv[0], 0755) < 0) strerr_diefu2sys(111, "mkdir ", argv[0]) ; |