Skip to content

Commit 5ee0ccc

Browse files
committed
Merge branch 'macro_free_v2_squashed'
2 parents 44010c6 + 7ca5f4b commit 5ee0ccc

File tree

169 files changed

+976
-555
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+976
-555
lines changed

changes/bug24337

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
o Minor features (defensive programming):
2+
- Most of the functions in Tor that free objects have been replaced
3+
with macros that free the objects and set the corresponding pointers
4+
to NULL. This change should help prevent a large class of dangling
5+
pointer bugs. Closes ticket 24337.
6+
7+
- Where possible, the tor_free() macro now only evaluates its input once.
8+
Part of ticket 24337.

configure.ac

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1991,7 +1991,6 @@ if test "x$enable_gcc_warnings_advisory" != "xno"; then
19911991
-Winvalid-source-encoding
19921992
-Winvalid-token-paste
19931993
-Wknr-promoted-parameter
1994-
-Wlanguage-extension-token
19951994
-Wlarge-by-value-copy
19961995
-Wliteral-conversion
19971996
-Wliteral-range

doc/HACKING/CodingStandards.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,46 @@ macro, as in:
346346
if (BUG(ptr == NULL))
347347
return -1;
348348

349+
Allocator conventions
350+
---------------------
351+
352+
By convention, any tor type with a name like `abc_t` should be allocated
353+
by a function named `abc_new()`. This function should never return
354+
NULL.
355+
356+
Also, a type named `abc_t` should be freed by a function named `abc_free_()`.
357+
Don't call this `abc_free_()` function directly -- instead, wrap it in a
358+
macro called `abc_free()`, using the `FREE_AND_NULL` macro:
359+
360+
void abc_free_(abc_t *obj);
361+
#define abc_free(obj) FREE_AND_NULL(abc_t, abc_free_, (abc))
362+
363+
This macro will free the underlying `abc_t` object, and will also set
364+
the object pointer to NULL.
365+
366+
You should define all `abc_free_()` functions to accept NULL inputs:
367+
368+
void
369+
abc_free_(abc_t *obj)
370+
{
371+
if (!obj)
372+
return;
373+
tor_free(obj->name);
374+
thing_free(obj->thing);
375+
tor_free(obj);
376+
}
377+
378+
If you need a free function that takes a `void *` argument (for example,
379+
to use it as a function callback), define it with a name like
380+
`abc_free_void()`:
381+
382+
static void
383+
abc_free_void_(void *obj)
384+
{
385+
abc_free_(obj);
386+
}
387+
388+
349389
Doxygen comment conventions
350390
---------------------------
351391

src/common/address.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1759,14 +1759,14 @@ get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr))
17591759
break;
17601760
} SMARTLIST_FOREACH_END(a);
17611761

1762-
free_interface_address6_list(addrs);
1762+
interface_address6_list_free(addrs);
17631763
return rv;
17641764
}
17651765

