summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2021-01-19 17:49:20 +0200
committerTimo Teräs <timo.teras@iki.fi>2021-04-11 14:05:55 +0300
commit5d32e0e34adde9bb2fe9f739b5c1abddfe17c08d (patch)
tree129af0ad6f96782aae2d06fe07b66296503a2047
parentc88113168d345ea101f6cce7e4a28c29fed9e74b (diff)
downloadapk-tools-5d32e0e34adde9bb2fe9f739b5c1abddfe17c08d.tar.gz
apk-tools-5d32e0e34adde9bb2fe9f739b5c1abddfe17c08d.tar.bz2
apk-tools-5d32e0e34adde9bb2fe9f739b5c1abddfe17c08d.tar.xz
apk-tools-5d32e0e34adde9bb2fe9f739b5c1abddfe17c08d.zip
libfetch: harden URL parsing
Treat URLs with too long individual components as malformed instead of silently truncating that field. There might be unexpected results if hostname, username or password field gets truncated. (cherry picked from commit 5edd60a4e5a996590fed591e7d3a9b8167156daa)
-rw-r--r--libfetch/fetch.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/libfetch/fetch.c b/libfetch/fetch.c
index 4abf56f..a0d4dbd 100644
--- a/libfetch/fetch.c
+++ b/libfetch/fetch.c
@@ -55,10 +55,14 @@ int fetchDebug;
#define URL_MALFORMED 1
#define URL_BAD_SCHEME 2
#define URL_BAD_PORT 3
+#define URL_BAD_HOST 4
+#define URL_BAD_AUTH 5
static struct fetcherr url_errlist[] = {
{ URL_MALFORMED, FETCH_URL, "Malformed URL" },
{ URL_BAD_SCHEME, FETCH_URL, "Invalid URL scheme" },
{ URL_BAD_PORT, FETCH_URL, "Invalid server port" },
+ { URL_BAD_HOST, FETCH_URL, "Invalid (or too long) hostname" },
+ { URL_BAD_AUTH, FETCH_URL, "Invalid (or too long) credentials" },
{ -1, FETCH_UNKNOWN, "Unknown parser error" }
};
@@ -414,7 +418,7 @@ fetchParseURL(const char *URL)
}
URL += 2;
p = URL;
- goto find_user;
+ goto find_user;
}
url_seterr(URL_BAD_SCHEME);
@@ -425,15 +429,22 @@ find_user:
if (p != NULL && *p == '@') {
/* username */
for (q = URL, i = 0; (*q != ':') && (*q != '@'); q++) {
- if (i < URL_USERLEN)
- u->user[i++] = *q;
+ if (i >= URL_USERLEN) {
+ url_seterr(URL_BAD_AUTH);
+ goto ouch;
+ }
+ u->user[i++] = *q;
}
/* password */
if (*q == ':') {
- for (q++, i = 0; (*q != '@'); q++)
- if (i < URL_PWDLEN)
- u->pwd[i++] = *q;
+ for (q++, i = 0; (*q != '@'); q++) {
+ if (i >= URL_PWDLEN) {
+ url_seterr(URL_BAD_AUTH);
+ goto ouch;
+ }
+ u->pwd[i++] = *q;
+ }
}
p++;
@@ -444,14 +455,20 @@ find_user:
/* hostname */
if (*p == '[' && (q = strchr(p + 1, ']')) != NULL &&
(*++q == '\0' || *q == '/' || *q == ':')) {
- if ((i = q - p - 2) > URL_HOSTLEN)
- i = URL_HOSTLEN;
+ if ((i = q - p - 2) >= URL_HOSTLEN) {
+ url_seterr(URL_BAD_HOST);
+ goto ouch;
+ }
strncpy(u->host, ++p, i);
p = q;
} else {
- for (i = 0; *p && (*p != '/') && (*p != ':'); p++)
- if (i < URL_HOSTLEN)
- u->host[i++] = *p;
+ for (i = 0; *p && (*p != '/') && (*p != ':'); p++) {
+ if (i >= URL_HOSTLEN) {
+ url_seterr(URL_BAD_HOST);
+ goto ouch;
+ }
+ u->host[i++] = *p;
+ }
}
/* port */