public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx@kernel.org>
To: Russ Allbery <eagle@eyrie.org>
Cc: libc-alpha@sourceware.org
Subject: Re: free(3) const void *
Date: Fri, 26 Jan 2024 19:23:40 +0100	[thread overview]
Message-ID: <ZbP4tUfXbOzsnHjX@debian> (raw)
In-Reply-To: <87y1ccq84g.fsf@hope.eyrie.org>

[-- Attachment #1: Type: text/plain, Size: 2741 bytes --]

Hi Russ,

On Fri, Jan 26, 2024 at 10:09:35AM -0800, Russ Allbery wrote:
> Maybe this way of explaining the objection will help.  Right now, if you
> pass a const pointer into a function, you have some assurance from that
> prototype (assisted by compiler diagnostics) that this function will not
> modify *or invalidate* that pointer and you can continue using that
> pointer after that call.  In other words, while C does not have full
> Rust-style lifetime tracking, the const marker on a function approximately
> indicates that the caller is not passing ownership of the pointer to that
> function and the function call will not affect the pointer.
> 
> With this prototype, I believe you will create a situation where someone
> could write a function that takes a const pointer and then calls free() at
> the end of that function call on this passed parameter, and there would be
> no warning from the compiler either when compiling that function or when
> compiling a function that calls it and then uses the pointer afterwards
> (at least unless there is enough inlining that a compiler can put all the
> pieces together).

Unless I'm missing something, you wouldn't get a warning either if you
use a pointer after free(3), if that free() is hidden in a function
call.

	extern void my_free(void *p);

	my_free(p);
	my_free(p);

`const` doesn't make a difference there, regarding diagnostics about
use-after-free.

> Unless I'm missing something, the more specific annotation indicating that
> free() is a deallocator doesn't help because it doesn't propagate up the
> call stack.  It will catch use after free within the same function, but it
> won't catch the case where someone passes a const pointer down a whole
> chain of functions that take const pointers, and then the function at the
> bottom of that call stack frees the pointer, unless someone carefully
> annotates every function in that call stack with that annotation.  When
> this is done in error, someone obviously wouldn't do that.

You must propagate the annotation yourself (I don't remember from the
top of my head if there's any way to remind you if you firgot to
propagate it.

	[[gnu::access(none)]] extern void my_free_const(const void *p);
	[[gnu::malloc(my_free_const)]] extern void *my_malloc(size_t bytes);

	p = my_malloc(1);
	my_free_const(p);
	my_free_const(p);  // Warning: use-after-free

So, after Xi's reminder, I'll reformulate my suggestion to

	[[gnu::access(none)]]
	void free(const void *p);

(or for compatibility reasons, do the const thing via a macro.)

Have a lovely night,
Alex

-- 
<https://www.alejandro-colomar.es/>
Looking for a remote C programming job at the moment.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2024-01-26 18:23 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-26 13:21 Alejandro Colomar
2024-01-26 14:24 ` Arsen Arsenović
2024-01-26 15:35   ` Alejandro Colomar
2024-01-26 17:22     ` Arsen Arsenović
2024-01-26 17:55       ` Xi Ruoyao
2024-01-26 18:11         ` Alejandro Colomar
2024-01-26 20:04           ` Arsen Arsenović
2024-01-26 20:07         ` Arsen Arsenović
2024-01-26 17:40     ` Andreas Schwab
2024-01-26 19:45     ` Florian Weimer
2024-01-26 15:13 ` Andreas Schwab
2024-01-26 15:33   ` Alejandro Colomar
2024-01-26 18:09 ` Russ Allbery
2024-01-26 18:23   ` Alejandro Colomar [this message]
2024-01-26 18:36     ` Xi Ruoyao
2024-01-26 18:40       ` Alejandro Colomar
2024-01-26 18:49         ` Xi Ruoyao
2024-01-26 18:57           ` Alejandro Colomar
2024-01-26 18:40     ` Russ Allbery
2024-01-26 18:45       ` Alejandro Colomar
2024-01-26 19:41   ` Florian Weimer
2024-01-26 18:39 ` [PATCH] Use [[gnu::access(none)]] on free(3) Alejandro Colomar
2024-01-26 18:41   ` Alejandro Colomar
2024-01-26 21:23     ` Paul Eggert
2024-01-26 23:19       ` Alejandro Colomar
2024-01-27 13:21       ` Cristian Rodríguez
2024-02-13 15:19         ` Gabriel Ravier
2024-02-13 15:28           ` Alejandro Colomar
2024-01-26 21:11 ` free(3) const void * DJ Delorie
2024-01-26 21:30   ` Andreas Schwab
2024-01-26 21:47     ` DJ Delorie
2024-01-26 22:07       ` Andreas Schwab
2024-01-26 23:25       ` Alejandro Colomar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZbP4tUfXbOzsnHjX@debian \
    --to=alx@kernel.org \
    --cc=eagle@eyrie.org \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).