Skip to content

Commit 36204e2

Browse files
committed
context.c : track length of buffer when buidling xml
As we are building up the xml, keep track of the length of the (remaining) buffer, and check it at the end to make sure we didn't overflow. This does change the max length of the channel xml description from MAX_size_t to MAX_ssize_t. Worse case, that is from 64k to 32k. The C spec defines the minimum size_t to 16-bits. Nominally, on most modern compilers (where size_t is 32-bits) this would reduce things from 4G to 2G. On Pluto, the nomial context is 24962 bytes, M2k is 31178. 32k seems pretty thin. Good thing we are all on modern compilers. Signed-off-by: Robin Getz <[email protected]>
1 parent 8c83eae commit 36204e2

File tree

2 files changed

+34
-13
lines changed

2 files changed

+34
-13
lines changed

context.c

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,25 @@ static const char xml_header[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
5353
/* Returns a string containing the XML representation of this context */
5454
char * iio_context_create_xml(const struct iio_context *ctx)
5555
{
56-
size_t len, *devices_len = NULL;
57-
char *str, *ptr, **devices = NULL;
56+
ssize_t len;
57+
size_t *devices_len = NULL;
58+
char *str, *ptr, *eptr, **devices = NULL;
5859
unsigned int i;
5960

60-
len = strlen(ctx->name) + sizeof(xml_header) - 1 +
61-
sizeof("<context name=\"\" ></context>");
62-
if (ctx->description)
63-
len += strlen(ctx->description) +
64-
sizeof(" description=\"\"") - 1;
61+
len = sizeof(xml_header) - 1;
62+
len += strnlen(ctx->name, MAX_CTX_NAME);
63+
len += sizeof("<context name=\"\" ></context>") - 1;
6564

66-
for (i = 0; i < ctx->nb_attrs; i++)
67-
len += strlen(ctx->attrs[i]) +
68-
strlen(ctx->values[i]) +
69-
sizeof("<context-attribute name=\"\" value=\"\" />");
65+
if (ctx->description) {
66+
len += strnlen(ctx->description, MAX_CTX_DESC);
67+
len += sizeof(" description=\"\"") - 1;
68+
}
69+
70+
for (i = 0; i < ctx->nb_attrs; i++) {
71+
len += strnlen(ctx->attrs[i], MAX_ATTR_NAME);
72+
len += strnlen(ctx->values[i], MAX_ATTR_VALUE);
73+
len += sizeof("<context-attribute name=\"\" value=\"\" />") - 1;
74+
}
7075

7176
if (ctx->nb_devices) {
7277
devices_len = malloc(ctx->nb_devices * sizeof(*devices_len));
@@ -94,6 +99,7 @@ char * iio_context_create_xml(const struct iio_context *ctx)
9499
errno = ENOMEM;
95100
goto err_free_devices;
96101
}
102+
eptr = str + len;
97103

98104
if (ctx->description) {
99105
iio_snprintf(str, len, "%s<context name=\"%s\" "
@@ -105,21 +111,32 @@ char * iio_context_create_xml(const struct iio_context *ctx)
105111
}
106112

107113
ptr = strrchr(str, '\0');
114+
len = eptr - ptr;
108115

109-
for (i = 0; i < ctx->nb_attrs; i++)
116+
for (i = 0; i < ctx->nb_attrs; i++) {
110117
ptr += sprintf(ptr, "<context-attribute name=\"%s\" value=\"%s\" />",
111118
ctx->attrs[i], ctx->values[i]);
112-
119+
len = eptr - ptr;
120+
}
113121

114122
for (i = 0; i < ctx->nb_devices; i++) {
115123
strcpy(ptr, devices[i]);
116124
ptr += devices_len[i];
125+
len -= devices_len[i];
117126
free(devices[i]);
118127
}
119128

120129
free(devices);
121130
free(devices_len);
122131
strcpy(ptr, "</context>");
132+
len -= sizeof("</context>") - 1;
133+
134+
if (len < 0) {
135+
IIO_ERROR("Internal libIIO error: iio_context_create_xml str length isssue\n");
136+
free(str);
137+
return NULL;
138+
}
139+
123140
return str;
124141

125142
err_free_devices:

iio-private.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@
6565
#define MAX_CHN_NAME 256 /* encoded in the sysfs filename */
6666
#define MAX_DEV_ID 256 /* encoded in the sysfs filename */
6767
#define MAX_DEV_NAME 256 /* encoded in the sysfs filename */
68+
#define MAX_CTX_NAME 256 /* nominally "xml" */
69+
#define MAX_CTX_DESC 256 /* nominally "linux ..." */
70+
#define MAX_ATTR_NAME 256 /* encoded in the sysfs filename */
71+
#define MAX_ATTR_VALUE 4096 /* Linux page size, could be anything */
6872

6973
/* ntohl/htonl are a nightmare to use in cross-platform applications,
7074
* since they are defined in different headers on different platforms.

0 commit comments

Comments
 (0)