loader.c 2.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>

/* Defined in nsexec.c. */

#define PANIC   "panic"
#define FATAL   "fatal"
#define ERROR   "error"
#define WARNING "warning"
#define INFO    "info"
#define DEBUG   "debug"

void write_log_with_info(const char *level, const char *function, int line, const char *format, ...);

#define write_log(level, fmt, ...) \
	write_log_with_info((level), __FUNCTION__, __LINE__, (fmt), ##__VA_ARGS__)

struct pal_attr_t {
	const char *args;
	const char *log_level;
};

struct pal_stdio_fds {
	int stdin, stdout, stderr;
};

31 32

int (*fptr_pal_get_version)(void);
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
int (*fptr_pal_init)(const struct pal_attr_t *attr);
int (*fptr_pal_exec)(const char *path, const char * const argv[],
			const struct pal_stdio_fds *stdio, int *exit_code);
int (*fptr_pal_kill)(int sig, int pid);
int (*fptr_pal_destroy)(void);

int is_enclave(void)
{
	const char *env;
	env = getenv("_LIBCONTAINER_PAL_PATH");
	if (env == NULL || *env == '\0')
		return 0;
	return 1;
}

int load_enclave_runtime(void)
{
50
	const char *file;
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
	const char *rootfs;
	void *dl;

	file = getenv("_LIBCONTAINER_PAL_PATH");
	if (file == NULL || *file == '\0') {
		write_log(DEBUG, "invalid environment _LIBCONTAINER_PAL_PATH");
		return -EINVAL;
	}
	write_log(DEBUG, "_LIBCONTAINER_PAL_PATH = %s", file);

	/* dlopen */
	rootfs = getenv("_LIBCONTAINER_PAL_ROOTFS");
	if (rootfs && *rootfs != '\0') {
		char sofile[BUFSIZ];
		char ldpath[BUFSIZ];
		const char *env_ldpath;

68
		if (*file != '/') {
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
			write_log(DEBUG, "_LIBCONTAINER_PAL_PATH must be a absolute path");
			return -ENOSPC;
		}
		snprintf(sofile, sizeof(sofile), "%s/%s", rootfs, file);
		snprintf(ldpath, sizeof(ldpath), "%s/lib64", rootfs);

		env_ldpath = getenv("LD_LIBRARY_PATH");
		if (env_ldpath && *env_ldpath != '\0') {
			char *saved_ldpath = strdup(env_ldpath);
			if (saved_ldpath == NULL)
				return -ENOMEM;
			setenv("LD_LIBRARY_PATH", ldpath, 1);
			dl = dlopen(sofile, RTLD_NOW);
			setenv("LD_LIBRARY_PATH", saved_ldpath, 1);
			free(saved_ldpath);
		} else {
			setenv("LD_LIBRARY_PATH", ldpath, 1);
			dl = dlopen(sofile, RTLD_NOW);
			unsetenv("LD_LIBRARY_PATH");
		}
	} else {
		dl = dlopen(file, RTLD_NOW);
	}

	if (dl == NULL) {
		write_log(DEBUG, "dlopen(): %s", dlerror());
		return -ENOEXEC;
	}

#define DLSYM(fn)								\
	do {									\
100 101
		fptr_pal_ ## fn = dlsym(dl, "pal_" #fn);				\
		write_log(DEBUG, "dlsym(%s) = %p", "pal_" #fn, fptr_pal_ ## fn);	\
102 103
	} while (0)

104
	DLSYM(get_version);
105 106 107 108 109 110 111 112
	DLSYM(init);
	DLSYM(exec);
	DLSYM(kill);
	DLSYM(destroy);
#undef DLSYM

	return 0;
}