Enable veriexec for loader
This relies on libbearssl and libsecureboot to verify files read by loader in a maner equivalent to how mac_veriexec Note: disabled by default. Use is initially expected to be by embeded vendors Reviewed by: emaste, imp Sponsored by: Juniper Networks Differential Revision: D16336
This commit is contained in:
parent
eb12b8ea5e
commit
8df8b2d3e5
@ -106,6 +106,10 @@ command_boot(int argc, char *argv[])
|
|||||||
if (archsw.arch_autoload() != 0)
|
if (archsw.arch_autoload() != 0)
|
||||||
return(CMD_ERROR);
|
return(CMD_ERROR);
|
||||||
|
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
verify_pcr_export(); /* for measured boot */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Call the exec handler from the loader matching the kernel */
|
/* Call the exec handler from the loader matching the kernel */
|
||||||
file_formats[fp->f_loader]->l_exec(fp);
|
file_formats[fp->f_loader]->l_exec(fp);
|
||||||
return(CMD_ERROR);
|
return(CMD_ERROR);
|
||||||
|
@ -330,6 +330,9 @@ struct arch_switch
|
|||||||
/* Probe ZFS pool(s), if needed. */
|
/* Probe ZFS pool(s), if needed. */
|
||||||
void (*arch_zfs_probe)(void);
|
void (*arch_zfs_probe)(void);
|
||||||
|
|
||||||
|
/* Return the hypervisor name/type or NULL if not virtualized. */
|
||||||
|
const char *(*arch_hypervisor)(void);
|
||||||
|
|
||||||
/* For kexec-type loaders, get ksegment structure */
|
/* For kexec-type loaders, get ksegment structure */
|
||||||
void (*arch_kexec_kseg_get)(int *nseg, void **kseg);
|
void (*arch_kexec_kseg_get)(int *nseg, void **kseg);
|
||||||
};
|
};
|
||||||
@ -346,4 +349,8 @@ time_t time(time_t *tloc);
|
|||||||
#define CTASSERT(x) _Static_assert(x, "compile-time assertion failed")
|
#define CTASSERT(x) _Static_assert(x, "compile-time assertion failed")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
#include <verify_file.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* !_BOOTSTRAP_H_ */
|
#endif /* !_BOOTSTRAP_H_ */
|
||||||
|
@ -379,6 +379,13 @@ interp_include(const char *filename)
|
|||||||
return(CMD_ERROR);
|
return(CMD_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
if (verify_file(fd, filename, 0, VE_GUESS) < 0) {
|
||||||
|
close(fd);
|
||||||
|
sprintf(command_errbuf,"can't verify '%s'", filename);
|
||||||
|
return(CMD_ERROR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Read the script into memory.
|
* Read the script into memory.
|
||||||
*/
|
*/
|
||||||
|
@ -96,6 +96,14 @@ interp_include(const char *filename)
|
|||||||
return(CMD_ERROR);
|
return(CMD_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
if (verify_file(fd, filename, 0, VE_GUESS) < 0) {
|
||||||
|
close(fd);
|
||||||
|
sprintf(command_errbuf,"can't verify '%s'", filename);
|
||||||
|
return(CMD_ERROR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the script into memory.
|
* Read the script into memory.
|
||||||
*/
|
*/
|
||||||
|
@ -245,6 +245,12 @@ __elfN(load_elf_header)(char *filename, elf_file_t ef)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
if (verify_file(ef->fd, filename, bytes_read, VE_MUST) < 0) {
|
||||||
|
err = EAUTH;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -129,6 +129,13 @@ __elfN(obj_loadfile)(char *filename, uint64_t dest,
|
|||||||
goto oerr;
|
goto oerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
if (verify_file(ef.fd, filename, bytes_read, VE_MUST) < 0) {
|
||||||
|
err = EAUTH;
|
||||||
|
goto oerr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
kfp = file_findfile(NULL, __elfN(obj_kerneltype));
|
kfp = file_findfile(NULL, __elfN(obj_kerneltype));
|
||||||
if (kfp == NULL) {
|
if (kfp == NULL) {
|
||||||
printf("elf" __XSTRING(__ELF_WORD_SIZE)
|
printf("elf" __XSTRING(__ELF_WORD_SIZE)
|
||||||
|
@ -104,6 +104,8 @@ command_load(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
struct preloaded_file *fp;
|
struct preloaded_file *fp;
|
||||||
char *typestr;
|
char *typestr;
|
||||||
|
char *prefix;
|
||||||
|
char *skip;
|
||||||
int dofile, dokld, ch, error;
|
int dofile, dokld, ch, error;
|
||||||
|
|
||||||
dokld = dofile = 0;
|
dokld = dofile = 0;
|
||||||
@ -114,11 +116,18 @@ command_load(int argc, char *argv[])
|
|||||||
command_errmsg = "no filename specified";
|
command_errmsg = "no filename specified";
|
||||||
return (CMD_CRIT);
|
return (CMD_CRIT);
|
||||||
}
|
}
|
||||||
while ((ch = getopt(argc, argv, "kt:")) != -1) {
|
prefix = skip = NULL;
|
||||||
|
while ((ch = getopt(argc, argv, "kp:s:t:")) != -1) {
|
||||||
switch(ch) {
|
switch(ch) {
|
||||||
case 'k':
|
case 'k':
|
||||||
dokld = 1;
|
dokld = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
|
prefix = optarg;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
skip = optarg;
|
||||||
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
typestr = optarg;
|
typestr = optarg;
|
||||||
dofile = 1;
|
dofile = 1;
|
||||||
@ -141,6 +150,12 @@ command_load(int argc, char *argv[])
|
|||||||
return (CMD_CRIT);
|
return (CMD_CRIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
if (strncmp(typestr, "manifest", 8) == 0) {
|
||||||
|
return (load_manifest(argv[1], prefix, skip, NULL));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
fp = file_findfile(argv[1], typestr);
|
fp = file_findfile(argv[1], typestr);
|
||||||
if (fp) {
|
if (fp) {
|
||||||
snprintf(command_errbuf, sizeof(command_errbuf),
|
snprintf(command_errbuf, sizeof(command_errbuf),
|
||||||
@ -435,6 +450,15 @@ file_loadraw(const char *fname, char *type, int insert)
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
if (verify_file(fd, name, 0, VE_MUST) < 0) {
|
||||||
|
sprintf(command_errbuf, "can't verify '%s'", name);
|
||||||
|
free(name);
|
||||||
|
close(fd);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (archsw.arch_loadaddr != NULL)
|
if (archsw.arch_loadaddr != NULL)
|
||||||
loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr);
|
loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr);
|
||||||
|
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
# Autogenerated - do NOT edit!
|
# Autogenerated - do NOT edit!
|
||||||
|
|
||||||
DIRDEPS = \
|
DIRDEPS = \
|
||||||
include \
|
stand/libsa \
|
||||||
include/xlocale \
|
|
||||||
lib/msun \
|
|
||||||
|
|
||||||
|
|
||||||
.include <dirdeps.mk>
|
.include <dirdeps.mk>
|
||||||
|
@ -1157,6 +1157,10 @@ typedef void ficlCompileFcn(FICL_SYSTEM *);
|
|||||||
DATA_SET(Xficl_compile_set, func)
|
DATA_SET(Xficl_compile_set, func)
|
||||||
SET_DECLARE(Xficl_compile_set, ficlCompileFcn);
|
SET_DECLARE(Xficl_compile_set, ficlCompileFcn);
|
||||||
|
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
#include <verify_file.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -67,6 +67,13 @@ static void ficlFopen(FICL_VM *pVM, char *writeMode) /* ( c-addr u fam -- fileid
|
|||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
stackPushPtr(pVM->pStack, NULL);
|
stackPushPtr(pVM->pStack, NULL);
|
||||||
else
|
else
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
if (*mode == 'r' &&
|
||||||
|
verify_file(fileno(f), filename, 0, VE_GUESS) < 0) {
|
||||||
|
fclose(f);
|
||||||
|
stackPushPtr(pVM->pStack, NULL);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
ficlFILE *ff = (ficlFILE *)malloc(sizeof(ficlFILE));
|
ficlFILE *ff = (ficlFILE *)malloc(sizeof(ficlFILE));
|
||||||
strcpy(ff->filename, filename);
|
strcpy(ff->filename, filename);
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
# Autogenerated - do NOT edit!
|
# Autogenerated - do NOT edit!
|
||||||
|
|
||||||
DIRDEPS = \
|
DIRDEPS = \
|
||||||
include \
|
stand/libsa \
|
||||||
include/xlocale \
|
|
||||||
lib/msun \
|
|
||||||
|
|
||||||
|
|
||||||
.include <dirdeps.mk>
|
.include <dirdeps.mk>
|
||||||
|
@ -2,15 +2,12 @@
|
|||||||
# Autogenerated - do NOT edit!
|
# Autogenerated - do NOT edit!
|
||||||
|
|
||||||
DIRDEPS = \
|
DIRDEPS = \
|
||||||
include \
|
stand/${MACHINE_CPUARCH}/btx/btx \
|
||||||
include/xlocale \
|
stand/${MACHINE_CPUARCH}/btx/btxldr \
|
||||||
stand/ficl32 \
|
stand/${MACHINE_CPUARCH}/btx/lib \
|
||||||
stand/geli \
|
stand/${MACHINE_CPUARCH}/libi386 \
|
||||||
stand/i386/btx/btx \
|
stand/ficl \
|
||||||
stand/i386/btx/btxldr \
|
stand/libsa \
|
||||||
stand/i386/btx/lib \
|
|
||||||
stand/i386/libi386 \
|
|
||||||
stand/libsa32 \
|
|
||||||
|
|
||||||
|
|
||||||
.include <dirdeps.mk>
|
.include <dirdeps.mk>
|
||||||
|
@ -35,5 +35,8 @@ CFLAGS+= -I${BOOTSRC}/include -I${LIBLUASRC} -I${LUASRC} -I${LDRSRC}
|
|||||||
.if ${MACHINE_CPUARCH} == "amd64" && ${DO32:U0} == 0
|
.if ${MACHINE_CPUARCH} == "amd64" && ${DO32:U0} == 0
|
||||||
CFLAGS+= -fPIC
|
CFLAGS+= -fPIC
|
||||||
.endif
|
.endif
|
||||||
|
.if ${MK_LOADER_VERIEXEC} == "yes"
|
||||||
|
CFLAGS+= -I${SRCTOP}/lib/libsecureboot/h -DLOADER_VERIEXEC
|
||||||
|
.endif
|
||||||
|
|
||||||
.include <bsd.lib.mk>
|
.include <bsd.lib.mk>
|
||||||
|
@ -31,6 +31,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include "lstd.h"
|
#include "lstd.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
#include <verify_file.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
FILE *
|
FILE *
|
||||||
fopen(const char *filename, const char *mode)
|
fopen(const char *filename, const char *mode)
|
||||||
{
|
{
|
||||||
@ -76,6 +80,17 @@ fopen(const char *filename, const char *mode)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LOADER_VERIEXEC
|
||||||
|
/* only regular files and only reading makes sense */
|
||||||
|
if (S_ISREG(st.st_mode) && !(m & O_WRONLY)) {
|
||||||
|
if (verify_file(fd, filename, 0, VE_GUESS) < 0) {
|
||||||
|
free(f);
|
||||||
|
close(fd);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
f->fd = fd;
|
f->fd = fd;
|
||||||
f->offset = 0;
|
f->offset = 0;
|
||||||
f->size = st.st_size;
|
f->size = st.st_size;
|
||||||
|
@ -164,6 +164,11 @@ SRCS+= explicit_bzero.c crc32_libkern.c
|
|||||||
.include "${SASRC}/geli/Makefile.inc"
|
.include "${SASRC}/geli/Makefile.inc"
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
.if ${MK_LOADER_VERIEXEC} == "yes" && ${MK_BEARSSL} == "yes"
|
||||||
|
.include "${SRCTOP}/lib/libbearssl/Makefile.libsa.inc"
|
||||||
|
.include "${SRCTOP}/lib/libsecureboot/Makefile.libsa.inc"
|
||||||
|
.endif
|
||||||
|
|
||||||
# Maybe ZFS
|
# Maybe ZFS
|
||||||
.if ${MK_LOADER_ZFS} == "yes"
|
.if ${MK_LOADER_ZFS} == "yes"
|
||||||
.include "${SASRC}/zfs/Makefile.inc"
|
.include "${SASRC}/zfs/Makefile.inc"
|
||||||
|
@ -2,10 +2,6 @@
|
|||||||
# Autogenerated - do NOT edit!
|
# Autogenerated - do NOT edit!
|
||||||
|
|
||||||
DIRDEPS = \
|
DIRDEPS = \
|
||||||
include \
|
|
||||||
include/arpa \
|
|
||||||
include/xlocale \
|
|
||||||
lib/libbz2 \
|
|
||||||
|
|
||||||
|
|
||||||
.include <dirdeps.mk>
|
.include <dirdeps.mk>
|
||||||
|
@ -2,10 +2,7 @@
|
|||||||
# Autogenerated - do NOT edit!
|
# Autogenerated - do NOT edit!
|
||||||
|
|
||||||
DIRDEPS = \
|
DIRDEPS = \
|
||||||
include \
|
stand/libsa \
|
||||||
include/arpa \
|
|
||||||
include/xlocale \
|
|
||||||
lib/libbz2 \
|
|
||||||
|
|
||||||
|
|
||||||
.include <dirdeps.mk>
|
.include <dirdeps.mk>
|
||||||
|
@ -73,6 +73,10 @@ SRCS+= interp_simple.c
|
|||||||
.error Unknown interpreter ${LOADER_INTERP}
|
.error Unknown interpreter ${LOADER_INTERP}
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
.if ${MK_LOADER_VERIEXEC} != "no"
|
||||||
|
CFLAGS+= -DLOADER_VERIEXEC -I${SRCTOP}/lib/libsecureboot/h
|
||||||
|
.endif
|
||||||
|
|
||||||
.if defined(BOOT_PROMPT_123)
|
.if defined(BOOT_PROMPT_123)
|
||||||
CFLAGS+= -DBOOT_PROMPT_123
|
CFLAGS+= -DBOOT_PROMPT_123
|
||||||
.endif
|
.endif
|
||||||
|
Loading…
Reference in New Issue
Block a user