From 2631ae8aab71c350273fa2d7a787bfcbff258029 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Thu, 14 Oct 2010 06:35:08 +0000 Subject: getservice: fix handling of long lines Don't try to be smart by dynamically realloc buffersize as it doesn't work. Instead, be simple and allocate a buffer big enough. This fixes a memory leak when calling getserv{ent,byname,byport} multiple times. To save memory we reduce number of max aliases. We seldomly will need more than 1 anyways. While here, fix segfault that happened if there were too many aliases. Signed-off-by: Natanael Copa Signed-off-by: Bernhard Reutner-Fischer --- libc/inet/getservice.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'libc/inet/getservice.c') diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c index c38ff80ac..183099f5c 100644 --- a/libc/inet/getservice.c +++ b/libc/inet/getservice.c @@ -28,9 +28,11 @@ aliases: case sensitive optional space or tab separated list of other names #include __UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); -#define MAXALIASES 35 -#define BUFSZ (80) /* one line */ -#define SBUFSIZE (BUFSZ + 1 + (sizeof(char *) * MAXALIASES)) +#define MINTOKENS 3 +#define MAXALIASES 8 /* we seldomly need more than 1 alias */ +#define MAXTOKENS (MINTOKENS + MAXALIASES + 1) +#define BUFSZ (255) /* one line */ +#define SBUFSIZE (BUFSZ + 1 + (sizeof(char *) * MAXTOKENS)) static parser_t *servp = NULL; static struct servent serve; @@ -65,10 +67,8 @@ libc_hidden_def(endservent) int getservent_r(struct servent *result_buf, char *buf, size_t buflen, struct servent **result) { - char **alias; - char **serv_aliases; char **tok = NULL; - const size_t aliaslen = sizeof(*serv_aliases) * MAXALIASES; + const size_t aliaslen = sizeof(char *) * MAXTOKENS; int ret = ERANGE; *result = NULL; @@ -87,13 +87,13 @@ int getservent_r(struct servent *result_buf, servp->data_len = aliaslen; servp->line_len = buflen - aliaslen; /* [[:space:]]/[[:space:]][] */ - if (!config_read(servp, &tok, MAXALIASES, 3, "# \t/", PARSE_NORMAL)) { + if (!config_read(servp, &tok, MAXTOKENS - 1, MINTOKENS, "# \t/", PARSE_NORMAL)) { goto DONE; } result_buf->s_name = *(tok++); result_buf->s_port = htons((u_short) atoi(*(tok++))); result_buf->s_proto = *(tok++); - result_buf->s_aliases = alias = serv_aliases = tok; + result_buf->s_aliases = tok; *result = result_buf; ret = 0; DONE: @@ -106,9 +106,8 @@ libc_hidden_def(getservent_r) static void __initbuf(void) { - if (servbuf) - servbuf_sz += BUFSZ; - servbuf = realloc(servbuf, servbuf_sz); + if (!servbuf) + servbuf = malloc(SBUFSIZE); if (!servbuf) abort(); } @@ -117,9 +116,8 @@ struct servent *getservent(void) { struct servent *result; - do { - __initbuf(); - } while (getservent_r(&serve, servbuf, servbuf_sz, &result) == ERANGE); + __initbuf(); + getservent_r(&serve, servbuf, servbuf_sz, &result); return result; } @@ -154,10 +152,8 @@ struct servent *getservbyname(const char *name, const char *proto) { struct servent *result; - do { - __initbuf(); - } while (getservbyname_r(name, proto, &serve, servbuf, servbuf_sz, &result) - == ERANGE); + __initbuf(); + getservbyname_r(name, proto, &serve, servbuf, servbuf_sz, &result); return result; } @@ -187,10 +183,8 @@ struct servent *getservbyport(int port, const char *proto) { struct servent *result; - do { - __initbuf(); - } while (getservbyport_r(port, proto, &serve, servbuf, servbuf_sz, &result) - == ERANGE); + __initbuf(); + getservbyport_r(port, proto, &serve, servbuf, servbuf_sz, &result); return result; } libc_hidden_def(getservbyport) -- cgit v1.2.3