Skip to content

Commit 30cf86f

Browse files
committed
Fix write-past-buffer-end in ldapServiceLookup().
The code to assemble ldap_get_values_len's output into a single string wrote the terminating null one byte past where it should. Fix that, and make some other cosmetic adjustments to make the code a trifle more readable and more in line with usual Postgres coding style. Also, free the "result" string when done with it, to avoid a permanent memory leak. Bug report and patch by Albe Laurenz, cosmetic adjustments by me.
1 parent fbc56f7 commit 30cf86f

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

src/interfaces/libpq/fe-connect.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3339,25 +3339,26 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
33393339
return 1;
33403340
}
33413341

3342-
/* concatenate values to a single string */
3343-
for (size = 0, i = 0; values[i] != NULL; ++i)
3342+
/* concatenate values into a single string with newline terminators */
3343+
size = 1; /* for the trailing null */
3344+
for (i = 0; values[i] != NULL; i++)
33443345
size += values[i]->bv_len + 1;
3345-
if ((result = malloc(size + 1)) == NULL)
3346+
if ((result = malloc(size)) == NULL)
33463347
{
33473348
printfPQExpBuffer(errorMessage,
33483349
libpq_gettext("out of memory\n"));
33493350
ldap_value_free_len(values);
33503351
ldap_unbind(ld);
33513352
return 3;
33523353
}
3353-
for (p = result, i = 0; values[i] != NULL; ++i)
3354+
p = result;
3355+
for (i = 0; values[i] != NULL; i++)
33543356
{
3355-
strncpy(p, values[i]->bv_val, values[i]->bv_len);
3357+
memcpy(p, values[i]->bv_val, values[i]->bv_len);
33563358
p += values[i]->bv_len;
33573359
*(p++) = '\n';
3358-
if (values[i + 1] == NULL)
3359-
*(p + 1) = '\0';
33603360
}
3361+
*p = '\0';
33613362

33623363
ldap_value_free_len(values);
33633364
ldap_unbind(ld);
@@ -3386,6 +3387,7 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
33863387
printfPQExpBuffer(errorMessage, libpq_gettext(
33873388
"missing \"=\" after \"%s\" in connection info string\n"),
33883389
optname);
3390+
free(result);
33893391
return 3;
33903392
}
33913393
else if (*p == '=')
@@ -3404,6 +3406,7 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
34043406
printfPQExpBuffer(errorMessage, libpq_gettext(
34053407
"missing \"=\" after \"%s\" in connection info string\n"),
34063408
optname);
3409+
free(result);
34073410
return 3;
34083411
}
34093412
break;
@@ -3467,6 +3470,7 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
34673470
printfPQExpBuffer(errorMessage,
34683471
libpq_gettext("invalid connection option \"%s\"\n"),
34693472
optname);
3473+
free(result);
34703474
return 1;
34713475
}
34723476
optname = NULL;
@@ -3475,6 +3479,8 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
34753479
oldstate = state;
34763480
}
34773481

3482+
free(result);
3483+
34783484
if (state == 5 || state == 6)
34793485
{
34803486
printfPQExpBuffer(errorMessage, libpq_gettext(

0 commit comments

Comments
 (0)