[Swan-dev] pfree checks

Paul Wouters paul at nohats.ca
Sat Oct 7 18:11:17 UTC 2017


Seems useful to me

Sent from my iPhone

> On Oct 7, 2017, at 13:29, Andrew Cagney <andrew.cagney at gmail.com> wrote:
> 
> I'm considering a commit containing some of the below additional checks:
> 
> - try to spot a double free (I think this check should go in)
> 
> - try to spot a use-after-free, not so sure about this
> 
> - and there is also the possibility of a check for heap overflow
> 
> but these start to stray into checks that free() is doing anyway :-/
> 
> thoughts,
> Andrew
> 
> diff --git a/lib/libswan/alloc.c b/lib/libswan/alloc.c
> index ab6f3194b..c1f9824e7 100644
> --- a/lib/libswan/alloc.c
> +++ b/lib/libswan/alloc.c
> @@ -61,6 +61,20 @@ void set_alloc_exit_log_func(exit_log_func_t func)
>  /* this magic number is 3671129837 decimal (623837458 complemented) */
>  #define LEAK_MAGIC 0xDAD0FEEDul
>  
> +#define INVALID_MAGIC 0xFE
> +#if __SIZEOF_POINTER__ == 4
> +#define INVALID_POINTER ((void*)0xFEFEFEFEul)
> +#endif
> +#if __SIZEOF_POINTER__ == 8
> +#define INVALID_POINTER ((void*)0xFEFEFEFEFEFEFEFEull)
> +#endif
> +#ifndef INVALID_POINTER
> +/* suppresses check */
> +#define INVALID_POINTER NULL
> +#endif
> +
> +static bool check_invalid_pointer = true;
> +
>  union mhdr {
>      struct {
>          const char *name;
> @@ -116,6 +130,9 @@ static void *alloc_bytes_raw(size_t size, const char *name)
>              allocs = p;
>              pthread_mutex_unlock(&leak_detective_mutex);
>          }
> +        if (p + 1 == INVALID_POINTER) {
> +            check_invalid_pointer = false; /* sigh! */
> +        }
>          return p + 1;
>      } else {
>          return p;
> @@ -128,8 +145,20 @@ void pfree(void *ptr)
>          union mhdr *p;
>  
>          passert(ptr != NULL);
> +        if (check_invalid_pointer) {
> +            if (ptr == INVALID_POINTER) {
> +                PASSERT_FAIL("pointer %p invalid (likely from use after free)", p);
> +            }
> +        }
> +
>          p = ((union mhdr *)ptr) - 1;
> -        passert(p->i.magic == LEAK_MAGIC);
> +
> +        if (p->i.magic == ~LEAK_MAGIC) {
> +            PASSERT_FAIL("pointer %p invalid (likely from double free)", ptr);
> +        } else if (p->i.magic != LEAK_MAGIC) {
> +            PASSERT_FAIL("pointer %p invalid (likely from heap corruption)", ptr);
> +        }
> +
>          {
>              pthread_mutex_lock(&leak_detective_mutex);
>              if (p->i.older != NULL) {
> @@ -146,7 +175,7 @@ void pfree(void *ptr)
>              pthread_mutex_unlock(&leak_detective_mutex);
>          }
>          /* stomp on memory!   Is another byte value better? */
> -        memset(p, 0xEF, sizeof(union mhdr) + p->i.size);
> +        memset(p, INVALID_MAGIC, sizeof(union mhdr) + p->i.size);
>          p->i.magic = ~LEAK_MAGIC;
>          free(p);
>      } else {
> 
> _______________________________________________
> Swan-dev mailing list
> Swan-dev at lists.libreswan.org
> https://lists.libreswan.org/mailman/listinfo/swan-dev



More information about the Swan-dev mailing list