svn commit: r364961 - in stable/12: lib/libsecureboot stand/common stand/uboot/lib sys/kern
Simon J. Gerraty
sjg at FreeBSD.org
Sat Aug 29 16:23:02 UTC 2020
Author: sjg
Date: Sat Aug 29 16:23:00 2020
New Revision: 364961
URL: https://svnweb.freebsd.org/changeset/base/364961
Log:
MFC loader fixes
r361710: stand/uboot: fix setting of gateip.s_addr
Missplaced paren.
r361933: loader: install allow for more complete device spec in url
Rework to simplify and impose sane url syntax.
That is we allow for file://[devname[:fstype]]/package
r362127: verify_pcr_export: bump kenv_mvallen if needed
r362231: make KENV_MVALLEN tunable
When doing secure boot, loader wants to export loader.ve.hashed
the value of which typically exceeds KENV_MVALLEN.
Replace use of KENV_MVALLEN with tunable kenv_mvallen.
Add getenv_string_buffer() for the case where a stack buffer cannot be
created and use uma_zone_t kenv_zone for suitably sized buffers.
r364443: veloader: insist on verifying .4th .lua etc
When files are read from .rc or .4th, verify_file is asked to
guess the severity (VE_TRY,VE_WANT,VE_MUST)
Reviewed by: imp, stevek, kevans
Modified:
stable/12/lib/libsecureboot/verify_file.c
stable/12/stand/common/install.c
stable/12/stand/uboot/lib/net.c
stable/12/sys/kern/kern_environment.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/lib/libsecureboot/verify_file.c
==============================================================================
--- stable/12/lib/libsecureboot/verify_file.c Sat Aug 29 16:04:02 2020 (r364960)
+++ stable/12/lib/libsecureboot/verify_file.c Sat Aug 29 16:23:00 2020 (r364961)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2017-2018, Juniper Networks, Inc.
+ * Copyright (c) 2017-2020, Juniper Networks, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <string.h>
#include <sys/queue.h>
+#include <sys/kenv.h>
#include "libsecureboot.h"
#include <verify_file.h>
@@ -254,6 +255,10 @@ severity_guess(const char *filename)
strcmp(cp, ".cookie") == 0 ||
strcmp(cp, ".hints") == 0)
return (VE_TRY);
+ if (strcmp(cp, ".4th") == 0 ||
+ strcmp(cp, ".lua") == 0 ||
+ strcmp(cp, ".rc") == 0)
+ return (VE_MUST);
}
return (VE_WANT);
}
@@ -532,6 +537,19 @@ verify_pcr_export(void)
DEBUG_PRINTF(1,
("%s: setenv(loader.ve.hashed, %s\n",
__func__, hinfo));
+ if ((hlen = strlen(hinfo)) > KENV_MVALLEN) {
+ /*
+ * bump kenv_mvallen
+ * roundup to multiple of KENV_MVALLEN
+ */
+ char mvallen[16];
+
+ hlen += KENV_MVALLEN -
+ (hlen % KENV_MVALLEN);
+ if (snprintf(mvallen, sizeof(mvallen),
+ "%d", (int) hlen) < sizeof(mvallen))
+ setenv("kenv_mvallen", mvallen, 1);
+ }
free(hinfo);
}
}
Modified: stable/12/stand/common/install.c
==============================================================================
--- stable/12/stand/common/install.c Sat Aug 29 16:04:02 2020 (r364960)
+++ stable/12/stand/common/install.c Sat Aug 29 16:23:00 2020 (r364961)
@@ -184,7 +184,8 @@ cleanup(void)
/*
* usage: install URL
- * where: URL = (tftp|file)://[host]/<package>
+ * where: URL = tftp://[host]/<package>
+ * or file://[devname[:fstype]]/<package>
*/
static int
install(char *pkgname)
@@ -192,8 +193,9 @@ install(char *pkgname)
static char buf[256];
struct fs_ops *proto;
struct preloaded_file *fp;
- char *s, *currdev;
- const char *devname;
+ char *e, *s, *currdev;
+ char *devname;
+ size_t devnamelen;
int error, fd, i, local;
s = strstr(pkgname, "://");
@@ -201,34 +203,74 @@ install(char *pkgname)
goto invalid_url;
i = s - pkgname;
+ s += 3;
+ if (*s == '\0')
+ goto invalid_url;
+
+ devname = NULL;
+ devnamelen = 0;
+ proto = NULL;
+ local = 0;
+
if (i == 4 && !strncasecmp(pkgname, "tftp", i)) {
devname = "net0";
+ devnamelen = 4;
proto = &tftp_fsops;
- local = 0;
} else if (i == 4 && !strncasecmp(pkgname, "file", i)) {
currdev = getenv("currdev");
- if (currdev != NULL && strcmp(currdev, "pxe0:") == 0) {
- devname = "pxe0";
- proto = NULL;
+ local = 1;
+
+ if (*s == '/') { /* file:/// */
+ if (devname == NULL)
+ devname = currdev;
+ if (devname == NULL)
+ devname = "disk1";
+ } else { /* file://devname[:fstype]/ */
+ devname = s;
+ e = strchr(devname, '/');
+ if (!e)
+ goto invalid_url;
+ devnamelen = e - devname;
+ s = e; /* consume devname */
+ }
+ if ((e = strchr(devname, ':')) != NULL) {
+ /* could be :fstype */
+ devnamelen = e - devname;
+ switch (e[1]) {
+ case '\0': /* just currdev */
+ break;
+ case 'd':
+ proto = &dosfs_fsops;
+ break;
#ifdef HOSTPROG
- } else if (currdev != NULL && strcmp(currdev, "host0:") == 0) {
- extern struct fs_ops host_fsops;
+ case 'h':
+ {
+ extern struct fs_ops host_fsops;
- devname = "host0";
- proto = &host_fsops;
+ proto = &host_fsops;
+ }
+ break;
#endif
- } else {
- devname = "disk1";
+ case 'u':
+ proto = &ufs_fsops;
+ break;
+ }
+ }
+ if (proto == NULL && strncmp(devname, "disk", 4) == 0) {
proto = &dosfs_fsops;
}
- local = 1;
- } else
- goto invalid_url;
+ }
- s += 3;
- if (*s == '\0')
+ if (devname == NULL)
goto invalid_url;
+ if (devnamelen == 0) {
+ /* default is currdev which ends with ':' */
+ devnamelen = strlen(devname);
+ if (devname[devnamelen - 1] == ':')
+ devnamelen--;
+ }
+
if (*s != '/' ) {
if (local)
goto invalid_url;
@@ -252,11 +294,12 @@ install(char *pkgname)
} else
pkgname = s;
- if (strlen(devname) + strlen(pkgname) + 2 > sizeof(buf)) {
+ i = snprintf(buf, sizeof(buf), "%.*s:%s",
+ (int) devnamelen, devname, pkgname);
+ if (i >= (int) sizeof(buf)) {
command_errmsg = "package name too long";
return (CMD_ERROR);
}
- sprintf(buf, "%s:%s", devname, pkgname);
setenv("install_package", buf, 1);
error = pkgfs_init(buf, proto);
Modified: stable/12/stand/uboot/lib/net.c
==============================================================================
--- stable/12/stand/uboot/lib/net.c Sat Aug 29 16:04:02 2020 (r364960)
+++ stable/12/stand/uboot/lib/net.c Sat Aug 29 16:23:00 2020 (r364961)
@@ -187,7 +187,7 @@ get_env_net_params()
rootip.s_addr = 0;
return;
}
- if ((gateip.s_addr = inet_addr(envstr) == INADDR_NONE)) {
+ if ((gateip.s_addr = inet_addr(envstr)) == INADDR_NONE) {
printf("Could not parse gatewayip '%s'\n", envstr);
rootip.s_addr = 0;
return;
Modified: stable/12/sys/kern/kern_environment.c
==============================================================================
--- stable/12/sys/kern/kern_environment.c Sat Aug 29 16:04:02 2020 (r364960)
+++ stable/12/sys/kern/kern_environment.c Sat Aug 29 16:23:00 2020 (r364961)
@@ -63,6 +63,9 @@ static MALLOC_DEFINE(M_KENV, "kenv", "kernel environme
#define KENV_SIZE 512 /* Maximum number of environment strings */
+static uma_zone_t kenv_zone;
+static int kenv_mvallen = KENV_MVALLEN;
+
/* pointer to the config-generated static environment */
char *kern_envp;
@@ -85,6 +88,8 @@ bool dynamic_kenv;
#define KENV_CHECK if (!dynamic_kenv) \
panic("%s: called before SI_SUB_KMEM", __func__)
+static char *getenv_string_buffer(const char *);
+
int
sys_kenv(td, uap)
struct thread *td;
@@ -110,9 +115,9 @@ sys_kenv(td, uap)
#endif
done = needed = 0;
buflen = uap->len;
- if (buflen > KENV_SIZE * (KENV_MNAMELEN + KENV_MVALLEN + 2))
+ if (buflen > KENV_SIZE * (KENV_MNAMELEN + kenv_mvallen + 2))
buflen = KENV_SIZE * (KENV_MNAMELEN +
- KENV_MVALLEN + 2);
+ kenv_mvallen + 2);
if (uap->len > 0 && uap->value != NULL)
buffer = malloc(buflen, M_TEMP, M_WAITOK|M_ZERO);
mtx_lock(&kenv_lock);
@@ -185,8 +190,8 @@ sys_kenv(td, uap)
error = EINVAL;
goto done;
}
- if (len > KENV_MVALLEN + 1)
- len = KENV_MVALLEN + 1;
+ if (len > kenv_mvallen + 1)
+ len = kenv_mvallen + 1;
value = malloc(len, M_TEMP, M_WAITOK);
error = copyinstr(uap->value, value, len, NULL);
if (error) {
@@ -327,7 +332,7 @@ init_dynamic_kenv_from(char *init_env, int *curpos)
for (cp = init_env; cp != NULL; cp = cpnext) {
cpnext = kernenv_next(cp);
len = strlen(cp) + 1;
- if (len > KENV_MNAMELEN + 1 + KENV_MVALLEN + 1) {
+ if (len > KENV_MNAMELEN + 1 + kenv_mvallen + 1) {
printf(
"WARNING: too long kenv string, ignoring %s\n",
cp);
@@ -375,7 +380,14 @@ static void
init_dynamic_kenv(void *data __unused)
{
int dynamic_envpos;
+ int size;
+ TUNABLE_INT_FETCH("kenv_mvallen", &kenv_mvallen);
+ size = KENV_MNAMELEN + 1 + kenv_mvallen + 1;
+
+ kenv_zone = uma_zcreate("kenv", size, NULL, NULL, NULL, NULL,
+ UMA_ALIGN_PTR, 0);
+
kenvp = malloc((KENV_SIZE + 1) * sizeof(char *), M_KENV,
M_WAITOK | M_ZERO);
@@ -395,7 +407,7 @@ freeenv(char *env)
if (dynamic_kenv && env != NULL) {
explicit_bzero(env, strlen(env));
- free(env, M_KENV);
+ uma_zfree(kenv_zone, env);
}
}
@@ -470,14 +482,11 @@ _getenv_static(const char *name)
char *
kern_getenv(const char *name)
{
- char buf[KENV_MNAMELEN + 1 + KENV_MVALLEN + 1];
char *ret;
if (dynamic_kenv) {
- if (getenv_string(name, buf, sizeof(buf))) {
- ret = strdup(buf, M_KENV);
- } else {
- ret = NULL;
+ ret = getenv_string_buffer(name);
+ if (ret == NULL) {
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
"getenv");
}
@@ -548,7 +557,7 @@ kern_setenv(const char *name, const char *value)
if (namelen > KENV_MNAMELEN + 1)
return (-1);
vallen = strlen(value) + 1;
- if (vallen > KENV_MVALLEN + 1)
+ if (vallen > kenv_mvallen + 1)
return (-1);
buf = malloc(namelen + vallen, M_KENV, M_WAITOK);
sprintf(buf, "%s=%s", name, value);
@@ -607,6 +616,33 @@ kern_unsetenv(const char *name)
}
/*
+ * Return a buffer containing the string value from an environment variable
+ */
+static char *
+getenv_string_buffer(const char *name)
+{
+ char *cp, *ret;
+ int len;
+
+ if (dynamic_kenv) {
+ len = KENV_MNAMELEN + 1 + kenv_mvallen + 1;
+ ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO);
+ mtx_lock(&kenv_lock);
+ cp = _getenv_dynamic(name, NULL);
+ if (cp != NULL)
+ strlcpy(ret, cp, len);
+ mtx_unlock(&kenv_lock);
+ if (cp == NULL) {
+ uma_zfree(kenv_zone, ret);
+ ret = NULL;
+ }
+ } else
+ ret = _getenv_static(name);
+
+ return (ret);
+}
+
+/*
* Return a string value from an environment variable.
*/
int
@@ -635,17 +671,19 @@ int
getenv_array(const char *name, void *pdata, int size, int *psize,
int type_size, bool allow_signed)
{
- char buf[KENV_MNAMELEN + 1 + KENV_MVALLEN + 1];
uint8_t shift;
int64_t value;
int64_t old;
+ char *buf;
char *end;
char *ptr;
int n;
+ int rc;
- if (getenv_string(name, buf, sizeof(buf)) == 0)
+ if ((buf = getenv_string_buffer(name)) == NULL)
return (0);
+ rc = 0; /* assume failure */
/* get maximum number of elements */
size /= type_size;
@@ -758,9 +796,11 @@ getenv_array(const char *name, void *pdata, int size,
*psize = n * type_size;
if (n != 0)
- return (1); /* success */
+ rc = 1; /* success */
error:
- return (0); /* failure */
+ if (dynamic_kenv)
+ uma_zfree(kenv_zone, buf);
+ return (rc);
}
/*
@@ -859,15 +899,17 @@ getenv_ulong(const char *name, unsigned long *data)
int
getenv_quad(const char *name, quad_t *data)
{
- char value[KENV_MNAMELEN + 1 + KENV_MVALLEN + 1];
- char *vtp;
+ char *value, *vtp;
quad_t iv;
- if (!getenv_string(name, value, sizeof(value)))
+ value = getenv_string_buffer(name);
+ if (value == NULL)
return (0);
iv = strtoq(value, &vtp, 0);
- if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0'))
+ if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
+ freeenv(value);
return (0);
+ }
switch (vtp[0]) {
case 't': case 'T':
iv *= 1024;
@@ -883,8 +925,10 @@ getenv_quad(const char *name, quad_t *data)
case '\0':
break;
default:
+ freeenv(value);
return (0);
}
+ freeenv(value);
*data = iv;
return (1);
}
More information about the svn-src-stable-12
mailing list