public inbox for libc-help@sourceware.org
 help / color / mirror / Atom feed
* Resource leak in getaddrinfo
@ 2020-01-20 16:10 Filip Ochnik
  2020-01-20 16:26 ` Florian Weimer
  0 siblings, 1 reply; 3+ messages in thread
From: Filip Ochnik @ 2020-01-20 16:10 UTC (permalink / raw)
  To: libc-help

Hi,

I'm debugging an issue with stale resolv.conf cache in libc. I have a question about a code fragment in getaddrinfo.c which, if I understand it correctly, leaks resources.

My current understanding is that each call to __resolv_context_get should be matched by a call to __resolv_context_put, otherwise the resolv context may never be freed.

Looking at the function getaddrinfo.c:gaih_inet I see that it calls __resolv_context_get in https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=sysdeps/posix/getaddrinfo.c;h=f813d85aa39d80a9f23f95368854213ebd60b46b;hb=HEAD#l746

It is then possible to arrive at the call site of gethosts macro without calling __resolv_context_put
here:
https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=sysdeps/posix/getaddrinfo.c;h=f813d85aa39d80a9f23f95368854213ebd60b46b;hb=HEAD#l849
or here:
https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=sysdeps/posix/getaddrinfo.c;h=f813d85aa39d80a9f23f95368854213ebd60b46b;hb=HEAD#l861

Next, in gethosts, we have a lot of branches, but it's possible to arrive here
https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=sysdeps/posix/getaddrinfo.c;h=f813d85aa39d80a9f23f95368854213ebd60b46b;hb=HEAD#l291
where the code jumps to free_and_return, without calling __resolv_context_put as in other branches.

Finally, free_and_return does not call __resolv_context_put either: https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=sysdeps/posix/getaddrinfo.c;h=f813d85aa39d80a9f23f95368854213ebd60b46b;hb=HEAD#l1116

So it seems that in certain scenarios (I don't know what they are as I don't understand the code well enough) we can call __resolv_context_get without matching __resolv_context_put and thus never free the underlying context.

Am I reading this correctly? Is this a bug?

Thanks,
Filip


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Resource leak in getaddrinfo
  2020-01-20 16:10 Resource leak in getaddrinfo Filip Ochnik
@ 2020-01-20 16:26 ` Florian Weimer
  2020-01-20 16:34   ` Filip Ochnik
  0 siblings, 1 reply; 3+ messages in thread
From: Florian Weimer @ 2020-01-20 16:26 UTC (permalink / raw)
  To: Filip Ochnik; +Cc: libc-help

* Filip Ochnik:

> So it seems that in certain scenarios (I don't know what they are as I
> don't understand the code well enough) we can call
> __resolv_context_get without matching __resolv_context_put and thus
> never free the underlying context.
>
> Am I reading this correctly? Is this a bug?

Yes, this:

 276   else if (status == NSS_STATUS_SUCCESS)                                      \
 277     {                                                                         \
 278       if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem))   \
 279         {                                                                     \
 280           __resolv_context_put (res_ctx);                                     \
 281           result = -EAI_SYSTEM;                                               \
 282           goto free_and_return;                                               \
 283         }                                                                     \
 284       *pat = addrmem;                                                         \
 285                                                                               \
 286       if (localcanon != NULL && canon == NULL)                                \
 287         {                                                                     \
 288           canonbuf = __strdup (localcanon);                                   \
 289           if (canonbuf == NULL)                                               \
 290             {                                                                 \
 291               result = -EAI_SYSTEM;                                           \
 292               goto free_and_return;                                           \
 293             }                                                                 \
 294           canon = canonbuf;                                                   \
 295         }                                                                     \

looks like a bug: The __resolv_context_put is call is missing from the
free_and_return call.  Fortunately, this only happens after a memory
allocation failure (in strdup), so this should be a rare occurrence.
But we should still fix it.  Would you please file a bug here?

<https://sourceware.org/bugzilla/enter_bug.cgi?product=glibc&component=network>

Thanks,
Florian

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Resource leak in getaddrinfo
  2020-01-20 16:26 ` Florian Weimer
@ 2020-01-20 16:34   ` Filip Ochnik
  0 siblings, 0 replies; 3+ messages in thread
From: Filip Ochnik @ 2020-01-20 16:34 UTC (permalink / raw)
  To: Florian Weimer; +Cc: libc-help

Done: https://sourceware.org/bugzilla/show_bug.cgi?id=25425 <https://sourceware.org/bugzilla/show_bug.cgi?id=25425>

Thanks for a quick response!

Filip

> On 20 Jan 2020, at 17:25, Florian Weimer <fweimer@redhat.com> wrote:
> 
> * Filip Ochnik:
> 
>> So it seems that in certain scenarios (I don't know what they are as I
>> don't understand the code well enough) we can call
>> __resolv_context_get without matching __resolv_context_put and thus
>> never free the underlying context.
>> 
>> Am I reading this correctly? Is this a bug?
> 
> Yes, this:
> 
> 276   else if (status == NSS_STATUS_SUCCESS)                                      \
> 277     {                                                                         \
> 278       if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem))   \
> 279         {                                                                     \
> 280           __resolv_context_put (res_ctx);                                     \
> 281           result = -EAI_SYSTEM;                                               \
> 282           goto free_and_return;                                               \
> 283         }                                                                     \
> 284       *pat = addrmem;                                                         \
> 285                                                                               \
> 286       if (localcanon != NULL && canon == NULL)                                \
> 287         {                                                                     \
> 288           canonbuf = __strdup (localcanon);                                   \
> 289           if (canonbuf == NULL)                                               \
> 290             {                                                                 \
> 291               result = -EAI_SYSTEM;                                           \
> 292               goto free_and_return;                                           \
> 293             }                                                                 \
> 294           canon = canonbuf;                                                   \
> 295         }                                                                     \
> 
> looks like a bug: The __resolv_context_put is call is missing from the
> free_and_return call.  Fortunately, this only happens after a memory
> allocation failure (in strdup), so this should be a rare occurrence.
> But we should still fix it.  Would you please file a bug here?
> 
> <https://sourceware.org/bugzilla/enter_bug.cgi?product=glibc&component=network>
> 
> Thanks,
> Florian
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-01-20 16:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-20 16:10 Resource leak in getaddrinfo Filip Ochnik
2020-01-20 16:26 ` Florian Weimer
2020-01-20 16:34   ` Filip Ochnik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).