init.c (2620B)
- // bootstrap-initrd: Linux initrd to bootstrap from a small binary seed
- // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #define _XOPEN_SOURCE 700 // mknod
- #include "src/loksh_tcc.h"
- #include <errno.h>
- #include <fcntl.h> // O_RDONLY
- #include <spawn.h> // posix_spawn
- #include <stdio.h> // fprintf
- #include <stdlib.h> // setenv
- #include <string.h> // strerror
- #include <sys/mount.h>
- #include <sys/stat.h> // mknod
- #include <sys/sysmacros.h> // makedev
- #include <sys/wait.h> // waitpid
- #include <unistd.h> // chdir, environ
- /* From SUS Chapter 8: Environment variable */
- extern char **environ;
- static int
- exec_wait(char *args[])
- {
- pid_t child = 0;
- // Allows to avoid a fork+exec
- int ret = posix_spawn(&child, args[0], NULL, NULL, args, environ);
- if(ret != 0)
- {
- fprintf(stderr, "Failed spawning command with argv[0] = '%s': %s\n", args[0], strerror(errno));
- return -1;
- }
- if(waitpid(child, NULL, 0) == -1)
- {
- fprintf(stderr, "Failed waiting for child of pid %d: %s\n", child, strerror(errno));
- return -1;
- }
- return 0;
- }
- static int
- build_loksh()
- {
- chdir("/src/loksh-7.6");
- fprintf(stderr, "Compiling loksh-7.6\n");
- if(exec_wait(loksh_tcc_cmd) < 0) return -1;
- fprintf(stderr, "Compiled loksh !\n");
- return 0;
- }
- int
- main(int argc, char *argv[])
- {
- setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1);
- setenv("HOME", "/root", 1);
- setenv("LOGNAME", "root", 1);
- if(build_loksh() < 0) return 1;
- if(mount("sysfs", "/sys", "sysfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, NULL) < 0)
- fprintf(stderr, "Failed to mount /sys: %s\n", strerror(errno));
- if(mount("proc", "/proc", "proc", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, "hidepid=2") <
- 0)
- fprintf(stderr, "Failed to mount /proc: %s\n", strerror(errno));
- if(mount("devtmpfs", "/dev", "devtmpfs", MS_NOSUID | MS_NOEXEC, NULL) < 0)
- fprintf(stderr, "Failed to mount /proc: %s\n", strerror(errno));
- errno = 0;
- if(mknod("/dev/null", S_IFCHR | 0666, makedev(0x1, 0x3)) < 0)
- {
- if(errno != 0 && errno != EEXIST)
- fprintf(stderr, "Failed to create /dev/null: %s\n", strerror(errno));
- }
- // PS1 shouldn't be exported but '\h\$ ' is an *awful* default
- // and oksh also doesn't sources ksh-specific files by default
- setenv("PS1", "$? $PWD # ", 1);
- fprintf(stderr, "Launching: /bin/loksh /init.sh\n");
- if(execl("/bin/loksh", "/bin/loksh", "/init.sh", (char *)0) < 0)
- {
- fprintf(stderr, "Failed to execute: %s\n", strerror(errno));
- return 1;
- }
- fprintf(stderr, "Unreachable\n");
- }