Skip to content

Instantly share code, notes, and snippets.

@lpereira lpereira/cryptsetup.diff Secret
Created May 9, 2017

Embed
What would you like to do?
diff --git a/src/cryptsetup.c b/src/cryptsetup.c
index 8920c1e..f945764 100644
--- a/src/cryptsetup.c
+++ b/src/cryptsetup.c
@@ -23,6 +23,13 @@
#include "cryptsetup.h"
+#include <linux/kexec.h>
+#include <linux/reboot.h>
+#include <sys/mount.h>
+#include <sys/reboot.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
static const char *opt_cipher = NULL;
static const char *opt_hash = NULL;
static int opt_verify_passphrase = 0;
@@ -1513,7 +1520,7 @@ static int run_action(struct action_type *action)
return translate_errno(r);
}
-int main(int argc, const char **argv)
+static int cryptsetup_main(int argc, const char **argv)
{
static char *popt_tmp;
static struct poptOption popt_help_options[] = {
@@ -1827,3 +1834,90 @@ int main(int argc, const char **argv)
poptFreeContext(popt_context);
return r;
}
+
+static long kexec_file_load(int kfd, int ifd, unsigned long cmdline_len,
+ const char *cmdline, unsigned long flags)
+{
+ return syscall(SYS_kexec_file_load, kfd, ifd, cmdline_len, cmdline, flags);
+}
+
+int main(int argc, char *argv[])
+{
+ static const char *open_boot_part_args[] = {
+ "/usr/bin/cryptsetup",
+ "open",
+ "--type",
+ "luks",
+ "/dev/sda1",
+ "bootpart",
+ };
+ static const char cmdline[] = "quiet root=/dev/sda6 rw";
+ static const int rw_mount_flags = MS_NOSUID | MS_NOEXEC;
+ static const int ro_mount_flags = MS_NOSUID | MS_NOEXEC | MS_RDONLY;
+ int initrd_fd, vmlinuz_fd;
+
+ if (mkdir("/proc", 0755) < 0) {
+ printf("Could not create /proc mount point\n");
+ sleep(5);
+ return EXIT_FAILURE;
+ }
+
+ if (mount("proc", "/proc", "proc", rw_mount_flags, NULL) < 0) {
+ printf("Could not mount /proc partition\n");
+ sleep(5);
+ return EXIT_FAILURE;
+ }
+
+ if (mount("dev", "/dev", "devtmpfs", rw_mount_flags, NULL) < 0) {
+ printf("Could not mount /dev partition\n");
+ sleep(5);
+ return EXIT_FAILURE;
+ }
+
+ if (cryptsetup_main(sizeof(open_boot_part_args)/sizeof(open_boot_part_args[0]),
+ open_boot_part_args) != EXIT_SUCCESS) {
+ printf("Could not open boot partition\n");
+ sleep(5);
+ return EXIT_FAILURE;
+ }
+
+ if (mkdir("/boot", 0755) < 0) {
+ printf("Could not create /boot mount point\n");
+ sleep(5);
+ return EXIT_FAILURE;
+ }
+
+ if (mount("/dev/mapper/bootpart", "/boot", "ext4", ro_mount_flags, NULL) < 0) {
+ printf("Could not mount /boot partition\n");
+ sleep(5);
+ return EXIT_FAILURE;
+ }
+
+ initrd_fd = open("/boot/initrd-linux.img", O_RDONLY | O_CLOEXEC);
+ if (initrd_fd < 0) {
+ printf("Could not open initrd\n");
+ sleep(5);
+ return EXIT_FAILURE;
+ }
+
+ vmlinuz_fd = open("/boot/vmlinuz-linux", O_RDONLY | O_CLOEXEC);
+ if (vmlinuz_fd < 0) {
+ printf("Could not open vmlinuz\n");
+ sleep(5);
+ return EXIT_FAILURE;
+ }
+
+ if (kexec_file_load(vmlinuz_fd, initrd_fd,
+ sizeof(cmdline), cmdline, 0) < 0) {
+
+ printf("Could not kexec: %s\n", strerror(errno));
+ sleep(5);
+ return EXIT_FAILURE;
+ }
+
+ reboot(LINUX_REBOOT_CMD_KEXEC);
+
+ printf("kexec failed: %s\n", strerror(errno));
+ sleep(5);
+ return EXIT_FAILURE;
+}
diff --git a/src/utils_password.c b/src/utils_password.c
index 0366b16..32ccae0 100644
--- a/src/utils_password.c
+++ b/src/utils_password.c
@@ -20,6 +20,7 @@
*/
#include "cryptsetup.h"
+#include <sys/time.h>
#include <termios.h>
int opt_force_password = 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.