Fam Zheng (2):
slirp: Add sanity check for str option length slirp: Implement RFC2132 TFTP server name -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEM/p7ZGGVAfjOnI+X4/ZanpVg20wFAlvM054ACgkQ4/ZanpVg 20zDghAA251oTzggsGn3VOXE6SCSFdFcyvZNtJE7ytDN/4hKlTonorpJcK0sQGtR FV1t7TTLHzNESNpbpyMKOw685BXQ6HTDgaeriyA1Iz5I23/CNdE1aG9go4MumEtO HSNrnschjbnzjmxed1OEQ/EiEGMWQpuQR6I0d5jOTArJfTgm8dm5ggUjvIDQMoNF 7mEaxvdqxtxaXO9/7v6elrfYN7pLs/d6Zk4nJ44jo2BqCizrBkX+IRqnSHq55Zhp WeZeEC9DeQfzo2AzFjSiHiYFdxT7aQCEw8IHSl+rS1VFzigeL7DTqUkqSoA64pKv /jo9Eiy08wk3Ipz8WEAbchwK7WJpEOIlt/8o7Svl0arC6aiN1c/uRER1OjEn9j1L K4kKMOh6whwKh3dKuv7oYfG1pJcUrl/OnVFcCZOhr7DGYPjObk3yS7Ykr0wx8Qib aOn4THlfgC+yYFsjulKKGMZvfK8qxxI7vrTRoPEnUP0HgMPYjkvx0gs5QJe4b+Dz a6dBa4aqEaGw8297nE/pNV0wVVSzTaKg0dTK3DmceGY0dhHavMMROWg5zfNbnJ+Y r3mXjirhQwKWup72A42njZ2Mnt+KHjLzbOta25ItOatxlxN16jODslNPxdbcmKHh fsWUwBBmqoK4ecuO7isuRyLi0sgbTQX4qSx3iv0EfdZAQRbCbuo= =h1hQ -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault' into staging Fam Zheng (2): slirp: Add sanity check for str option length slirp: Implement RFC2132 TFTP server name # gpg: Signature made Sun 21 Oct 2018 20:29:34 BST # gpg: using RSA key E3F65A9E9560DB4C # gpg: Good signature from "Samuel Thibault <samuel.thibault@aquilenet.fr>" # gpg: aka "Samuel Thibault <sthibault@debian.org>" # gpg: aka "Samuel Thibault <samuel.thibault@gnu.org>" # gpg: aka "Samuel Thibault <samuel.thibault@inria.fr>" # gpg: aka "Samuel Thibault <samuel.thibault@labri.fr>" # gpg: aka "Samuel Thibault <samuel.thibault@ens-lyon.org>" # gpg: aka "Samuel Thibault <samuel.thibault@u-bordeaux.fr>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 900C B024 B679 31D4 0F82 304B D017 8C76 7D06 9EE6 # Subkey fingerprint: 33FA 7B64 6195 01F8 CE9C 8F97 E3F6 5A9E 9560 DB4C * remotes/thibault/tags/samuel-thibault: slirp: Implement RFC2132 TFTP server name slirp: Add sanity check for str option length Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
9b29b44e8e
21
net/slirp.c
21
net/slirp.c
|
@ -150,6 +150,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
|
||||||
const char *vnameserver, const char *vnameserver6,
|
const char *vnameserver, const char *vnameserver6,
|
||||||
const char *smb_export, const char *vsmbserver,
|
const char *smb_export, const char *vsmbserver,
|
||||||
const char **dnssearch, const char *vdomainname,
|
const char **dnssearch, const char *vdomainname,
|
||||||
|
const char *tftp_server_name,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
/* default settings according to historic slirp */
|
/* default settings according to historic slirp */
|
||||||
|
@ -350,6 +351,20 @@ static int net_slirp_init(NetClientState *peer, const char *model,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vdomainname && strlen(vdomainname) > 255) {
|
||||||
|
error_setg(errp, "'domainname' parameter cannot exceed 255 bytes");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vhostname && strlen(vhostname) > 255) {
|
||||||
|
error_setg(errp, "'vhostname' parameter cannot exceed 255 bytes");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tftp_server_name && strlen(tftp_server_name) > 255) {
|
||||||
|
error_setg(errp, "'tftp-server-name' parameter cannot exceed 255 bytes");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
|
nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
|
||||||
|
|
||||||
|
@ -361,7 +376,8 @@ static int net_slirp_init(NetClientState *peer, const char *model,
|
||||||
|
|
||||||
s->slirp = slirp_init(restricted, ipv4, net, mask, host,
|
s->slirp = slirp_init(restricted, ipv4, net, mask, host,
|
||||||
ipv6, ip6_prefix, vprefix6_len, ip6_host,
|
ipv6, ip6_prefix, vprefix6_len, ip6_host,
|
||||||
vhostname, tftp_export, bootfile, dhcp,
|
vhostname, tftp_server_name,
|
||||||
|
tftp_export, bootfile, dhcp,
|
||||||
dns, ip6_dns, dnssearch, vdomainname, s);
|
dns, ip6_dns, dnssearch, vdomainname, s);
|
||||||
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
|
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
|
||||||
|
|
||||||
|
@ -898,7 +914,8 @@ int net_init_slirp(const Netdev *netdev, const char *name,
|
||||||
user->ipv6_host, user->hostname, user->tftp,
|
user->ipv6_host, user->hostname, user->tftp,
|
||||||
user->bootfile, user->dhcpstart,
|
user->bootfile, user->dhcpstart,
|
||||||
user->dns, user->ipv6_dns, user->smb,
|
user->dns, user->ipv6_dns, user->smb,
|
||||||
user->smbserver, dnssearch, user->domainname, errp);
|
user->smbserver, dnssearch, user->domainname,
|
||||||
|
user->tftp_server_name, errp);
|
||||||
|
|
||||||
while (slirp_configs) {
|
while (slirp_configs) {
|
||||||
config = slirp_configs;
|
config = slirp_configs;
|
||||||
|
|
|
@ -174,6 +174,8 @@
|
||||||
#
|
#
|
||||||
# @guestfwd: forward guest TCP connections
|
# @guestfwd: forward guest TCP connections
|
||||||
#
|
#
|
||||||
|
# @tftp-server-name: RFC2132 "TFTP server name" string (Since 3.1)
|
||||||
|
#
|
||||||
# Since: 1.2
|
# Since: 1.2
|
||||||
##
|
##
|
||||||
{ 'struct': 'NetdevUserOptions',
|
{ 'struct': 'NetdevUserOptions',
|
||||||
|
@ -198,7 +200,8 @@
|
||||||
'*smb': 'str',
|
'*smb': 'str',
|
||||||
'*smbserver': 'str',
|
'*smbserver': 'str',
|
||||||
'*hostfwd': ['String'],
|
'*hostfwd': ['String'],
|
||||||
'*guestfwd': ['String'] } }
|
'*guestfwd': ['String'],
|
||||||
|
'*tftp-server-name': 'str' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @NetdevTapOptions:
|
# @NetdevTapOptions:
|
||||||
|
|
|
@ -1823,7 +1823,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
|
||||||
" [,ipv6[=on|off]][,ipv6-net=addr[/int]][,ipv6-host=addr]\n"
|
" [,ipv6[=on|off]][,ipv6-net=addr[/int]][,ipv6-host=addr]\n"
|
||||||
" [,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
|
" [,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
|
||||||
" [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,domainname=domain]\n"
|
" [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,domainname=domain]\n"
|
||||||
" [,tftp=dir][,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
|
" [,tftp=dir][,tftp-server-name=name][,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
"[,smb=dir[,smbserver=addr]]\n"
|
"[,smb=dir[,smbserver=addr]]\n"
|
||||||
#endif
|
#endif
|
||||||
|
@ -2060,6 +2060,11 @@ server. The files in @var{dir} will be exposed as the root of a TFTP server.
|
||||||
The TFTP client on the guest must be configured in binary mode (use the command
|
The TFTP client on the guest must be configured in binary mode (use the command
|
||||||
@code{bin} of the Unix TFTP client).
|
@code{bin} of the Unix TFTP client).
|
||||||
|
|
||||||
|
@item tftp-server-name=@var{name}
|
||||||
|
In BOOTP reply, broadcast @var{name} as the "TFTP server name" (RFC2132 option
|
||||||
|
66). This can be used to advise the guest to load boot files or configurations
|
||||||
|
from a different server than the host address.
|
||||||
|
|
||||||
@item bootfile=@var{file}
|
@item bootfile=@var{file}
|
||||||
When using the user mode network stack, broadcast @var{file} as the BOOTP
|
When using the user mode network stack, broadcast @var{file} as the BOOTP
|
||||||
filename. In conjunction with @option{tftp}, this can be used to network boot
|
filename. In conjunction with @option{tftp}, this can be used to network boot
|
||||||
|
|
|
@ -159,6 +159,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
|
||||||
struct in_addr preq_addr;
|
struct in_addr preq_addr;
|
||||||
int dhcp_msg_type, val;
|
int dhcp_msg_type, val;
|
||||||
uint8_t *q;
|
uint8_t *q;
|
||||||
|
uint8_t *end;
|
||||||
uint8_t client_ethaddr[ETH_ALEN];
|
uint8_t client_ethaddr[ETH_ALEN];
|
||||||
|
|
||||||
/* extract exact DHCP msg type */
|
/* extract exact DHCP msg type */
|
||||||
|
@ -240,6 +241,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
|
||||||
rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
|
rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
|
||||||
|
|
||||||
q = rbp->bp_vend;
|
q = rbp->bp_vend;
|
||||||
|
end = (uint8_t *)&rbp[1];
|
||||||
memcpy(q, rfc1533_cookie, 4);
|
memcpy(q, rfc1533_cookie, 4);
|
||||||
q += 4;
|
q += 4;
|
||||||
|
|
||||||
|
@ -292,24 +294,46 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
|
||||||
|
|
||||||
if (*slirp->client_hostname) {
|
if (*slirp->client_hostname) {
|
||||||
val = strlen(slirp->client_hostname);
|
val = strlen(slirp->client_hostname);
|
||||||
*q++ = RFC1533_HOSTNAME;
|
if (q + val + 2 >= end) {
|
||||||
*q++ = val;
|
g_warning("DHCP packet size exceeded, "
|
||||||
memcpy(q, slirp->client_hostname, val);
|
"omitting host name option.");
|
||||||
q += val;
|
} else {
|
||||||
|
*q++ = RFC1533_HOSTNAME;
|
||||||
|
*q++ = val;
|
||||||
|
memcpy(q, slirp->client_hostname, val);
|
||||||
|
q += val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slirp->vdomainname) {
|
if (slirp->vdomainname) {
|
||||||
val = strlen(slirp->vdomainname);
|
val = strlen(slirp->vdomainname);
|
||||||
*q++ = RFC1533_DOMAINNAME;
|
if (q + val + 2 >= end) {
|
||||||
*q++ = val;
|
g_warning("DHCP packet size exceeded, "
|
||||||
memcpy(q, slirp->vdomainname, val);
|
"omitting domain name option.");
|
||||||
q += val;
|
} else {
|
||||||
|
*q++ = RFC1533_DOMAINNAME;
|
||||||
|
*q++ = val;
|
||||||
|
memcpy(q, slirp->vdomainname, val);
|
||||||
|
q += val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slirp->tftp_server_name) {
|
||||||
|
val = strlen(slirp->tftp_server_name);
|
||||||
|
if (q + val + 2 >= end) {
|
||||||
|
g_warning("DHCP packet size exceeded, "
|
||||||
|
"omitting tftp-server-name option.");
|
||||||
|
} else {
|
||||||
|
*q++ = RFC2132_TFTP_SERVER_NAME;
|
||||||
|
*q++ = val;
|
||||||
|
memcpy(q, slirp->tftp_server_name, val);
|
||||||
|
q += val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slirp->vdnssearch) {
|
if (slirp->vdnssearch) {
|
||||||
size_t spaceleft = sizeof(rbp->bp_vend) - (q - rbp->bp_vend);
|
|
||||||
val = slirp->vdnssearch_len;
|
val = slirp->vdnssearch_len;
|
||||||
if (val + 1 > spaceleft) {
|
if (q + val >= end) {
|
||||||
g_warning("DHCP packet size exceeded, "
|
g_warning("DHCP packet size exceeded, "
|
||||||
"omitting domain-search option.");
|
"omitting domain-search option.");
|
||||||
} else {
|
} else {
|
||||||
|
@ -331,6 +355,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
|
||||||
memcpy(q, nak_msg, sizeof(nak_msg) - 1);
|
memcpy(q, nak_msg, sizeof(nak_msg) - 1);
|
||||||
q += sizeof(nak_msg) - 1;
|
q += sizeof(nak_msg) - 1;
|
||||||
}
|
}
|
||||||
|
assert(q < end);
|
||||||
*q = RFC1533_END;
|
*q = RFC1533_END;
|
||||||
|
|
||||||
daddr.sin_addr.s_addr = 0xffffffffu;
|
daddr.sin_addr.s_addr = 0xffffffffu;
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
#define RFC2132_MAX_SIZE 57
|
#define RFC2132_MAX_SIZE 57
|
||||||
#define RFC2132_RENEWAL_TIME 58
|
#define RFC2132_RENEWAL_TIME 58
|
||||||
#define RFC2132_REBIND_TIME 59
|
#define RFC2132_REBIND_TIME 59
|
||||||
|
#define RFC2132_TFTP_SERVER_NAME 66
|
||||||
|
|
||||||
#define DHCPDISCOVER 1
|
#define DHCPDISCOVER 1
|
||||||
#define DHCPOFFER 2
|
#define DHCPOFFER 2
|
||||||
|
|
|
@ -13,6 +13,7 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
|
||||||
bool in6_enabled,
|
bool in6_enabled,
|
||||||
struct in6_addr vprefix_addr6, uint8_t vprefix_len,
|
struct in6_addr vprefix_addr6, uint8_t vprefix_len,
|
||||||
struct in6_addr vhost6, const char *vhostname,
|
struct in6_addr vhost6, const char *vhostname,
|
||||||
|
const char *tftp_server_name,
|
||||||
const char *tftp_path, const char *bootfile,
|
const char *tftp_path, const char *bootfile,
|
||||||
struct in_addr vdhcp_start, struct in_addr vnameserver,
|
struct in_addr vdhcp_start, struct in_addr vnameserver,
|
||||||
struct in6_addr vnameserver6, const char **vdnssearch,
|
struct in6_addr vnameserver6, const char **vdnssearch,
|
||||||
|
|
|
@ -283,6 +283,7 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
|
||||||
bool in6_enabled,
|
bool in6_enabled,
|
||||||
struct in6_addr vprefix_addr6, uint8_t vprefix_len,
|
struct in6_addr vprefix_addr6, uint8_t vprefix_len,
|
||||||
struct in6_addr vhost6, const char *vhostname,
|
struct in6_addr vhost6, const char *vhostname,
|
||||||
|
const char *tftp_server_name,
|
||||||
const char *tftp_path, const char *bootfile,
|
const char *tftp_path, const char *bootfile,
|
||||||
struct in_addr vdhcp_start, struct in_addr vnameserver,
|
struct in_addr vdhcp_start, struct in_addr vnameserver,
|
||||||
struct in6_addr vnameserver6, const char **vdnssearch,
|
struct in6_addr vnameserver6, const char **vdnssearch,
|
||||||
|
@ -321,6 +322,7 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
|
||||||
slirp->vdhcp_startaddr = vdhcp_start;
|
slirp->vdhcp_startaddr = vdhcp_start;
|
||||||
slirp->vnameserver_addr = vnameserver;
|
slirp->vnameserver_addr = vnameserver;
|
||||||
slirp->vnameserver_addr6 = vnameserver6;
|
slirp->vnameserver_addr6 = vnameserver6;
|
||||||
|
slirp->tftp_server_name = g_strdup(tftp_server_name);
|
||||||
|
|
||||||
if (vdnssearch) {
|
if (vdnssearch) {
|
||||||
translate_dnssearch(slirp, vdnssearch);
|
translate_dnssearch(slirp, vdnssearch);
|
||||||
|
|
|
@ -212,6 +212,7 @@ struct Slirp {
|
||||||
/* tftp states */
|
/* tftp states */
|
||||||
char *tftp_prefix;
|
char *tftp_prefix;
|
||||||
struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
|
struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
|
||||||
|
char *tftp_server_name;
|
||||||
|
|
||||||
ArpTable arp_table;
|
ArpTable arp_table;
|
||||||
NdpTable ndp_table;
|
NdpTable ndp_table;
|
||||||
|
|
Loading…
Reference in New Issue