aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2014-04-10 10:24:30 +0200
committerLuiz Capitulino <lcapitulino@redhat.com>2014-05-08 14:19:58 -0400
commite9c5c1f40c949c5d2d7e1eeddf3caaed32e1c641 (patch)
tree2f81ee84959156d40e2d9ba80066aafa08520532 /util
parentcb45de6798956975c4b13a6233f7a00d2239b61a (diff)
cutils: tighten qemu_parse_fd()
qemu_parse_fd() used to handle at least the following strings incorrectly: o "-2": simply let through o "2147483648": returned as LONG_MAX==INT_MAX on ILP32 (with ERANGE ignored); implementation-defined behavior on LP64 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Diffstat (limited to 'util')
-rw-r--r--util/cutils.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/util/cutils.c b/util/cutils.c
index b337293239..dbe7412bd8 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -24,6 +24,8 @@
#include "qemu-common.h"
#include "qemu/host-utils.h"
#include <math.h>
+#include <limits.h>
+#include <errno.h>
#include "qemu/sockets.h"
#include "qemu/iov.h"
@@ -457,11 +459,16 @@ int parse_uint_full(const char *s, unsigned long long *value, int base)
int qemu_parse_fd(const char *param)
{
- int fd;
- char *endptr = NULL;
+ long fd;
+ char *endptr;
+ errno = 0;
fd = strtol(param, &endptr, 10);
- if (*endptr || (fd == 0 && param == endptr)) {
+ if (param == endptr /* no conversion performed */ ||
+ errno != 0 /* not representable as long; possibly others */ ||
+ *endptr != '\0' /* final string not empty */ ||
+ fd < 0 /* invalid as file descriptor */ ||
+ fd > INT_MAX /* not representable as int */) {
return -1;
}
return fd;