From a23b00988ae023f18bd31f18ab2fd32230637ce2 Mon Sep 17 00:00:00 2001 From: Marko Hrastovec Date: Thu, 17 Sep 2020 07:33:32 +0200 Subject: [PATCH] freeaddrinfo.3: Fix memory leaks in freeaddrinfo() examples [mtk: the coding style used in the example could lead people to inject memory leaks in their code if they cut/paste/modify the code to replace "exit" paths with "return" paths from a library function.] [Marko, from the mail thread discussing this patch:] You are right about terminating the process. However, people copy that example and put the code in a function changing "exit" to "return". There are a bunch of examples like that here https://beej.us/guide/bgnet/html/#poll, for instance. That error bothered me when reading the network programming guide https://beej.us/guide/bgnet/html/. Than I looked for information elsewhere: https://stackoverflow.com/questions/6712740/valgrind-reporting-that-getaddrinfo-is-leaking-memory https://stackoverflow.com/questions/15690303/server-client-sockets-freeaddrinfo3-placement And finally, I checked manual pages and saw where these errors come from. When you change that to a function and return without doing freeaddrinfo, that is a memory leak. I believe an example should show good programming practices. Relying on exiting and clearing the memory in that case is not such a case. In my opinion, these examples lead people to make mistakes in their programs. Signed-off-by: Michael Kerrisk --- man3/getaddrinfo.3 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/man3/getaddrinfo.3 b/man3/getaddrinfo.3 index c9a4b3e43..4d383bea0 100644 --- a/man3/getaddrinfo.3 +++ b/man3/getaddrinfo.3 @@ -711,13 +711,13 @@ main(int argc, char *argv[]) close(sfd); } + freeaddrinfo(result); /* No longer needed */ + if (rp == NULL) { /* No address succeeded */ fprintf(stderr, "Could not bind\en"); exit(EXIT_FAILURE); } - freeaddrinfo(result); /* No longer needed */ - /* Read datagrams and echo them back to sender */ for (;;) { @@ -804,13 +804,13 @@ main(int argc, char *argv[]) close(sfd); } + freeaddrinfo(result); /* No longer needed */ + if (rp == NULL) { /* No address succeeded */ fprintf(stderr, "Could not connect\en"); exit(EXIT_FAILURE); } - freeaddrinfo(result); /* No longer needed */ - /* Send remaining command\-line arguments as separate datagrams, and read responses from server */