Allow kernel with the BOOTP option to boot when DHCP/BOOTP sets the root

path to an absolute path without a host name.  Previously, there was a
nasty POLA violation where a system would PXE boot until you added the
BOOTP option and then it would panic instead.

Reviewed by:	tegge, Dirk-Willem van Gulik <dirkx at webweaving.org>
		(a previous version)
Submitted by:	tegge (getip function)
This commit is contained in:
Brooks Davis 2004-03-12 20:37:40 +00:00
parent db322c7eba
commit 41b7cd3729
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=126888

View File

@ -216,8 +216,10 @@ SYSCTL_STRING(_kern, OID_AUTO, bootp_cookie, CTLFLAG_RD,
/* mountd RPC */
static int md_mount(struct sockaddr_in *mdsin, char *path, u_char *fhp,
int *fhsizep, struct nfs_args *args, struct thread *td);
static int setfs(struct sockaddr_in *addr, char *path, char *p);
static int setfs(struct sockaddr_in *addr, char *path, char *p,
const struct in_addr *siaddr);
static int getdec(char **ptr);
static int getip(char **ptr, struct in_addr *ip);
static char *substr(char *a, char *b);
static void mountopts(struct nfs_args *args, char *p);
static int xdr_opaque_decode(struct mbuf **ptr, u_char *buf, int len);
@ -1157,11 +1159,36 @@ bootpc_adjust_interface(struct bootpc_ifcontext *ifctx,
}
static int
setfs(struct sockaddr_in *addr, char *path, char *p)
setfs(struct sockaddr_in *addr, char *path, char *p,
const struct in_addr *siaddr)
{
if (getip(&p, &addr->sin_addr) == 0) {
if (siaddr != NULL && *p == '/')
bcopy(siaddr, &addr->sin_addr, sizeof(struct in_addr));
else
return 0;
} else {
if (*p != ':')
return 0;
p++;
}
addr->sin_len = sizeof(struct sockaddr_in);
addr->sin_family = AF_INET;
strlcpy(path, p, MNAMELEN);
return 1;
}
static int
getip(char **ptr, struct in_addr *addr)
{
char *p;
unsigned int ip;
int val;
p = *ptr;
ip = 0;
if (((val = getdec(&p)) < 0) || (val > 255))
return 0;
@ -1184,15 +1211,9 @@ setfs(struct sockaddr_in *addr, char *path, char *p)
if (((val = getdec(&p)) < 0) || (val > 255))
return 0;
ip |= val;
if (*p != ':')
return 0;
p++;
addr->sin_addr.s_addr = htonl(ip);
addr->sin_len = sizeof(struct sockaddr_in);
addr->sin_family = AF_INET;
strncpy(path, p, MNAMELEN - 1);
addr->s_addr = htonl(ip);
*ptr = p;
return 1;
}
@ -1551,7 +1572,12 @@ bootpc_decode_reply(struct nfsv3_diskless *nd, struct bootpc_ifcontext *ifctx,
if (gctx->setrootfs != NULL) {
printf("rootfs %s (ignored) ", p);
} else if (setfs(&nd->root_saddr,
nd->root_hostnam, p)) {
nd->root_hostnam, p, &ifctx->reply.siaddr)) {
if (*p == '/') {
printf("root_server ");
print_sin_addr(&nd->root_saddr);
printf(" ");
}
printf("rootfs %s ", p);
gctx->gotrootpath = 1;
ifctx->gotrootpath = 1;