17661766
/** Free a smartlist of IP addresses returned by get_interface_address6_list.
17671767
*/
17681768
void
1769-
free_interface_address6_list(smartlist_t *addrs)
1769+
interface_address6_list_free_(smartlist_t *addrs)
17701770
{
17711771
if (addrs != NULL) {
17721772
SMARTLIST_FOREACH(addrs, tor_addr_t *, a, tor_free(a));
@@ -1781,7 +1781,7 @@ free_interface_address6_list(smartlist_t *addrs)
17811781
* An empty smartlist means that there are no addresses of the selected type
17821782
* matching these criteria.
17831783
* Returns NULL on failure.
1784-
* Use free_interface_address6_list to free the returned list.
1784+
* Use interface_address6_list_free to free the returned list.
17851785
*/
17861786
MOCK_IMPL(smartlist_t *,
17871787
get_interface_address6_list,(int severity,

src/common/address.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,9 @@ const char * fmt_addr32(uint32_t addr);
206206

207207
MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family,
208208
tor_addr_t *addr));
209-
void free_interface_address6_list(smartlist_t * addrs);
209+
void interface_address6_list_free_(smartlist_t * addrs);// XXXX
210+
#define interface_address6_list_free(addrs) \
211+
FREE_AND_NULL(smartlist_t, interface_address6_list_free_, (addrs))
210212
MOCK_DECL(smartlist_t *,get_interface_address6_list,(int severity,
211213
sa_family_t family,
212214
int include_internal));
@@ -321,13 +323,8 @@ int addr_mask_get_bits(uint32_t mask);
321323
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
322324
char *tor_dup_ip(uint32_t addr) ATTR_MALLOC;
323325
MOCK_DECL(int,get_interface_address,(int severity, uint32_t *addr));
324-
/** Free a smartlist of IP addresses returned by get_interface_address_list.
325-
*/
326-
static inline void
327-
free_interface_address_list(smartlist_t *addrs)
328-
{
329-
free_interface_address6_list(addrs);
330-
}
326+
#define interface_address_list_free(lst)\
327+
interface_address6_list_free(lst)
331328
/** Return a smartlist of the IPv4 addresses of all interfaces on the server.
332329
* Excludes loopback and multicast addresses. Only includes internal addresses
333330
* if include_internal is true. (Note that a relay behind NAT may use an

src/common/aes.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ aes_new_cipher(const uint8_t *key, const uint8_t *iv, int key_bits)
110110
return (aes_cnt_cipher_t *) cipher;
111111
}
112112
void
113-
aes_cipher_free(aes_cnt_cipher_t *cipher_)
113+
aes_cipher_free_(aes_cnt_cipher_t *cipher_)
114114
{
115115
if (!cipher_)
116116
return;
@@ -324,7 +324,7 @@ aes_set_key(aes_cnt_cipher_t *cipher, const uint8_t *key, int key_bits)
324324
/** Release storage held by <b>cipher</b>
325325
*/
326326
void
327-
aes_cipher_free(aes_cnt_cipher_t *cipher)
327+
aes_cipher_free_(aes_cnt_cipher_t *cipher)
328328
{
329329
if (!cipher)
330330
return;

src/common/aes.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ typedef struct aes_cnt_cipher aes_cnt_cipher_t;
1717

1818
aes_cnt_cipher_t* aes_new_cipher(const uint8_t *key, const uint8_t *iv,
1919
int key_bits);
20-
void aes_cipher_free(aes_cnt_cipher_t *cipher);
20+
void aes_cipher_free_(aes_cnt_cipher_t *cipher);
21+
#define aes_cipher_free(cipher) \
22+
FREE_AND_NULL(aes_cnt_cipher_t, aes_cipher_free_, (cipher))
2123
void aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len);
2224

2325
int evaluate_evp_for_aes(int force_value);

src/common/buffers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ buf_slack(const buf_t *buf)
409409

410410
/** Release storage held by <b>buf</b>. */
411411
void
412-
buf_free(buf_t *buf)
412+
buf_free_(buf_t *buf)
413413
{
414414
if (!buf)
415415
return;

src/common/buffers.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ struct tor_compress_state_t;
2424
buf_t *buf_new(void);
2525
buf_t *buf_new_with_capacity(size_t size);
2626
size_t buf_get_default_chunk_size(const buf_t *buf);
27-
void buf_free(buf_t *buf);
27+
void buf_free_(buf_t *buf);
28+
#define buf_free(b) FREE_AND_NULL(buf_t, buf_free_, (b))
2829
void buf_clear(buf_t *buf);
2930
buf_t *buf_copy(const buf_t *buf);
3031

src/common/compat.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1905,9 +1905,12 @@ tor_passwd_dup(const struct passwd *pw)
19051905
return new_pw;
19061906
}
19071907

1908+
#define tor_passwd_free(pw) \
1909+
FREE_AND_NULL(struct passwd, tor_passwd_free_, (pw))
1910+
19081911
/** Helper: free one of our cached 'struct passwd' values. */
19091912
static void
1910-
tor_passwd_free(struct passwd *pw)
1913+
tor_passwd_free_(struct passwd *pw)
19111914
{
19121915
if (!pw)
19131916
return;

0 commit comments

Comments
 (0)