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.
---
 libc/inet/getservice.c |   38 ++++++++++++++++----------------------
 1 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c
index c38ff80..183099f 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 <bits/uClibc_mutex.h>
 __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;
        /* <name>[[:space:]]<port>/<proto>[[:space:]][<aliases>] */
-       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)
-- 
1.7.3.1

_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to