summaryrefslogtreecommitdiff
path: root/vl.c
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2006-02-04 22:15:28 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2006-02-04 22:15:28 +0000
commitd861b05ea30e6ac177de9b679da96194ebe21afc (patch)
tree6bb3605e24633c0e64c9b7396873bbe28fe93be1 /vl.c
parent191abaa2f0aca0c6ebca06f3e985da02ac950d14 (diff)
downloadqemu-d861b05ea30e6ac177de9b679da96194ebe21afc.tar.gz
Avoid buffer overflow when sending slirp packets.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1744 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'vl.c')
-rw-r--r--vl.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/vl.c b/vl.c
index d875f2ac0a..6d319bc330 100644
--- a/vl.c
+++ b/vl.c
@@ -1842,13 +1842,16 @@ VLANState *qemu_find_vlan(int id)
}
VLANClientState *qemu_new_vlan_client(VLANState *vlan,
- IOReadHandler *fd_read, void *opaque)
+ IOReadHandler *fd_read,
+ IOCanRWHandler *fd_can_read,
+ void *opaque)
{
VLANClientState *vc, **pvc;
vc = qemu_mallocz(sizeof(VLANClientState));
if (!vc)
return NULL;
vc->fd_read = fd_read;
+ vc->fd_can_read = fd_can_read;
vc->opaque = opaque;
vc->vlan = vlan;
@@ -1860,6 +1863,20 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
return vc;
}
+int qemu_can_send_packet(VLANClientState *vc1)
+{
+ VLANState *vlan = vc1->vlan;
+ VLANClientState *vc;
+
+ for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
+ if (vc != vc1) {
+ if (vc->fd_can_read && !vc->fd_can_read(vc->opaque))
+ return 0;
+ }
+ }
+ return 1;
+}
+
void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
{
VLANState *vlan = vc1->vlan;
@@ -1885,7 +1902,7 @@ static VLANClientState *slirp_vc;
int slirp_can_output(void)
{
- return 1;
+ return qemu_can_send_packet(slirp_vc);
}
void slirp_output(const uint8_t *pkt, int pkt_len)
@@ -1913,7 +1930,7 @@ static int net_slirp_init(VLANState *vlan)
slirp_init();
}
slirp_vc = qemu_new_vlan_client(vlan,
- slirp_receive, NULL);
+ slirp_receive, NULL, NULL);
snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
return 0;
}
@@ -2098,7 +2115,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
if (!s)
return NULL;
s->fd = fd;
- s->vc = qemu_new_vlan_client(vlan, tap_receive, s);
+ s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
qemu_set_fd_handler(s->fd, tap_send, NULL, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
return s;
@@ -2412,7 +2429,7 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
return NULL;
s->fd = fd;
- s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, s);
+ s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
/* mcast: save bound address as dst */
@@ -2440,7 +2457,7 @@ static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
return NULL;
s->fd = fd;
s->vc = qemu_new_vlan_client(vlan,
- net_socket_receive, s);
+ net_socket_receive, NULL, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"socket: fd=%d", fd);
if (is_connected) {