Commit d861b05ea30e6ac177de9b679da96194ebe21afc

Authored by pbrook
1 parent 191abaa2

Avoid buffer overflow when sending slirp packets.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1744 c046a42c-6fe2-441c-8c8c-71466251a162
hw/lance.c
... ... @@ -283,6 +283,11 @@ static CPUWriteMemoryFunc *lance_mem_write[3] = {
283 283  
284 284 #define MIN_BUF_SIZE 60
285 285  
  286 +static void lance_can_receive(void *opaque)
  287 +{
  288 + return 1;
  289 +}
  290 +
286 291 static void lance_receive(void *opaque, const uint8_t *buf, int size)
287 292 {
288 293 LANCEState *s = opaque;
... ... @@ -440,7 +445,7 @@ void lance_init(NICInfo *nd, int irq, uint32_t leaddr, uint32_t ledaddr)
440 445  
441 446 lance_reset(s);
442 447  
443   - s->vc = qemu_new_vlan_client(nd->vlan, lance_receive, s);
  448 + s->vc = qemu_new_vlan_client(nd->vlan, lance_receive, lance_can_receive, s);
444 449  
445 450 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
446 451 "lance macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
... ...
hw/ne2000.c
... ... @@ -200,14 +200,10 @@ static int compute_mcast_idx(const uint8_t *ep)
200 200 return (crc >> 26);
201 201 }
202 202  
203   -/* return the max buffer size if the NE2000 can receive more data */
204   -static int ne2000_can_receive(void *opaque)
  203 +static int ne2000_buffer_full(NE2000State *s)
205 204 {
206   - NE2000State *s = opaque;
207 205 int avail, index, boundary;
208   -
209   - if (s->cmd & E8390_STOP)
210   - return 0;
  206 +
211 207 index = s->curpag << 8;
212 208 boundary = s->boundary << 8;
213 209 if (index < boundary)
... ... @@ -215,8 +211,17 @@ static int ne2000_can_receive(void *opaque)
215 211 else
216 212 avail = (s->stop - s->start) - (index - boundary);
217 213 if (avail < (MAX_ETH_FRAME_SIZE + 4))
218   - return 0;
219   - return MAX_ETH_FRAME_SIZE;
  214 + return 1;
  215 + return 0;
  216 +}
  217 +
  218 +static int ne2000_can_receive(void *opaque)
  219 +{
  220 + NE2000State *s = opaque;
  221 +
  222 + if (s->cmd & E8390_STOP)
  223 + return 1;
  224 + return !ne2000_buffer_full(s);
220 225 }
221 226  
222 227 #define MIN_BUF_SIZE 60
... ... @@ -234,7 +239,7 @@ static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
234 239 printf("NE2000: received len=%d\n", size);
235 240 #endif
236 241  
237   - if (!ne2000_can_receive(s))
  242 + if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
238 243 return;
239 244  
240 245 /* XXX: check this */
... ... @@ -722,7 +727,8 @@ void isa_ne2000_init(int base, int irq, NICInfo *nd)
722 727  
723 728 ne2000_reset(s);
724 729  
725   - s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s);
  730 + s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive,
  731 + ne2000_can_receive, s);
726 732  
727 733 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
728 734 "ne2000 macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
... ... @@ -791,7 +797,8 @@ void pci_ne2000_init(PCIBus *bus, NICInfo *nd)
791 797 s->pci_dev = (PCIDevice *)d;
792 798 memcpy(s->macaddr, nd->macaddr, 6);
793 799 ne2000_reset(s);
794   - s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s);
  800 + s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive,
  801 + ne2000_can_receive, s);
795 802  
796 803 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
797 804 "ne2000 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
... ...
hw/smc91c111.c
... ... @@ -593,6 +593,17 @@ static uint32_t smc91c111_readl(void *opaque, target_phys_addr_t offset)
593 593 return val;
594 594 }
595 595  
  596 +static int smc91c111_can_receive(void *opaque)
  597 +{
  598 + smc91c111_state *s = (smc91c111_state *)opaque;
  599 +
  600 + if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
  601 + return 1;
  602 + if (s->allocated == (1 << NUM_PACKETS) - 1)
  603 + return 0;
  604 + return 1;
  605 +}
  606 +
