Page MenuHomeFreeBSD

D51187.id158075.diff
No OneTemporary

D51187.id158075.diff

diff --git a/stand/common/dev_net.c b/stand/common/dev_net.c
--- a/stand/common/dev_net.c
+++ b/stand/common/dev_net.c
@@ -63,11 +63,15 @@
#include <bootp.h>
#include <bootparam.h>
+#ifdef NETIF_DEBUG
+# define _DEBUG_LEVEL NETIF_DEBUG
+#endif
+
#include "dev_net.h"
#include "bootstrap.h"
-#ifdef NETIF_DEBUG
-int debug = 0;
+#ifndef NETPROTO_DEFAULT
+# define NETPROTO_DEFAULT NET_NFS
#endif
static char *netdev_name;
@@ -143,11 +147,8 @@
return (ENXIO);
}
netdev_name = strdup(devname);
-#ifdef NETIF_DEBUG
- if (debug)
- printf("%s: netif_open() succeeded\n",
- __func__);
-#endif
+ DEBUG_PRINTF(1,("%s: netif_open() succeeded %#x\n",
+ __func__, rootip.s_addr));
}
/*
* If network params were not set by netif_open(), try to get
@@ -200,10 +201,7 @@
{
struct devdesc *dev;
-#ifdef NETIF_DEBUG
- if (debug)
- printf("%s: opens=%d\n", __func__, netdev_opens);
-#endif
+ DEBUG_PRINTF(1,("%s: opens=%d\n", __func__, netdev_opens));
dev = f->f_devdata;
dev->d_opendata = NULL;
@@ -216,10 +214,7 @@
{
if (netdev_sock >= 0) {
-#ifdef NETIF_DEBUG
- if (debug)
- printf("%s: calling netif_close()\n", __func__);
-#endif
+ DEBUG_PRINTF(1,("%s: calling netif_close()\n", __func__));
rootip.s_addr = 0;
free(netdev_name);
netif_close(netdev_sock);
@@ -271,10 +266,7 @@
bootp(sock);
if (myip.s_addr != 0)
goto exit;
-#ifdef NETIF_DEBUG
- if (debug)
- printf("%s: BOOTP failed, trying RARP/RPC...\n", __func__);
-#endif
+ DEBUG_PRINTF(1,("%s: BOOTP failed, trying RARP/RPC...\n", __func__));
#endif
/*
@@ -292,10 +284,7 @@
printf("%s: bootparam/whoami RPC failed\n", __func__);
return (EIO);
}
-#ifdef NETIF_DEBUG
- if (debug)
- printf("%s: client name: %s\n", __func__, hostname);
-#endif
+ DEBUG_PRINTF(1,("%s: client name: %s\n", __func__, hostname));
/*
* Ignore the gateway from whoami (unreliable).
@@ -309,16 +298,12 @@
}
if (smask) {
netmask = smask;
-#ifdef NETIF_DEBUG
- if (debug)
- printf("%s: subnet mask: %s\n", __func__,
- intoa(netmask));
-#endif
+ DEBUG_PRINTF(1,("%s: subnet mask: %s\n", __func__,
+ intoa(netmask)));
}
-#ifdef NETIF_DEBUG
- if (gateip.s_addr && debug)
- printf("%s: net gateway: %s\n", __func__, inet_ntoa(gateip));
-#endif
+ if (gateip.s_addr)
+ DEBUG_PRINTF(1,("%s: net gateway: %s\n", __func__,
+ inet_ntoa(gateip)));
/* Get the root server and pathname. */
if (bp_getfile(sock, "root", &rootip, rootpath)) {
@@ -326,15 +311,13 @@
return (EIO);
}
exit:
- if ((rootaddr = net_parse_rootpath()) != INADDR_NONE)
+ if ((rootaddr = net_parse_rootpath()) != htonl(INADDR_NONE))
rootip.s_addr = rootaddr;
-#ifdef NETIF_DEBUG
- if (debug) {
- printf("%s: server addr: %s\n", __func__, inet_ntoa(rootip));
- printf("%s: server path: %s\n", __func__, rootpath);
- }
-#endif
+ DEBUG_PRINTF(1,("%s: proto: %d\n", __func__, netproto));
+ DEBUG_PRINTF(1,("%s: server addr: %s\n", __func__, inet_ntoa(rootip)));
+ DEBUG_PRINTF(1,("%s: server port: %d\n", __func__, rootport));
+ DEBUG_PRINTF(1,("%s: server path: %s\n", __func__, rootpath));
return (0);
}
@@ -373,7 +356,7 @@
* Parses the rootpath if present
*
* The rootpath format can be in the form
- * <scheme>://ip/path
+ * <scheme>://ip[:port]/path
* <scheme>:/path
*
* For compatibility with previous behaviour it also accepts as an NFS scheme
@@ -388,10 +371,10 @@
uint32_t
net_parse_rootpath(void)
{
- n_long addr = htonl(INADDR_NONE);
+ n_long addr = 0;
size_t i;
char ip[FNAME_SIZE];
- char *ptr, *val;
+ char *ptr, *portp, *val;
netproto = NET_NONE;
@@ -406,10 +389,12 @@
ptr = rootpath;
/* Fallback for compatibility mode */
if (netproto == NET_NONE) {
- netproto = NET_NFS;
+ netproto = NETPROTO_DEFAULT;
(void)strsep(&ptr, ":");
if (ptr != NULL) {
addr = inet_addr(rootpath);
+ DEBUG_PRINTF(1,("rootpath=%s addr=%#x\n",
+ rootpath, addr));
bcopy(ptr, rootpath, strlen(ptr) + 1);
}
} else {
@@ -417,16 +402,21 @@
if (*ptr == '/') {
/* we are in the form <scheme>://, we do expect an ip */
ptr++;
- /*
- * XXX when http will be there we will need to check for
- * a port, but right now we do not need it yet
- */
+ portp = val = strchr(ptr, ':');
+ if (val != NULL) {
+ val++;
+ rootport = strtol(val, NULL, 10);
+ }
val = strchr(ptr, '/');
if (val != NULL) {
+ if (portp == NULL)
+ portp = val;
snprintf(ip, sizeof(ip), "%.*s",
- (int)((uintptr_t)val - (uintptr_t)ptr),
+ (int)((uintptr_t)portp - (uintptr_t)ptr),
ptr);
addr = inet_addr(ip);
+ DEBUG_PRINTF(1,("ip=%s addr=%#x\n",
+ ip, addr));
bcopy(val, rootpath, strlen(val) + 1);
}
} else {
@@ -434,6 +424,7 @@
bcopy(ptr, rootpath, strlen(ptr) + 1);
}
}
-
+ if (addr == 0)
+ addr = htonl(INADDR_NONE);
return (addr);
}
diff --git a/stand/common/install.c b/stand/common/install.c
--- a/stand/common/install.c
+++ b/stand/common/install.c
@@ -137,7 +137,9 @@
}
*p++ = '\0';
- if (strcmp(tag, "KERNEL") == 0)
+ if (strncmp(tag, "ENV_", 4) == 0)
+ setenv(&tag[4], val, 1);
+ else if (strcmp(tag, "KERNEL") == 0)
error = setpath(&inst_kernel, val);
else if (strcmp(tag, "MODULES") == 0)
error = setmultipath(&inst_modules, val);
@@ -288,6 +290,9 @@
} else
pkgname = s;
+ if (proto == NULL && netproto == NET_TFTP) {
+ proto = &tftp_fsops;
+ }
i = snprintf(buf, sizeof(buf), "%.*s:%s",
(int) devnamelen, devname, pkgname);
if (i >= (int) sizeof(buf)) {
diff --git a/stand/common/misc.c b/stand/common/misc.c
--- a/stand/common/misc.c
+++ b/stand/common/misc.c
@@ -199,8 +199,12 @@
if ((rv = devparse(&ncurr, value, NULL)) != 0)
return (rv);
+ rv = (ncurr->d_dev->dv_type == DEVT_NET);
free(ncurr);
-
+ if (rv != 0) {
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return (0);
+ }
return (mount_currdev(ev, flags, value));
}
diff --git a/stand/defs.mk b/stand/defs.mk
--- a/stand/defs.mk
+++ b/stand/defs.mk
@@ -207,6 +207,8 @@
# Make sure we use the machine link we're about to create
CFLAGS+=-I.
+.include "${BOOTSRC}/veriexec.mk"
+
all: ${PROG}
CLEANFILES+= teken_state.h
diff --git a/stand/libsa/globals.c b/stand/libsa/globals.c
--- a/stand/libsa/globals.c
+++ b/stand/libsa/globals.c
@@ -17,6 +17,7 @@
u_char bcea[6] = BA; /* broadcast ethernet address */
char rootpath[FNAME_SIZE] = "/"; /* root mount path */
+int rootport = 0; /* port for rootpath server */
char bootfile[FNAME_SIZE]; /* bootp says to boot this */
char hostname[FNAME_SIZE]; /* our hostname */
int hostnamelen;
diff --git a/stand/libsa/net.h b/stand/libsa/net.h
--- a/stand/libsa/net.h
+++ b/stand/libsa/net.h
@@ -75,6 +75,7 @@
extern u_char bcea[6];
extern char rootpath[FNAME_SIZE];
+extern int rootport;
extern char bootfile[FNAME_SIZE];
extern char hostname[FNAME_SIZE];
extern int hostnamelen;
diff --git a/stand/libsa/open.c b/stand/libsa/open.c
--- a/stand/libsa/open.c
+++ b/stand/libsa/open.c
@@ -155,8 +155,15 @@
file = NULL;
if (exclusive_file_system != NULL) {
+ /* loader is forcing the filesystem to be used */
fs = exclusive_file_system;
- error = (fs->fo_open)(fname, f);
+ /* only skip devopen for pkgfs */
+ if (fs != &pkgfs_fsops)
+ error = devopen(f, fname, &file);
+ else
+ error = 0, file = fname;
+ if (error == 0)
+ error = (fs->fo_open)(file, f);
if (error == 0)
goto ok;
goto err;
diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h
--- a/stand/libsa/stand.h
+++ b/stand/libsa/stand.h
@@ -558,4 +558,14 @@
__END_DECLS
+/* define _DEBUG_LEVEL n before include */
+#ifndef DEBUG_PRINTF
+#ifdef _DEBUG_LEVEL
+static int _debug = _DEBUG_LEVEL;
+# define DEBUG_PRINTF(n, args) if (_debug >= n) printf args
+#else
+# define DEBUG_PRINTF(n, args)
+#endif
+#endif
+
#endif /* STAND_H */
diff --git a/stand/libsa/tftp.c b/stand/libsa/tftp.c
--- a/stand/libsa/tftp.c
+++ b/stand/libsa/tftp.c
@@ -50,8 +50,14 @@
#include <netinet/in_systm.h>
#include <arpa/tftp.h>
+#ifdef LOADER_VERIEXEC
+#include <verify_file.h>
+#endif
+
#include <string.h>
+//#define _DEBUG_LEVEL 3
+
#include "stand.h"
#include "net.h"
#include "netif.h"
@@ -84,7 +90,6 @@
};
static int tftpport = 2000;
-static int is_open = 0;
/*
* The legacy TFTP_BLKSIZE value was SEGSIZE(512).
@@ -98,10 +103,14 @@
* Jumbo frames in the future.
*/
#define TFTP_MAX_BLKSIZE 9008
-#define TFTP_TRIES 2
+#define TFTP_TRIES 3
struct tftp_handle {
struct iodesc *iodesc;
+ struct iodesc io;
+ int id;
+ ino_t ino;
+ int port;
int currblock; /* contents of lastdata */
unsigned int islastblock:1; /* flag */
unsigned int tries:4; /* number of read attempts */
@@ -177,6 +186,9 @@
wbuf.t.th_block = htons(block);
wtail += 2;
+ DEBUG_PRINTF(5,("%s: myport=%hu xid=%lu, block=%hu\n",
+ __func__, h->iodesc->myport, h->iodesc->xid, block));
+
sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t);
}
@@ -190,6 +202,7 @@
void *ptr = NULL;
ssize_t len;
int tftp_error;
+ unsigned short block;
errno = 0;
extra = recv_extra;
@@ -203,19 +216,22 @@
}
extra->rtype = ntohs(t->th_opcode);
- switch (ntohs(t->th_opcode)) {
+ block = ntohs(t->th_block);
+ DEBUG_PRINTF(6,("%s: myport=%hu xid=%lu, block=%hu, opcode=%hu\n",
+ __func__, d->myport, d->xid, block, extra->rtype));
+ switch (extra->rtype) {
case DATA: {
int got;
- if (htons(t->th_block) < (u_short)d->xid) {
+ if (block < (u_short)d->xid) {
/*
* Apparently our ACK was missed, re-send.
*/
- tftp_sendack(h, htons(t->th_block));
+ tftp_sendack(h, block);
free(ptr);
return (-1);
}
- if (htons(t->th_block) != (u_short)d->xid) {
+ if (block != (u_short)d->xid) {
/*
* Packet from the future, drop this.
*/
@@ -241,9 +257,7 @@
printf("illegal tftp error %d\n", tftp_error);
errno = EIO;
} else {
-#ifdef TFTP_DEBUG
- printf("tftp-error %d\n", tftp_error);
-#endif
+ DEBUG_PRINTF(0, ("tftp-error %d\n", tftp_error));
errno = tftperrors[tftp_error];
}
free(ptr);
@@ -284,9 +298,7 @@
return (0);
}
default:
-#ifdef TFTP_DEBUG
- printf("tftp type %d not handled\n", ntohs(t->th_opcode));
-#endif
+ DEBUG_PRINTF(0, ("tftp type %hu not handled\n", extra->rtype));
free(ptr);
return (-1);
}
@@ -343,7 +355,7 @@
bcopy("0", wtail, 2);
wtail += 2;
- h->iodesc->myport = htons(tftpport + (getsecs() & 0x3ff));
+ h->iodesc->myport = htons(h->port + (getsecs() & 0x3ff));
h->iodesc->destport = htons(IPPORT_TFTP);
h->iodesc->xid = 1; /* expected block */
@@ -351,11 +363,15 @@
h->islastblock = 0;
h->validsize = 0;
+ DEBUG_PRINTF(5,("%s: %s: id=%d port=%d myport=%hu xid=1\n",
+ __func__, h->path, h->id, h->port, ntohs(h->iodesc->myport)));
pkt = NULL;
recv_extra.tftp_handle = h;
res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *)&wbuf.t,
&recvtftp, &pkt, (void **)&t, &recv_extra);
if (res == -1) {
+ DEBUG_PRINTF(3,("%s: %s: id=%d errno=%d\n",
+ __func__, h->path, h->id, errno));
free(pkt);
return (errno);
}
@@ -410,12 +426,18 @@
h->iodesc->xid = h->currblock + 1; /* expected block */
+ DEBUG_PRINTF(5,("%s: %s: id=%d port=%d myport=%hu xid=%lu\n",
+ __func__, h->path, h->id, h->port,
+ ntohs(h->iodesc->myport), h->iodesc->xid));
+
pkt = NULL;
recv_extra.tftp_handle = h;
res = sendrecv(h->iodesc, &sendudp, &wbuf.t, wtail - (char *)&wbuf.t,
&recvtftp, &pkt, (void **)&t, &recv_extra);
if (res == -1) { /* 0 is OK! */
+ DEBUG_PRINTF(3,("%s: %s: id=%d errno=%d\n",
+ __func__, h->path, h->id, errno));
free(pkt);
return (errno);
}
@@ -428,21 +450,32 @@
if (res < h->tftp_blksize)
h->islastblock = 1; /* EOF */
- if (h->islastblock == 1) {
+ DEBUG_PRINTF(5,("%s: %s: id=%d res=%d blksz=%d last=%d\n",
+ __func__, h->path, h->id, res, h->tftp_blksize, h->islastblock));
+
+ if (h->islastblock) {
/* Send an ACK for the last block */
- wbuf.t.th_block = htons((u_short)h->currblock);
- sendudp(h->iodesc, &wbuf.t, wtail - (char *)&wbuf.t);
+ tftp_sendack(h, h->currblock);
}
return (0);
}
+/*
+ * If doing verification we need to handle multiple
+ * files at the same time.
+ */
+#define TOPEN_MAX 8
+static struct tftp_handle *handles[TOPEN_MAX];
+
static int
tftp_open(const char *path, struct open_file *f)
{
struct devdesc *dev;
struct tftp_handle *tftpfile;
struct iodesc *io;
+ static int lx = 0;
+ int i, x;
int res;
size_t pathsize;
const char *extraslash;
@@ -450,24 +483,39 @@
if (netproto != NET_TFTP)
return (EINVAL);
- if (f->f_dev->dv_type != DEVT_NET)
+ if (f->f_dev == NULL || f->f_dev->dv_type != DEVT_NET)
return (EINVAL);
- if (is_open)
+ tftpfile = NULL;
+ for (x = lx + 1, i = 0; i < TOPEN_MAX; i++, x++) {
+ x %= TOPEN_MAX;
+ if (handles[x] == NULL) {
+ handles[x] = tftpfile = calloc(1, sizeof(*tftpfile));
+ if (tftpfile == NULL)
+ return (ENOMEM);
+ /* id allows us to clear the slot on close */
+ tftpfile->id = lx = x;
+ /* port ensures a different session with server */
+ tftpfile->port = (tftpport + (x * tftpport)) & 0xffff;
+ DEBUG_PRINTF(1, ("%s(%s) id=%d port=%d\n",
+ __func__, path, tftpfile->id, tftpfile->port));
+ break;
+ }
+ }
+ if (tftpfile == NULL) {
+ DEBUG_PRINTF(1, ("%s: EBUSY\n", __func__));
return (EBUSY);
-
- tftpfile = calloc(1, sizeof(*tftpfile));
- if (!tftpfile)
- return (ENOMEM);
-
+ }
tftpfile->tftp_blksize = TFTP_REQUESTED_BLKSIZE;
dev = f->f_devdata;
- tftpfile->iodesc = io = socktodesc(*(int *)(dev->d_opendata));
+ io = socktodesc(*(int *)(dev->d_opendata));
if (io == NULL) {
free(tftpfile);
return (EINVAL);
}
+ memcpy(&tftpfile->io, io, sizeof(tftpfile->io));
+ io = tftpfile->iodesc = &tftpfile->io;
io->destip = rootip;
tftpfile->off = 0;
pathsize = (strlen(rootpath) + 1 + strlen(path) + 1) * sizeof(char);
@@ -480,8 +528,11 @@
extraslash = "";
else
extraslash = "/";
- res = snprintf(tftpfile->path, pathsize, "%s%s%s",
- rootpath, extraslash, path);
+ if (rootpath[0] == '/' && rootpath[1] == '\0' && path[0] == '/')
+ res = strlcpy(tftpfile->path, path, pathsize);
+ else
+ res = snprintf(tftpfile->path, pathsize, "%s%s%s",
+ rootpath, extraslash, path);
if (res < 0 || res > pathsize) {
free(tftpfile->path);
free(tftpfile);
@@ -491,13 +542,13 @@
res = tftp_makereq(tftpfile);
if (res) {
+ handles[tftpfile->id] = NULL;
free(tftpfile->path);
free(tftpfile->pkt);
free(tftpfile);
return (res);
}
f->f_fsdata = tftpfile;
- is_open = 1;
return (0);
}
@@ -547,9 +598,7 @@
rc = tftp_getnextblock(tftpfile);
if (rc) { /* no answer */
-#ifdef TFTP_DEBUG
- printf("tftp: read error\n");
-#endif
+ DEBUG_PRINTF(0, ("tftp: read error\n"));
if (tftpfile->tries > TFTP_TRIES) {
return (rc);
} else {
@@ -568,10 +617,8 @@
inbuffer = tftpfile->validsize - offinblock;
if (inbuffer < 0) {
-#ifdef TFTP_DEBUG
- printf("tftp: invalid offset %d\n",
- tftpfile->off);
-#endif
+ DEBUG_PRINTF(0, ("tftp: invalid offset %d\n",
+ tftpfile->off));
return (EINVAL);
}
count = (size < inbuffer ? size : inbuffer);
@@ -586,15 +633,15 @@
if ((tftpfile->islastblock) && (count == inbuffer))
break; /* EOF */
} else {
-#ifdef TFTP_DEBUG
- printf("tftp: block %d not found\n", needblock);
-#endif
+ DEBUG_PRINTF(0, ("tftp: block %d not found\n", needblock));
return (EINVAL);
}
}
out:
+ DEBUG_PRINTF(4, ("%s(%s) res=%ld\n", __func__, tftpfile->path,
+ (tftpfile->tftp_tsize - tftpfile->off)));
if (resid != NULL)
*resid = res;
return (rc);
@@ -610,15 +657,18 @@
tftp_senderr(tftpfile, 0, "No error: file closed");
if (tftpfile) {
+ DEBUG_PRINTF(1, ("%s(%d): %s\n", __func__,
+ tftpfile->id, tftpfile->path));
+ handles[tftpfile->id] = NULL;
free(tftpfile->path);
free(tftpfile->pkt);
free(tftpfile->tftp_cache);
free(tftpfile);
}
- is_open = 0;
return (0);
}
+
static int
tftp_stat(struct open_file *f, struct stat *sb)
{
@@ -630,6 +680,29 @@
sb->st_uid = 0;
sb->st_gid = 0;
sb->st_size = tftpfile->tftp_tsize;
+ sb->st_mtime = 0;
+#ifdef LOADER_VERIEXEC
+ /* libsecureboot needs st_dev and st_ino at minimum;
+ * we need to fake something that will be close enough to
+ * unique.
+ */
+ sb->st_dev = (dev_t)tftpfile->iodesc->destip.s_addr;
+ /* we don't want to compute this more than once */
+ if (tftpfile->ino == 0) {
+ union {
+ unsigned char digest[SHA_DIGEST_LENGTH];
+ ino_t ino;
+ } u;
+
+ hash_string(tftpfile->path, 0, u.digest, sizeof(u.digest));
+
+ tftpfile->ino = u.ino & 0x7fffffff;
+ DEBUG_PRINTF(2,("%s(%s) dev=%lu ino=%lu\n", __func__,
+ tftpfile->path, (unsigned long)sb->st_dev,
+ (unsigned long)tftpfile->ino));
+ }
+ sb->st_ino = tftpfile->ino;
+#endif
return (0);
}
@@ -827,9 +900,7 @@
return (-1);
}
-#ifdef TFTP_DEBUG
- printf("tftp_blksize: %u\n", h->tftp_blksize);
- printf("tftp_tsize: %lu\n", h->tftp_tsize);
-#endif
+ DEBUG_PRINTF(2, ("tftp_blksize: %u\n", h->tftp_blksize));
+ DEBUG_PRINTF(2, ("tftp_tsize: %lu\n", h->tftp_tsize));
return (0);
}
diff --git a/stand/loader.mk b/stand/loader.mk
--- a/stand/loader.mk
+++ b/stand/loader.mk
@@ -101,8 +101,6 @@
.error Unknown interpreter ${LOADER_INTERP}
.endif
-.include "${BOOTSRC}/veriexec.mk"
-
.if defined(BOOT_PROMPT_123)
CFLAGS+= -DBOOT_PROMPT_123
.endif

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 15, 11:38 AM (13 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27648278
Default Alt Text
D51187.id158075.diff (17 KB)

Event Timeline