summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorRuss Allbery <eagle@eyrie.org>2018-03-31 18:29:58 -0700
committerRuss Allbery <eagle@eyrie.org>2018-04-01 16:14:31 -0700
commit62e412902ea3c8cd5a7d2c1349c4e073903c7f74 (patch)
treea30ce1f0016d0dc3d239f34736335121152a1c27 /client
parentc28f50baa00835cb73804bd81d283e10ddf5d797 (diff)
Update to rra-c-util 7.1 and C TAP Harness 4.3
Validate command argument count, the length of command arguments, and the length of blocks of output from the server fit into the data type used in the wire protocol. Check the port argument to remctl and remctld to ensure that it is a valid port number. Update to rra-c-util 7.1: * Avoid spurious test failures from the network library. * Fix configure output when a Kerberos install prefix was provided. * Fix new warnings in GCC 7 and add new warning flags. * Fix all warnings from the Clang static analyzer. * Fix warnings under Clang with most warnings enabled. Update to C TAP Harness 4.3: * On test failures, report left/right instead of wanted/expected. * Fix string comparisons involving NULL pointers.
Diffstat (limited to 'client')
-rw-r--r--client/client-v1.c18
-rw-r--r--client/client-v2.c18
-rw-r--r--client/internal.h5
-rw-r--r--client/remctl.c7
4 files changed, 39 insertions, 9 deletions
diff --git a/client/client-v1.c b/client/client-v1.c
index 2c4446f..fa9414d 100644
--- a/client/client-v1.c
+++ b/client/client-v1.c
@@ -9,7 +9,8 @@
*
* Written by Russ Allbery <eagle@eyrie.org>
* Based on work by Anton Ushakov
- * Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2012, 2014
+ * Copyright 2018 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2002-2008, 2010, 2012, 2014
* The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
@@ -43,6 +44,12 @@ internal_v1_commandv(struct remctl *r, const struct iovec *command,
OM_uint32 data, major, minor;
int status;
+ /* Check that the number of arguments isn't too high to represent. */
+ if (count > UINT32_MAX) {
+ internal_set_error(r, "too many arguments to command");
+ return false;
+ }
+
/* Allocate room for the total message: argc, {<length><arg>}+. */
token.length = 4;
for (i = 0; i < count; i++) {
@@ -60,11 +67,16 @@ internal_v1_commandv(struct remctl *r, const struct iovec *command,
/* First, the argument count. Then, each argument. */
p = token.value;
- data = htonl(count);
+ data = htonl((OM_uint32) count);
memcpy(p, &data, 4);
p += 4;
for (i = 0; i < count; i++) {
- data = htonl(command[i].iov_len);
+ if (command[i].iov_len > UINT32_MAX) {
+ internal_set_error(r, "command component too long");
+ free(token.value);
+ return false;
+ }
+ data = htonl((OM_uint32) command[i].iov_len);
memcpy(p, &data, 4);
p += 4;
memcpy(p, command[i].iov_base, command[i].iov_len);
diff --git a/client/client-v2.c b/client/client-v2.c
index 68b34a9..96beae8 100644
--- a/client/client-v2.c
+++ b/client/client-v2.c
@@ -6,7 +6,8 @@
*
* Written by Russ Allbery <eagle@eyrie.org>
* Based on work by Anton Ushakov
- * Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
+ * Copyright 2018 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2002-2010, 2012
* The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
@@ -49,6 +50,12 @@ internal_v2_commandv(struct remctl *r, const struct iovec *command,
OM_uint32 data, major, minor;
int status;
+ /* Check that the number of arguments isn't too high to represent. */
+ if (count > UINT32_MAX) {
+ internal_set_error(r, "too many arguments to command");
+ return false;
+ }
+
/* Determine the total length of the message. */
length = 4;
for (iov = 0; iov < count; iov++)
@@ -108,7 +115,7 @@ internal_v2_commandv(struct remctl *r, const struct iovec *command,
/* Argument count if we haven't sent anything yet. */
if (sent == 0) {
- data = htonl(count);
+ data = htonl((OM_uint32) count);
memcpy(p, &data, 4);
p += 4;
sent += 4;
@@ -126,7 +133,12 @@ internal_v2_commandv(struct remctl *r, const struct iovec *command,
if (offset == 0) {
if (left < 4 || (left < 5 && command[iov].iov_len > 0))
break;
- data = htonl(command[iov].iov_len);
+ if (command[iov].iov_len > UINT32_MAX) {
+ internal_set_error(r, "command component too long");
+ free(token.value);
+ return false;
+ }
+ data = htonl((OM_uint32) command[iov].iov_len);
memcpy(p, &data, 4);
p += 4;
sent += 4;
diff --git a/client/internal.h b/client/internal.h
index c580bc8..c8f946a 100644
--- a/client/internal.h
+++ b/client/internal.h
@@ -3,8 +3,9 @@
*
* Written by Russ Allbery <eagle@eyrie.org>
* Based on prior work by Anton Ushakov
- * Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013,
- * 2014 The Board of Trustees of the Leland Stanford Junior University
+ * Copyright 2018 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2002-2010, 2012-2014
+ * The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
*/
diff --git a/client/remctl.c b/client/remctl.c
index 619c28e..17ecc52 100644
--- a/client/remctl.c
+++ b/client/remctl.c
@@ -121,6 +121,8 @@ main(int argc, char *argv[])
struct addrinfo hints, *ai;
const char *source = NULL;
const char *service_name = NULL;
+ char *end;
+ long tmp_port;
unsigned short port = 0;
struct remctl *r;
int errorcode = 0;
@@ -149,7 +151,10 @@ main(int argc, char *argv[])
usage(0);
break;
case 'p':
- port = atoi(optarg);
+ tmp_port = strtol(optarg, &end, 10);
+ if (*end != '\0' || tmp_port < 1 || tmp_port > (1L << 16) - 1)
+ die("invalid port number %ld", tmp_port);
+ port = (unsigned short) tmp_port;
break;
case 's':
service_name = optarg;