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); | ||||||
|  |             if (q + val + 2 >= end) { | ||||||
|  |                 g_warning("DHCP packet size exceeded, " | ||||||
|  |                     "omitting host name option."); | ||||||
|  |             } else { | ||||||
|                 *q++ = RFC1533_HOSTNAME; |                 *q++ = RFC1533_HOSTNAME; | ||||||
|                 *q++ = val; |                 *q++ = val; | ||||||
|                 memcpy(q, slirp->client_hostname, val); |                 memcpy(q, slirp->client_hostname, val); | ||||||
|                 q += val; |                 q += val; | ||||||
|             } |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         if (slirp->vdomainname) { |         if (slirp->vdomainname) { | ||||||
|             val = strlen(slirp->vdomainname); |             val = strlen(slirp->vdomainname); | ||||||
|  |             if (q + val + 2 >= end) { | ||||||
|  |                 g_warning("DHCP packet size exceeded, " | ||||||
|  |                     "omitting domain name option."); | ||||||
|  |             } else { | ||||||
|                 *q++ = RFC1533_DOMAINNAME; |                 *q++ = RFC1533_DOMAINNAME; | ||||||
|                 *q++ = val; |                 *q++ = val; | ||||||
|                 memcpy(q, slirp->vdomainname, val); |                 memcpy(q, slirp->vdomainname, val); | ||||||
|                 q += 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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Peter Maydell
						Peter Maydell