mirror of https://gitee.com/openkylin/libvirt.git
Remove & ban use of select() for waiting for I/O
Use of the select() system call is inherantly dangerous since applications will hit a buffer overrun if any FD number exceeds the size of the select set size (typically 1024). Replace the two uses of select() with poll() and use cfg.mk to ban any future use of select(). NB: This changes the phyp driver so that it uses an infinite timeout, instead of busy-waiting for 1ms at a time. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
8f76ad9992
commit
8845d8dfa3
5
cfg.mk
5
cfg.mk
|
@ -444,6 +444,11 @@ sc_prohibit_nonreentrant:
|
||||||
done ; \
|
done ; \
|
||||||
exit $$fail
|
exit $$fail
|
||||||
|
|
||||||
|
sc_prohibit_select:
|
||||||
|
@prohibit="\\<select *\\(" \
|
||||||
|
halt="use poll(), not se""lect()" \
|
||||||
|
$(_sc_search_regexp)
|
||||||
|
|
||||||
# Prohibit the inclusion of <ctype.h>.
|
# Prohibit the inclusion of <ctype.h>.
|
||||||
sc_prohibit_ctype_h:
|
sc_prohibit_ctype_h:
|
||||||
@prohibit='^# *include *<ctype\.h>' \
|
@prohibit='^# *include *<ctype\.h>' \
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <domain_event.h>
|
#include <domain_event.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "virauth.h"
|
#include "virauth.h"
|
||||||
|
@ -72,29 +73,22 @@ static unsigned const int PHYP_MAC_SIZE= 12;
|
||||||
static int
|
static int
|
||||||
waitsocket(int socket_fd, LIBSSH2_SESSION * session)
|
waitsocket(int socket_fd, LIBSSH2_SESSION * session)
|
||||||
{
|
{
|
||||||
struct timeval timeout;
|
struct pollfd fds[1];
|
||||||
fd_set fd;
|
|
||||||
fd_set *writefd = NULL;
|
|
||||||
fd_set *readfd = NULL;
|
|
||||||
int dir;
|
int dir;
|
||||||
|
|
||||||
timeout.tv_sec = 0;
|
memset(fds, 0, sizeof(fds));
|
||||||
timeout.tv_usec = 1000;
|
fds[0].fd = socket_fd;
|
||||||
|
|
||||||
FD_ZERO(&fd);
|
|
||||||
|
|
||||||
FD_SET(socket_fd, &fd);
|
|
||||||
|
|
||||||
/* now make sure we wait in the correct direction */
|
/* now make sure we wait in the correct direction */
|
||||||
dir = libssh2_session_block_directions(session);
|
dir = libssh2_session_block_directions(session);
|
||||||
|
|
||||||
if (dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
if (dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||||
readfd = &fd;
|
fds[0].events |= POLLIN;
|
||||||
|
|
||||||
if (dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
if (dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||||
writefd = &fd;
|
fds[0].events |= POLLOUT;
|
||||||
|
|
||||||
return select(socket_fd + 1, readfd, writefd, NULL, &timeout);
|
return poll(fds, ARRAY_CARDINALITY(fds), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this function is the layer that manipulates the ssh channel itself
|
/* this function is the layer that manipulates the ssh channel itself
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NET
|
#define VIR_FROM_THIS VIR_FROM_NET
|
||||||
|
|
||||||
#define NETLINK_ACK_TIMEOUT_S 2
|
#define NETLINK_ACK_TIMEOUT_S (2*1000)
|
||||||
|
|
||||||
#if defined(__linux__) && defined(HAVE_LIBNL)
|
#if defined(__linux__) && defined(HAVE_LIBNL)
|
||||||
/* State for a single netlink event handle */
|
/* State for a single netlink event handle */
|
||||||
|
@ -185,10 +185,7 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
|
||||||
.nl_groups = 0,
|
.nl_groups = 0,
|
||||||
};
|
};
|
||||||
ssize_t nbytes;
|
ssize_t nbytes;
|
||||||
struct timeval tv = {
|
struct pollfd fds[1];
|
||||||
.tv_sec = NETLINK_ACK_TIMEOUT_S,
|
|
||||||
};
|
|
||||||
fd_set readfds;
|
|
||||||
int fd;
|
int fd;
|
||||||
int n;
|
int n;
|
||||||
struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
|
struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
|
||||||
|
@ -242,14 +239,15 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
FD_ZERO(&readfds);
|
memset(fds, 0, sizeof(fds));
|
||||||
FD_SET(fd, &readfds);
|
fds[0].fd = fd;
|
||||||
|
fds[0].events = POLLIN;
|
||||||
|
|
||||||
n = select(fd + 1, &readfds, NULL, NULL, &tv);
|
n = poll(fds, ARRAY_CARDINALITY(fds), NETLINK_ACK_TIMEOUT_S);
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
virReportSystemError(errno, "%s",
|
virReportSystemError(errno, "%s",
|
||||||
_("error in select call"));
|
_("error in poll call"));
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
virReportSystemError(ETIMEDOUT, "%s",
|
virReportSystemError(ETIMEDOUT, "%s",
|
||||||
_("no valid netlink response was received"));
|
_("no valid netlink response was received"));
|
||||||
|
|
Loading…
Reference in New Issue