596 607 static void smc91c111_receive(void *opaque, const uint8_t *buf, int size)
597 608 {
598 609 smc91c111_state *s = (smc91c111_state *)opaque;
... ... @@ -697,6 +708,7 @@ void smc91c111_init(NICInfo *nd, uint32_t base, void *pic, int irq)
697 708  
698 709 smc91c111_reset(s);
699 710  
700   - s->vc = qemu_new_vlan_client(nd->vlan, smc91c111_receive, s);
  711 + s->vc = qemu_new_vlan_client(nd->vlan, smc91c111_receive,
  712 + smc91c111_can_receive, s);
701 713 /* ??? Save/restore. */
702 714 }
... ...
... ... @@ -1842,13 +1842,16 @@ VLANState *qemu_find_vlan(int id)
1842 1842 }
1843 1843  
1844 1844 VLANClientState *qemu_new_vlan_client(VLANState *vlan,
1845   - IOReadHandler *fd_read, void *opaque)
  1845 + IOReadHandler *fd_read,
  1846 + IOCanRWHandler *fd_can_read,
  1847 + void *opaque)
1846 1848 {
1847 1849 VLANClientState *vc, **pvc;
1848 1850 vc = qemu_mallocz(sizeof(VLANClientState));
1849 1851 if (!vc)
1850 1852 return NULL;
1851 1853 vc->fd_read = fd_read;
  1854 + vc->fd_can_read = fd_can_read;
1852 1855 vc->opaque = opaque;
1853 1856 vc->vlan = vlan;
1854 1857  
... ... @@ -1860,6 +1863,20 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
1860 1863 return vc;
1861 1864 }
1862 1865  
  1866 +int qemu_can_send_packet(VLANClientState *vc1)
  1867 +{
  1868 + VLANState *vlan = vc1->vlan;
  1869 + VLANClientState *vc;
  1870 +
  1871 + for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
  1872 + if (vc != vc1) {
  1873 + if (vc->fd_can_read && !vc->fd_can_read(vc->opaque))
  1874 + return 0;
  1875 + }
  1876 + }
  1877 + return 1;
  1878 +}
  1879 +
1863 1880 void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
1864 1881 {
1865 1882 VLANState *vlan = vc1->vlan;
... ... @@ -1885,7 +1902,7 @@ static VLANClientState *slirp_vc;
1885 1902  
1886 1903 int slirp_can_output(void)
1887 1904 {
1888   - return 1;
  1905 + return qemu_can_send_packet(slirp_vc);
1889 1906 }
1890 1907  
1891 1908 void slirp_output(const uint8_t *pkt, int pkt_len)
... ... @@ -1913,7 +1930,7 @@ static int net_slirp_init(VLANState *vlan)
1913 1930 slirp_init();
1914 1931 }
1915 1932 slirp_vc = qemu_new_vlan_client(vlan,
1916   - slirp_receive, NULL);
  1933 + slirp_receive, NULL, NULL);
1917 1934 snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
1918 1935 return 0;
1919 1936 }
... ... @@ -2098,7 +2115,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
2098 2115 if (!s)
2099 2116 return NULL;
2100 2117 s->fd = fd;
2101   - s->vc = qemu_new_vlan_client(vlan, tap_receive, s);
  2118 + s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
2102 2119 qemu_set_fd_handler(s->fd, tap_send, NULL, s);
2103 2120 snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
2104 2121 return s;
... ... @@ -2412,7 +2429,7 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
2412 2429 return NULL;
2413 2430 s->fd = fd;
2414 2431  
2415   - s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, s);
  2432 + s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
2416 2433 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
2417 2434  
2418 2435 /* mcast: save bound address as dst */
... ... @@ -2440,7 +2457,7 @@ static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
2440 2457 return NULL;
2441 2458 s->fd = fd;
2442 2459 s->vc = qemu_new_vlan_client(vlan,
2443   - net_socket_receive, s);
  2460 + net_socket_receive, NULL, s);
2444 2461 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2445 2462 "socket: fd=%d", fd);
2446 2463 if (is_connected) {
... ...
... ... @@ -279,6 +279,9 @@ typedef struct VLANClientState VLANClientState;
279 279  
280 280 struct VLANClientState {
281 281 IOReadHandler *fd_read;
  282 + /* Packets may still be sent if this returns zero. It's used to
  283 + rate-limit the slirp code. */
  284 + IOCanRWHandler *fd_can_read;
282 285 void *opaque;
283 286 struct VLANClientState *next;
284 287 struct VLANState *vlan;
... ... @@ -293,8 +296,12 @@ typedef struct VLANState {
293 296  
294 297 VLANState *qemu_find_vlan(int id);
295 298 VLANClientState *qemu_new_vlan_client(VLANState *vlan,
296   - IOReadHandler *fd_read, void *opaque);
  299 + IOReadHandler *fd_read,
  300 + IOCanRWHandler *fd_can_read,
  301 + void *opaque);
  302 +int qemu_can_send_packet(VLANClientState *vc);
297 303 void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
  304 +void qemu_handler_true(void *opaque);
298 305  
299 306 void do_info_network(void);
300 307  
... ...