Skip to content

Commit 9258589

Browse files
committed
Prevent memory leak
``` for (int i = 0; i < arg->family_size; i++) { arg->getaddrinfo_entries[i] = allocate_fast_fallback_getaddrinfo_entry(); if (!(arg->getaddrinfo_entries[i])) rb_syserr_fail(errno, "calloc(3)"); ``` If the allocation fails in the second interation, the memory allocated in the first iteration would be leaked. This change prevents the memory leak by allocating the memory in advance. (The struct name `fast_fallback_getaddrinfo_shared` might no longer be good.)
1 parent 6ab76a6 commit 9258589

File tree

3 files changed

+15
-28
lines changed

3 files changed

+15
-28
lines changed

ext/socket/ipsocket.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -235,31 +235,18 @@ struct fast_fallback_inetsock_arg
235235
};
236236

237237
static struct fast_fallback_getaddrinfo_shared *
238-
allocate_fast_fallback_getaddrinfo_shared(void)
238+
allocate_fast_fallback_getaddrinfo_shared(int family_size)
239239
{
240240
struct fast_fallback_getaddrinfo_shared *shared;
241241

242242
shared = (struct fast_fallback_getaddrinfo_shared *)calloc(
243243
1,
244-
sizeof(struct fast_fallback_getaddrinfo_shared)
244+
sizeof(struct fast_fallback_getaddrinfo_shared) + (family_size == 1 ? 0 : 2) * sizeof(struct fast_fallback_getaddrinfo_entry)
245245
);
246246

247247
return shared;
248248
}
249249

250-
static struct fast_fallback_getaddrinfo_entry *
251-
allocate_fast_fallback_getaddrinfo_entry(void)
252-
{
253-
struct fast_fallback_getaddrinfo_entry *entry;
254-
255-
entry = (struct fast_fallback_getaddrinfo_entry *)calloc(
256-
1,
257-
sizeof(struct fast_fallback_getaddrinfo_entry)
258-
);
259-
260-
return entry;
261-
}
262-
263250
static void
264251
allocate_fast_fallback_getaddrinfo_hints(struct addrinfo *hints, int family, int remote_addrinfo_hints, int additional_flags)
265252
{
@@ -604,7 +591,7 @@ init_fast_fallback_inetsock_internal(VALUE v)
604591
hostname_resolution_notifier = pipefd[1];
605592
wait_arg.readfds = &readfds;
606593

607-
arg->getaddrinfo_shared = allocate_fast_fallback_getaddrinfo_shared();
594+
arg->getaddrinfo_shared = allocate_fast_fallback_getaddrinfo_shared(arg->family_size);
608595
if (!arg->getaddrinfo_shared) rb_syserr_fail(errno, "calloc(3)");
609596

610597
arg->getaddrinfo_shared->lock = calloc(1, sizeof(rb_nativethread_lock_t));
@@ -659,8 +646,7 @@ init_fast_fallback_inetsock_internal(VALUE v)
659646
arg->getaddrinfo_shared->refcount = arg->family_size + 1;
660647

661648
for (int i = 0; i < arg->family_size; i++) {
662-
arg->getaddrinfo_entries[i] = allocate_fast_fallback_getaddrinfo_entry();
663-
if (!(arg->getaddrinfo_entries[i])) rb_syserr_fail(errno, "calloc(3)");
649+
arg->getaddrinfo_entries[i] = &arg->getaddrinfo_shared->getaddrinfo_entries[i];
664650
arg->getaddrinfo_entries[i]->shared = arg->getaddrinfo_shared;
665651

666652
struct addrinfo getaddrinfo_hints[arg->family_size];

ext/socket/raddrinfo.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3047,7 +3047,6 @@ free_fast_fallback_getaddrinfo_entry(struct fast_fallback_getaddrinfo_entry **en
30473047
freeaddrinfo((*entry)->ai);
30483048
(*entry)->ai = NULL;
30493049
}
3050-
free(*entry);
30513050
*entry = NULL;
30523051
}
30533052

ext/socket/rubysocket.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138

139139
#include "internal.h"
140140
#include "internal/array.h"
141+
#include "internal/compilers.h"
141142
#include "internal/error.h"
142143
#include "internal/gc.h"
143144
#include "internal/io.h"
@@ -426,15 +427,6 @@ char *port_str(VALUE port, char *pbuf, size_t pbuflen, int *flags_ptr);
426427
# define IPV4_HOSTNAME_RESOLVED '2'
427428
# define SELECT_CANCELLED '3'
428429

429-
struct fast_fallback_getaddrinfo_shared
430-
{
431-
int wait, notify, refcount, connection_attempt_fds_size;
432-
int cancelled;
433-
int *connection_attempt_fds;
434-
char *node, *service;
435-
rb_nativethread_lock_t *lock;
436-
};
437-
438430
struct fast_fallback_getaddrinfo_entry
439431
{
440432
int family, err, refcount;
@@ -446,6 +438,16 @@ struct fast_fallback_getaddrinfo_entry
446438
int test_ecode;
447439
};
448440

441+
struct fast_fallback_getaddrinfo_shared
442+
{
443+
int wait, notify, refcount, connection_attempt_fds_size;
444+
int cancelled;
445+
int *connection_attempt_fds;
446+
char *node, *service;
447+
rb_nativethread_lock_t *lock;
448+
struct fast_fallback_getaddrinfo_entry getaddrinfo_entries[FLEX_ARY_LEN];
449+
};
450+
449451
int raddrinfo_pthread_create(pthread_t *th, void *(*start_routine) (void *), void *arg);
450452
void *do_fast_fallback_getaddrinfo(void *ptr);
451453
void free_fast_fallback_getaddrinfo_entry(struct fast_fallback_getaddrinfo_entry **entry);

0 commit comments

Comments
 (0)