diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-10-23 16:05:00 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-10-23 16:05:00 +0100 |
commit | 9b29b44e8ee55456e7df8106530534e1e6ef0d64 (patch) | |
tree | 4c143d20ae0f075db01fb608c0e424418e495f68 /slirp | |
parent | 7acd80e82d9332dfdaedc60c91eb3ec5195738bb (diff) | |
parent | 0fca92b9077af9817c04545cdfc519fe95c6fde9 (diff) |
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>
Diffstat (limited to 'slirp')
-rw-r--r-- | slirp/bootp.c | 45 | ||||
-rw-r--r-- | slirp/bootp.h | 1 | ||||
-rw-r--r-- | slirp/libslirp.h | 1 | ||||
-rw-r--r-- | slirp/slirp.c | 2 | ||||
-rw-r--r-- | slirp/slirp.h | 1 |
5 files changed, 40 insertions, 10 deletions
diff --git a/slirp/bootp.c b/slirp/bootp.c index 9e7b53ba94..7b1af73c95 100644 --- a/slirp/bootp.c +++ b/slirp/bootp.c @@ -159,6 +159,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) struct in_addr preq_addr; int dhcp_msg_type, val; uint8_t *q; + uint8_t *end; uint8_t client_ethaddr[ETH_ALEN]; /* 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 */ q = rbp->bp_vend; + end = (uint8_t *)&rbp[1]; memcpy(q, rfc1533_cookie, 4); q += 4; @@ -292,24 +294,46 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) if (*slirp->client_hostname) { val = strlen(slirp->client_hostname); - *q++ = RFC1533_HOSTNAME; - *q++ = val; - memcpy(q, slirp->client_hostname, val); - q += val; + if (q + val + 2 >= end) { + g_warning("DHCP packet size exceeded, " + "omitting host name option."); + } else { + *q++ = RFC1533_HOSTNAME; + *q++ = val; + memcpy(q, slirp->client_hostname, val); + q += val; + } } if (slirp->vdomainname) { val = strlen(slirp->vdomainname); - *q++ = RFC1533_DOMAINNAME; - *q++ = val; - memcpy(q, slirp->vdomainname, val); - q += val; + if (q + val + 2 >= end) { + g_warning("DHCP packet size exceeded, " + "omitting domain name option."); + } 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) { - size_t spaceleft = sizeof(rbp->bp_vend) - (q - rbp->bp_vend); val = slirp->vdnssearch_len; - if (val + 1 > spaceleft) { + if (q + val >= end) { g_warning("DHCP packet size exceeded, " "omitting domain-search option."); } else { @@ -331,6 +355,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) memcpy(q, nak_msg, sizeof(nak_msg) - 1); q += sizeof(nak_msg) - 1; } + assert(q < end); *q = RFC1533_END; daddr.sin_addr.s_addr = 0xffffffffu; diff --git a/slirp/bootp.h b/slirp/bootp.h index 394525733e..4043489835 100644 --- a/slirp/bootp.h +++ b/slirp/bootp.h @@ -70,6 +70,7 @@ #define RFC2132_MAX_SIZE 57 #define RFC2132_RENEWAL_TIME 58 #define RFC2132_REBIND_TIME 59 +#define RFC2132_TFTP_SERVER_NAME 66 #define DHCPDISCOVER 1 #define DHCPOFFER 2 diff --git a/slirp/libslirp.h b/slirp/libslirp.h index 740408a96e..42e42e9a2a 100644 --- a/slirp/libslirp.h +++ b/slirp/libslirp.h @@ -13,6 +13,7 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork, bool in6_enabled, struct in6_addr vprefix_addr6, uint8_t vprefix_len, struct in6_addr vhost6, const char *vhostname, + const char *tftp_server_name, const char *tftp_path, const char *bootfile, struct in_addr vdhcp_start, struct in_addr vnameserver, struct in6_addr vnameserver6, const char **vdnssearch, diff --git a/slirp/slirp.c b/slirp/slirp.c index 5c3bd6163f..51de41fc02 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -283,6 +283,7 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork, bool in6_enabled, struct in6_addr vprefix_addr6, uint8_t vprefix_len, struct in6_addr vhost6, const char *vhostname, + const char *tftp_server_name, const char *tftp_path, const char *bootfile, struct in_addr vdhcp_start, struct in_addr vnameserver, 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->vnameserver_addr = vnameserver; slirp->vnameserver_addr6 = vnameserver6; + slirp->tftp_server_name = g_strdup(tftp_server_name); if (vdnssearch) { translate_dnssearch(slirp, vdnssearch); diff --git a/slirp/slirp.h b/slirp/slirp.h index 10b410898a..b80725a0d6 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -212,6 +212,7 @@ struct Slirp { /* tftp states */ char *tftp_prefix; struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; + char *tftp_server_name; ArpTable arp_table; NdpTable ndp_table; |