Re: [PATCH] tsearch.3: tdelete() can return dangling pointers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Jan,

On 03/21/2018 05:47 PM, Jann Horn wrote:
> POSIX says that deleting the root node must cause tdelete() to return some
> unspecified non-NULL pointer. Glibc implements it by returning a dangling
> pointer to the (freed) root node:
> 
> $ cat bogus_tdelete.c
> #include <search.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <err.h>
> #include <assert.h>
> 
> static void *root = NULL;
> 
> static void *xmalloc(unsigned n) {
>     void *p;
>     p = malloc(n);
>     if (!p)
>         err(1, "malloc");
>     return p;
> }
> 
> static int compare(const void *pa, const void *pb) {
>     if (*(int *) pa < *(int *) pb)
>         return -1;
>     if (*(int *) pa > *(int *) pb)
>         return 1;
>     return 0;
> }
> 
> int main(void) {
>     int *ptr;
>     void *val, *parent;
> 
>     ptr = xmalloc(sizeof(int));
>     *ptr = 1234;
>     val = tsearch((void*)ptr, &root, compare);
>     assert(*(int**)val == ptr);
>     printf("root: %p\n", root);
> 
>     parent = tdelete((void*)ptr, &root, compare);
>     printf("tdelete return value: %p; new root: %p\n", parent, root);
> 
>     return 0;
> }
> $ gcc -o bogus_tdelete bogus_tdelete.c -std=gnu99 -Wall
> $ gdb ./bogus_tdelete
> GNU gdb (GDB) 7.9-gg19
> [...]
> (gdb) break free
> Function "free" not defined.
> Make breakpoint pending on future shared library load? (y or [n]) y
> Breakpoint 1 (free) pending.
> (gdb) run
> Starting program: /usr/local/google/home/jannh/tmp/bogus_tdelete
> [...]
> root: 0x555555756030
> 
> Breakpoint 1, 0x00007ffff7ab54e0 in free () from [...]
> (gdb) print (void*)$rdi
> $1 = (void *) 0x555555756030
> (gdb) cont
> Continuing.
> tdelete return value: 0x555555756030; new root: (nil)
> [Inferior 1 (process 56564) exited normally]
> (gdb) quit
> 
> Therefore, explicitly note that tdelete() may return bad pointers that must
> not be accessed.
> 
> Signed-off-by: Jann Horn <jannh@xxxxxxxxxx>

Thanks for the patch (and, by the way, thanks also for the excellent
commit messages on these patches of yours!). Applied.

Cheers,

Michael


> ---
>  man3/tsearch.3 | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/man3/tsearch.3 b/man3/tsearch.3
> index 5cbc8b7a4..464fcae76 100644
> --- a/man3/tsearch.3
> +++ b/man3/tsearch.3
> @@ -180,6 +180,9 @@ the item whose node is returned is unspecified.
>  .BR tdelete ()
>  returns a pointer to the parent of the node deleted, or
>  NULL if the item was not found.
> +If the deleted node was the root node,
> +.BR tdelete ()
> +returns a dangling pointer that must not be accessed.
>  .PP
>  .BR tsearch (),
>  .BR tfind (),
> 


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux