unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [RFC] Supporting malloc_usable_size
@ 2022-11-24 21:32 Siddhesh Poyarekar
  2022-12-02  4:42 ` DJ Delorie via Libc-alpha
  2022-12-02 12:03 ` Andreas Schwab
  0 siblings, 2 replies; 25+ messages in thread
From: Siddhesh Poyarekar @ 2022-11-24 21:32 UTC (permalink / raw)
  To: libc-alpha; +Cc: fweimer, carlos

Hello,

This is in context of this systemd issue:

https://github.com/systemd/systemd/issues/22801

through which I had discovered that systemd was (ab)using
malloc_usable_size to use spare space in an allocated object.  This was
discovered when _FORTIFY_SOURCE=3 flagged this as a buffer overflow,
since the compiler is unable to see that the space beyond the allocation
was safe to use.

At that time, I thought this use was to avoid reallocating[1] when
there's enough space in the usable size and that is not entirely false.
I had then proposed during my Cauldron talk (and in discussions with
some of you) that maybe providing a fast path for cases where the new
size was within the current chunk size was the solution to the problem
systemd was trying to solve with malloc_usable_size.

However I was wrong, it looks like the malloc_usable_size usage goes far
beyond simply optimizing allocation, it is used as a way to query sizes
of objects and hence eliminating the need to pass their corresponding
sizes.  This is probably suboptimal (given that there's a call into
libc.so at every point instead of what could have been just an
additional parameter alongside the object) but it's the design pattern
they've chosen.

I have an idea to support this abuse and at the same time, satisfy the
compiler by giving it a hint of the new size.  This could be done within
systemd by calling a dummy allocator (e.g. expand_to_usable) with the
result of malloc_usable_size(), thus telling the compiler that the
object has been expanded to the usable size, thus making accesses into
the spare space well defined.  I have a patch too (see below) to systemd
that demonstrates how this could be achieved, it's been tested with gcc
as well as clang and with _FORTIFY_SOURCE=3.

The larger consequence of this patch though is that we further support
the usage of malloc_usable_size for cases beyond diagnostics.  Do we
want to do that?  If we do, should we also then make clear what kind of
usage we support as a library, say, in the manual?  We don't have a
manual blurb for malloc_usable_size, so maybe this is a good opportunity
to do that.

Any other thoughts on malloc_usable_size?

Thanks,
Sid


[1] https://developers.redhat.com/articles/2022/09/17/gccs-new-fortification-level#the_gains_of_improved_security_coverage_outweigh_the_cost

---
 src/basic/alloc-util.c     |  5 +++++
 src/basic/alloc-util.h     | 16 ++++++++++++++--
 src/test/test-alloc-util.c |  5 +++--
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/basic/alloc-util.c b/src/basic/alloc-util.c
index b030f454b2..58cf7c7433 100644
--- a/src/basic/alloc-util.c
+++ b/src/basic/alloc-util.c
@@ -102,3 +102,8 @@ void* greedy_realloc0(
 
         return q;
 }
+
+void *expand_to_usable (void *ptr, size_t newsize _unused_)
+{
+        return ptr;
+}
diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h
index b38db7d473..0c0b4851f5 100644
--- a/src/basic/alloc-util.h
+++ b/src/basic/alloc-util.h
@@ -4,6 +4,7 @@
 #include <alloca.h>
 #include <stddef.h>
 #include <stdlib.h>
+#include <malloc.h>
 #include <string.h>
 
 #include "macro.h"
@@ -184,6 +185,18 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
 #  define msan_unpoison(r, s)
 #endif
 
+void *expand_to_usable (void *ptr, size_t newsize) _alloc_ (2);
+
+static inline size_t
+_malloc_usable_size(void **ptr)
+{
+        if (*ptr == NULL)
+                return 0;
+        size_t full_size = malloc_usable_size (*ptr);
+        *ptr = expand_to_usable (*ptr, full_size);
+        return full_size;
+}
+
 /* This returns the number of usable bytes in a malloc()ed region as per malloc_usable_size(), in a way that
  * is compatible with _FORTIFY_SOURCES. If _FORTIFY_SOURCES is used many memory operations will take the
  * object size as returned by __builtin_object_size() into account. Hence, let's return the smaller size of
@@ -193,8 +206,7 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
  * too. Moreover, when NULL is passed malloc_usable_size() is documented to return zero, and
  * __builtin_object_size() returns SIZE_MAX too, hence we also return a sensible value of 0 in this corner
  * case. */
-#define MALLOC_SIZEOF_SAFE(x) \
-        MIN(malloc_usable_size(x), __builtin_object_size(x, 0))
+#define MALLOC_SIZEOF_SAFE(x) _malloc_usable_size((void **) &(x))
 
 /* Inspired by ELEMENTSOF() but operates on malloc()'ed memory areas: typesafely returns the number of items
  * that fit into the specified memory block */
diff --git a/src/test/test-alloc-util.c b/src/test/test-alloc-util.c
index df6139005f..f9fd192576 100644
--- a/src/test/test-alloc-util.c
+++ b/src/test/test-alloc-util.c
@@ -170,8 +170,9 @@ TEST(malloc_size_safe) {
         size_t n = 4711;
 
         /* Let's check the macros and built-ins work on NULL and return the expected values */
-        assert_se(MALLOC_ELEMENTSOF((float*) NULL) == 0);
-        assert_se(MALLOC_SIZEOF_SAFE((float*) NULL) == 0);
+        float *nullptr = NULL;
+        assert_se(MALLOC_ELEMENTSOF(nullptr) == 0);
+        assert_se(MALLOC_SIZEOF_SAFE(nullptr) == 0);
         assert_se(malloc_usable_size(NULL) == 0); /* as per man page, this is safe and defined */
         assert_se(__builtin_object_size(NULL, 0) == SIZE_MAX); /* as per docs SIZE_MAX is returned for pointers where the size isn't known */
 
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-11-24 21:32 [RFC] Supporting malloc_usable_size Siddhesh Poyarekar
@ 2022-12-02  4:42 ` DJ Delorie via Libc-alpha
  2022-12-02  5:00   ` Sam James via Libc-alpha
  2022-12-02 12:03 ` Andreas Schwab
  1 sibling, 1 reply; 25+ messages in thread
From: DJ Delorie via Libc-alpha @ 2022-12-02  4:42 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: libc-alpha

Siddhesh Poyarekar <siddhesh@gotplt.org> writes:
> At that time, I thought this use was to avoid reallocating[1] when

You can't do an optimal realloc if you don't know what the usable size
is, but once you know the optimal size, calling realloc() should be a
valid way of telling the compiler what you're doing.  We just need to
ensure that our realloc() does the sane thing in such cases and I see no
problem with users doing it.

> that maybe providing a fast path for cases where the new
> size was within the current chunk size was the solution to the problem
> systemd was trying to solve with malloc_usable_size.

I think a fast path check would be good for performance anyway, but
let's not call it a solution, because it won't change the functionality,
just the speed.

> it is used as a way to query sizes of objects and hence eliminating
> the need to pass their corresponding sizes.

Since malloc_usable_size is nonstandard and intended for debugging, this
is a bad programming practice (as noted in the man page).  As such, I
see no need to spend effort on it, either to block it or to optimize it.
Caveat programmer.  As long as the function returns the correct value, I
have no desire to worry about it further ;-)

> I have an idea to support this abuse and at the same time, satisfy the
> compiler by giving it a hint of the new size.

That's a lot of work to avoid a call to realloc().  And if they're
calling into libc to get a record size, they already don't care about
optimal performance.

> The larger consequence of this patch though is that we further support
> the usage of malloc_usable_size for cases beyond diagnostics.  Do we
> want to do that?

To what extend do we support it *at all*, other than "it returns the
right number at the time it was called" ?

> If we do, should we also then make clear what kind of usage we support
> as a library, say, in the manual?

Our man page already says "The main use of this function is for
debugging and introspection".  The BSD manual says "The
malloc_usable_size() function is not a mechanism for in-place realloc();
rather it is provided solely as a tool for introspection purposes."

So clarifying the manual to be more in line with BSD is probably OK but
anything further than that is IMHO an API change.

We may want to add a caveat that the returned value is only valid until
the next call to any malloc family function, though, although I don't
see any way our code could make the usable size of an allocated chunk
*smaller*.  I don't think we've ever guaranteed that the heap metadata
is constant.

Maybe as a lark we could make 1% of the calls return an obviously wrong
value?  ;-)


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-02  4:42 ` DJ Delorie via Libc-alpha
@ 2022-12-02  5:00   ` Sam James via Libc-alpha
  2022-12-02  5:28     ` DJ Delorie via Libc-alpha
  0 siblings, 1 reply; 25+ messages in thread
From: Sam James via Libc-alpha @ 2022-12-02  5:00 UTC (permalink / raw)
  To: DJ Delorie; +Cc: Siddhesh Poyarekar, libc-alpha

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



> On 2 Dec 2022, at 04:42, DJ Delorie via Libc-alpha <libc-alpha@sourceware.org> wrote:
> 
> [snip]

>> The larger consequence of this patch though is that we further support
>> the usage of malloc_usable_size for cases beyond diagnostics.  Do we
>> want to do that?
> 
> To what extend do we support it *at all*, other than "it returns the
> right number at the time it was called" ?

Right. It's still not clear to me if glibc is actually interested in supporting
the use case here. If it isn't, it should be stated clearly so it's clear
who is to blame when FORTIFY_SOURCE=3 complains.

(And it's also unclear to me that it should be supported, either.)

> 
>> If we do, should we also then make clear what kind of usage we support
>> as a library, say, in the manual?
> 
> Our man page already says "The main use of this function is for
> debugging and introspection".  The BSD manual says "The
> malloc_usable_size() function is not a mechanism for in-place realloc();
> rather it is provided solely as a tool for introspection purposes."
> 

My guess is the systemd maintainers currently rely on a specific interpretation
of "introspection" which may not align with glibc's.


[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 358 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-02  5:00   ` Sam James via Libc-alpha
@ 2022-12-02  5:28     ` DJ Delorie via Libc-alpha
  2022-12-02 12:36       ` Siddhesh Poyarekar
  0 siblings, 1 reply; 25+ messages in thread
From: DJ Delorie via Libc-alpha @ 2022-12-02  5:28 UTC (permalink / raw)
  To: Sam James; +Cc: siddhesh, libc-alpha

Sam James <sam@gentoo.org> writes:
> Right. It's still not clear to me if glibc is actually interested in supporting
> the use case here. If it isn't, it should be stated clearly so it's clear
> who is to blame when FORTIFY_SOURCE=3 complains.

I don't think it's up to glibc to support a "use case" per se.  The API
does what is documented, no more, no less.  As long as we function
"correctly", the users can abuse that functionality all they want.  My
opinion is just that, when they do that, it's up to them to make sure
their abuse plays well with other tools, like gcc and FORTIFY_SOURCE=3.

Hence my focus on documentation.

We can document what the APIs do.

We can provide a tutorial that helps people understand how the APIs work
together in a "best practices" way.

We can list caveats that document whar be dragons.

Beyond that, caveat programmer.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-11-24 21:32 [RFC] Supporting malloc_usable_size Siddhesh Poyarekar
  2022-12-02  4:42 ` DJ Delorie via Libc-alpha
@ 2022-12-02 12:03 ` Andreas Schwab
  2022-12-02 12:22   ` Siddhesh Poyarekar
  1 sibling, 1 reply; 25+ messages in thread
From: Andreas Schwab @ 2022-12-02 12:03 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: libc-alpha, fweimer, carlos

On Nov 24 2022, Siddhesh Poyarekar wrote:

> This is in context of this systemd issue:
>
> https://github.com/systemd/systemd/issues/22801
>
> through which I had discovered that systemd was (ab)using
> malloc_usable_size to use spare space in an allocated object.  This was
> discovered when _FORTIFY_SOURCE=3 flagged this as a buffer overflow,
> since the compiler is unable to see that the space beyond the allocation
> was safe to use.

Which it isn't.  Nothing prevents malloc to hand out the extra space to
a different thread any time, so the size returned by malloc_usable_size
can get outdated instantly.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-02 12:03 ` Andreas Schwab
@ 2022-12-02 12:22   ` Siddhesh Poyarekar
  2022-12-02 12:34     ` Andreas Schwab
  2022-12-02 12:54     ` Florian Weimer via Libc-alpha
  0 siblings, 2 replies; 25+ messages in thread
From: Siddhesh Poyarekar @ 2022-12-02 12:22 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: libc-alpha, fweimer, carlos

On 2022-12-02 07:03, Andreas Schwab wrote:
> On Nov 24 2022, Siddhesh Poyarekar wrote:
> 
>> This is in context of this systemd issue:
>>
>> https://github.com/systemd/systemd/issues/22801
>>
>> through which I had discovered that systemd was (ab)using
>> malloc_usable_size to use spare space in an allocated object.  This was
>> discovered when _FORTIFY_SOURCE=3 flagged this as a buffer overflow,
>> since the compiler is unable to see that the space beyond the allocation
>> was safe to use.
> 
> Which it isn't.  Nothing prevents malloc to hand out the extra space to
> a different thread any time, so the size returned by malloc_usable_size
> can get outdated instantly.

Not with the current malloc implementation I suppose but I get what you 
mean.  Florian had mentioned a similar caveat where a malloc 
implementation could coalesce adjacent free blocks with the end of an 
allocated block and change the value of malloc_usable_size at any 
arbitrary point in time too.

However the man page starts with "Although the excess bytes can be 
overwritten by the application without ill effects" and maybe that 
reassurance needs to be dropped.

Thanks,
Sid

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-02 12:22   ` Siddhesh Poyarekar
@ 2022-12-02 12:34     ` Andreas Schwab
  2022-12-02 12:39       ` Florian Weimer via Libc-alpha
  2022-12-02 12:54     ` Florian Weimer via Libc-alpha
  1 sibling, 1 reply; 25+ messages in thread
From: Andreas Schwab @ 2022-12-02 12:34 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: libc-alpha, fweimer, carlos

On Dez 02 2022, Siddhesh Poyarekar wrote:

> However the man page starts with "Although the excess bytes can be
> overwritten by the application without ill effects" and maybe that
> reassurance needs to be dropped.

Or perhaps amended: "until the next call to malloc/realloc/free in any
thread".

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-02  5:28     ` DJ Delorie via Libc-alpha
@ 2022-12-02 12:36       ` Siddhesh Poyarekar
  2022-12-02 19:16         ` DJ Delorie via Libc-alpha
  0 siblings, 1 reply; 25+ messages in thread
From: Siddhesh Poyarekar @ 2022-12-02 12:36 UTC (permalink / raw)
  To: DJ Delorie, Sam James; +Cc: libc-alpha

On 2022-12-02 00:28, DJ Delorie wrote:
> Sam James <sam@gentoo.org> writes:
>> Right. It's still not clear to me if glibc is actually interested in supporting
>> the use case here. If it isn't, it should be stated clearly so it's clear
>> who is to blame when FORTIFY_SOURCE=3 complains.
> 
> I don't think it's up to glibc to support a "use case" per se.  The API
> does what is documented, no more, no less.  As long as we function
> "correctly", the users can abuse that functionality all they want.  My
> opinion is just that, when they do that, it's up to them to make sure
> their abuse plays well with other tools, like gcc and FORTIFY_SOURCE=3.
> 
> Hence my focus on documentation.
> 
> We can document what the APIs do.
> 
> We can provide a tutorial that helps people understand how the APIs work
> together in a "best practices" way.
> 
> We can list caveats that document whar be dragons.
> 
> Beyond that, caveat programmer.

Thanks, from your and Sam's comments, one thing I can be sure of is that 
I (as glibc maintainer) should not be the one suggesting hacks that add 
some measure of safety to this use since that then may get misconstrued 
as endorsement by the glibc project.  It has happened before:

https://github.com/systemd/systemd/issues/22801#issuecomment-1073962482

Besides, both Andreas and Florian pointed out ways in which such 
malloc_usable_size could be unsafe despite current definitions, so that 
is further reason to not support this use case.

On to the alternative question then; given that the interface has 
minimal utility, unnecessarily exposes internal implementation caveats 
and is prone to abuse, does it make sense to deprecate it?  If not, does 
it make sense to make the note in the man page stronger by, e.g. 
removing the "without ill effects" and discourage its use for anything 
other than diagnostics?

Thanks,
Sid

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-02 12:34     ` Andreas Schwab
@ 2022-12-02 12:39       ` Florian Weimer via Libc-alpha
  2022-12-05 18:46         ` Zack Weinberg via Libc-alpha
  0 siblings, 1 reply; 25+ messages in thread
From: Florian Weimer via Libc-alpha @ 2022-12-02 12:39 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Siddhesh Poyarekar, libc-alpha, carlos

* Andreas Schwab:

> On Dez 02 2022, Siddhesh Poyarekar wrote:
>
>> However the man page starts with "Although the excess bytes can be
>> overwritten by the application without ill effects" and maybe that
>> reassurance needs to be dropped.
>
> Or perhaps amended: "until the next call to malloc/realloc/free in any
> thread".

The list will never be complete because glibc can call into the malloc
subsystem internally, or even spontaneously from an internal service
thread.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-02 12:22   ` Siddhesh Poyarekar
  2022-12-02 12:34     ` Andreas Schwab
@ 2022-12-02 12:54     ` Florian Weimer via Libc-alpha
  1 sibling, 0 replies; 25+ messages in thread
From: Florian Weimer via Libc-alpha @ 2022-12-02 12:54 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: Andreas Schwab, libc-alpha, carlos

* Siddhesh Poyarekar:

> On 2022-12-02 07:03, Andreas Schwab wrote:
>> On Nov 24 2022, Siddhesh Poyarekar wrote:
>> 
>>> This is in context of this systemd issue:
>>>
>>> https://github.com/systemd/systemd/issues/22801
>>>
>>> through which I had discovered that systemd was (ab)using
>>> malloc_usable_size to use spare space in an allocated object.  This was
>>> discovered when _FORTIFY_SOURCE=3 flagged this as a buffer overflow,
>>> since the compiler is unable to see that the space beyond the allocation
>>> was safe to use.
>> Which it isn't.  Nothing prevents malloc to hand out the extra space
>> to
>> a different thread any time, so the size returned by malloc_usable_size
>> can get outdated instantly.
>
> Not with the current malloc implementation I suppose but I get what
> you mean.  Florian had mentioned a similar caveat where a malloc 
> implementation could coalesce adjacent free blocks with the end of an
> allocated block and change the value of malloc_usable_size at any 
> arbitrary point in time too.
>
> However the man page starts with "Although the excess bytes can be
> overwritten by the application without ill effects" and maybe that 
> reassurance needs to be dropped.

I think that is part of the interface contract.

During the life-time of an allocation, the observed return value can
only ever grow, never shrink.  That's how I read the interface
description (because it doesn't say the value is constant).

However, systemd has cases which seem incompatible even with that: The
code derives an array length from the malloc_usable_size return value.
It assumes that if it has initialized the array up to that length at one
point, all array elements are initialized.  But when the array length is
recomputed, new uninitialized elements may appear, so that's not really
correct.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC] Supporting malloc_usable_size
@ 2022-12-02 13:54 Wilco Dijkstra via Libc-alpha
  0 siblings, 0 replies; 25+ messages in thread
From: Wilco Dijkstra via Libc-alpha @ 2022-12-02 13:54 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: 'GNU C Library'

Hi Siddhesh,

> Not with the current malloc implementation I suppose but I get what you 
> mean.  Florian had mentioned a similar caveat where a malloc 
> implementation could coalesce adjacent free blocks with the end of an 
> allocated block and change the value of malloc_usable_size at any 
> arbitrary point in time too.

A different allocator might keep track of separate values for requested and
allocated block sizes. Then it could reduce the allocated block size and thus
malloc_usable_size. So unless we clearly specify the guarantees, one has to
assume the malloc_usable_size is unsafe to be used.

> However the man page starts with "Although the excess bytes can be 
> overwritten by the application without ill effects" and maybe that 
> reassurance needs to be dropped.

If we ever allow use of the extra memory returned by malloc_usable_size, the
implementation *must* be identical to performing a realloc that returns the
original pointer (as in, if we keep track of the actual size passed to malloc, or
do security stuff like pointer tagging, we must update all that in every
malloc_usable_size call).

So we could redefine malloc_usable_size in terms of being equivalent to realloc
(which will make it more complex and expensive), or say that you must never use
the extra space and make it a debug-only feature. My preference is the latter
since we already have realloc, and if we ensure it's efficient, there is no real need
for user code to ever use a non-standard interface.

Cheers,
Wilco

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-02 12:36       ` Siddhesh Poyarekar
@ 2022-12-02 19:16         ` DJ Delorie via Libc-alpha
  2022-12-02 19:49           ` Siddhesh Poyarekar
  0 siblings, 1 reply; 25+ messages in thread
From: DJ Delorie via Libc-alpha @ 2022-12-02 19:16 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: sam, libc-alpha

Siddhesh Poyarekar <siddhesh@gotplt.org> writes:
> On to the alternative question then; given that the interface has 
> minimal utility, unnecessarily exposes internal implementation caveats 
> and is prone to abuse, does it make sense to deprecate it?  If not, does 
> it make sense to make the note in the man page stronger by, e.g. 
> removing the "without ill effects" and discourage its use for anything 
> other than diagnostics?

I see no reason to deprecate this call, as long as it does what it's
documented to do.  Just because we think it's a bad API doesn't mean
some other developer won't find it immensely useful in some way we
haven't imagined.

Existing notes:

  The value returned by malloc_usable_size() may be greater than the
  requested size of the allocation because of alignment and minimum size
  constraints.  Although the excess bytes can be overwritten by the
  application without ill effects, this is not good programming
  practice: the number of excess bytes in an allocation depends on the
  underlying implementation.

Suggested text:?

  The value returned by malloc_usable_size() may be greater than the
  requested size of the allocation because of various internal
  implementation details, none of which the programmer should rely on.
  This function is intended to only be used for diagnostics and
  statistics; writing to the excess memory without first calling
  realloc() to resize the allocation is not supported.  The returned
  value is only valid at the time of the call; any other call to a
  malloc family API may invalidate it.

I think this is as harsh as we should go, and I'm not opposed to
removing any of the above if we think it oversteps the ABI bounds.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-02 19:16         ` DJ Delorie via Libc-alpha
@ 2022-12-02 19:49           ` Siddhesh Poyarekar
  2022-12-02 19:57             ` DJ Delorie via Libc-alpha
  0 siblings, 1 reply; 25+ messages in thread
From: Siddhesh Poyarekar @ 2022-12-02 19:49 UTC (permalink / raw)
  To: DJ Delorie; +Cc: sam, libc-alpha

On 2022-12-02 14:16, DJ Delorie wrote:
>    The value returned by malloc_usable_size() may be greater than the
>    requested size of the allocation because of various internal
>    implementation details, none of which the programmer should rely on.
>    This function is intended to only be used for diagnostics and
>    statistics; writing to the excess memory without first calling
>    realloc() to resize the allocation is not supported.  The returned
>    value is only valid at the time of the call; any other call to a
>    malloc family API may invalidate it.

That sounds reasonable.  I wonder if the last statement could be taken 
as a guarantee of validity up to a certain point (i.e. another call to a 
malloc family API); should that be simply "The returned value is only 
valid at the time of the call."?

Thanks,
Sid

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-02 19:49           ` Siddhesh Poyarekar
@ 2022-12-02 19:57             ` DJ Delorie via Libc-alpha
  0 siblings, 0 replies; 25+ messages in thread
From: DJ Delorie via Libc-alpha @ 2022-12-02 19:57 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: sam, libc-alpha

Siddhesh Poyarekar <siddhesh@gotplt.org> writes:
> That sounds reasonable.  I wonder if the last statement could be taken 
> as a guarantee of validity up to a certain point (i.e. another call to a 
> malloc family API); should that be simply "The returned value is only 
> valid at the time of the call."?

Good point.  Agreed.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-02 12:39       ` Florian Weimer via Libc-alpha
@ 2022-12-05 18:46         ` Zack Weinberg via Libc-alpha
  2022-12-05 19:04           ` Siddhesh Poyarekar
  2022-12-05 20:35           ` Florian Weimer via Libc-alpha
  0 siblings, 2 replies; 25+ messages in thread
From: Zack Weinberg via Libc-alpha @ 2022-12-05 18:46 UTC (permalink / raw)
  To: libc-alpha

On 2022-12-02 7:39 AM, Florian Weimer via Libc-alpha wrote:
> * Andreas Schwab:
> 
>> On Dez 02 2022, Siddhesh Poyarekar wrote:
>>
>>> However the man page starts with "Although the excess bytes can be
>>> overwritten by the application without ill effects" and maybe that
>>> reassurance needs to be dropped.
>>
>> Or perhaps amended: "until the next call to malloc/realloc/free in any
>> thread".
> 
> The list will never be complete because glibc can call into the malloc
> subsystem internally

How about this then?  "The excess bytes, if any, are only guaranteed to 
exist until the next call to malloc/realloc/free in any thread.  Note 
that almost all C library functions are allowed to use malloc internally 
for scratch space, and the list of functions that do so may change 
without notice.  Only the functions documented as async-signal-safe are 
guaranteed not to use malloc internally."

> or even spontaneously from an internal service thread

We don't have any of those now, do we?  I'm inclined to say that we 
_shouldn't_ have any of those.

zw


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-05 18:46         ` Zack Weinberg via Libc-alpha
@ 2022-12-05 19:04           ` Siddhesh Poyarekar
  2022-12-05 20:35           ` Florian Weimer via Libc-alpha
  1 sibling, 0 replies; 25+ messages in thread
From: Siddhesh Poyarekar @ 2022-12-05 19:04 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha; +Cc: DJ Delorie

On 2022-12-05 13:46, Zack Weinberg via Libc-alpha wrote:
> On 2022-12-02 7:39 AM, Florian Weimer via Libc-alpha wrote:
>> * Andreas Schwab:
>>
>>> On Dez 02 2022, Siddhesh Poyarekar wrote:
>>>
>>>> However the man page starts with "Although the excess bytes can be
>>>> overwritten by the application without ill effects" and maybe that
>>>> reassurance needs to be dropped.
>>>
>>> Or perhaps amended: "until the next call to malloc/realloc/free in any
>>> thread".
>>
>> The list will never be complete because glibc can call into the malloc
>> subsystem internally
> 
> How about this then?  "The excess bytes, if any, are only guaranteed to 
> exist until the next call to malloc/realloc/free in any thread.  Note 
> that almost all C library functions are allowed to use malloc internally 
> for scratch space, and the list of functions that do so may change 
> without notice.  Only the functions documented as async-signal-safe are 
> guaranteed not to use malloc internally."

DJ has also made a suggestion for this[1], which seems similar to what 
you have.  The only concern I have is the additional guarantee the text 
appears to provide (valid till the next allocator call); I'd personally 
prefer something that gives absolutely no guarantees.

Maybe one of you could volunteer to propose this to the man pages project?

Thanks,
Sid

[1] https://sourceware.org/pipermail/libc-alpha/2022-December/143701.html

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-05 18:46         ` Zack Weinberg via Libc-alpha
  2022-12-05 19:04           ` Siddhesh Poyarekar
@ 2022-12-05 20:35           ` Florian Weimer via Libc-alpha
  2022-12-06 19:25             ` Siddhesh Poyarekar
  1 sibling, 1 reply; 25+ messages in thread
From: Florian Weimer via Libc-alpha @ 2022-12-05 20:35 UTC (permalink / raw)
  To: Zack Weinberg via Libc-alpha; +Cc: Zack Weinberg

* Zack Weinberg via Libc-alpha:

> On 2022-12-02 7:39 AM, Florian Weimer via Libc-alpha wrote:
>> * Andreas Schwab:
>> 
>>> On Dez 02 2022, Siddhesh Poyarekar wrote:
>>>
>>>> However the man page starts with "Although the excess bytes can be
>>>> overwritten by the application without ill effects" and maybe that
>>>> reassurance needs to be dropped.
>>>
>>> Or perhaps amended: "until the next call to malloc/realloc/free in any
>>> thread".
>> The list will never be complete because glibc can call into the
>> malloc
>> subsystem internally
>
> How about this then?  "The excess bytes, if any, are only guaranteed
> to exist until the next call to malloc/realloc/free in any thread.
> Note that almost all C library functions are allowed to use malloc
> internally for scratch space, and the list of functions that do so may
> change without notice.  Only the functions documented as
> async-signal-safe are guaranteed not to use malloc internally."

I think it's a backwards-incompatible change.  The existing manual page
documents the function as MT-Safe.

With this new policy, I don't think malloc_usable_size is useful for
anything at all, and we can just deprecate it (with a deprecation
warning message) and eventually remove it from linking (after
considering the impact on replacement malloc implementations, but I
don't think it will be problematic).

>> or even spontaneously from an internal service thread
>
> We don't have any of those now, do we?  I'm inclined to say that we
> _shouldn't_ have any of those.

mq_notify and timer_create do this, I think.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-05 20:35           ` Florian Weimer via Libc-alpha
@ 2022-12-06 19:25             ` Siddhesh Poyarekar
  2022-12-07 10:01               ` Florian Weimer via Libc-alpha
  0 siblings, 1 reply; 25+ messages in thread
From: Siddhesh Poyarekar @ 2022-12-06 19:25 UTC (permalink / raw)
  To: Florian Weimer, Zack Weinberg via Libc-alpha; +Cc: Zack Weinberg

On 2022-12-05 15:35, Florian Weimer via Libc-alpha wrote:
> I think it's a backwards-incompatible change.  The existing manual page
> documents the function as MT-Safe.
> 
> With this new policy, I don't think malloc_usable_size is useful for
> anything at all, and we can just deprecate it (with a deprecation
> warning message) and eventually remove it from linking (after
> considering the impact on replacement malloc implementations, but I
> don't think it will be problematic).

We don't have consensus on deprecation unfortunately.  DJ is of the 
opinion that the limited use (knowing the usable size but not being able 
to do anything with it) may be useful enough for some programs.  With 
that position, making it clear that the extra space is never safely 
usable and then just leaving it at that is probably the least worst out.

Sid

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-06 19:25             ` Siddhesh Poyarekar
@ 2022-12-07 10:01               ` Florian Weimer via Libc-alpha
  2022-12-07 16:34                 ` Siddhesh Poyarekar
  2022-12-07 18:45                 ` DJ Delorie via Libc-alpha
  0 siblings, 2 replies; 25+ messages in thread
From: Florian Weimer via Libc-alpha @ 2022-12-07 10:01 UTC (permalink / raw)
  To: Siddhesh Poyarekar
  Cc: Zack Weinberg via Libc-alpha, Zack Weinberg, DJ Delorie

* Siddhesh Poyarekar:

> On 2022-12-05 15:35, Florian Weimer via Libc-alpha wrote:
>> I think it's a backwards-incompatible change.  The existing manual page
>> documents the function as MT-Safe.
>> With this new policy, I don't think malloc_usable_size is useful for
>> anything at all, and we can just deprecate it (with a deprecation
>> warning message) and eventually remove it from linking (after
>> considering the impact on replacement malloc implementations, but I
>> don't think it will be problematic).
>
> We don't have consensus on deprecation unfortunately.  DJ is of the
> opinion that the limited use (knowing the usable size but not being
> able to do anything with it) may be useful enough for some programs.
> With that position, making it clear that the extra space is never
> safely usable and then just leaving it at that is probably the least
> worst out.

Maybe we could add a deprecation warning just for -D_FORTIFY_SOURCE=3?

DJ, what do you think?

Thanks,
Florian


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-07 10:01               ` Florian Weimer via Libc-alpha
@ 2022-12-07 16:34                 ` Siddhesh Poyarekar
  2022-12-07 16:54                   ` Adhemerval Zanella Netto via Libc-alpha
  2022-12-07 18:45                 ` DJ Delorie via Libc-alpha
  1 sibling, 1 reply; 25+ messages in thread
From: Siddhesh Poyarekar @ 2022-12-07 16:34 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Zack Weinberg via Libc-alpha, Zack Weinberg, DJ Delorie

On 2022-12-07 05:01, Florian Weimer wrote:
> * Siddhesh Poyarekar:
> 
>> On 2022-12-05 15:35, Florian Weimer via Libc-alpha wrote:
>>> I think it's a backwards-incompatible change.  The existing manual page
>>> documents the function as MT-Safe.
>>> With this new policy, I don't think malloc_usable_size is useful for
>>> anything at all, and we can just deprecate it (with a deprecation
>>> warning message) and eventually remove it from linking (after
>>> considering the impact on replacement malloc implementations, but I
>>> don't think it will be problematic).
>>
>> We don't have consensus on deprecation unfortunately.  DJ is of the
>> opinion that the limited use (knowing the usable size but not being
>> able to do anything with it) may be useful enough for some programs.
>> With that position, making it clear that the extra space is never
>> safely usable and then just leaving it at that is probably the least
>> worst out.
> 
> Maybe we could add a deprecation warning just for -D_FORTIFY_SOURCE=3?

I'm all for deprecation, at least partial if not full.

Thanks,
Sid

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-07 16:34                 ` Siddhesh Poyarekar
@ 2022-12-07 16:54                   ` Adhemerval Zanella Netto via Libc-alpha
  2022-12-07 16:57                     ` Sam James via Libc-alpha
                                       ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: Adhemerval Zanella Netto via Libc-alpha @ 2022-12-07 16:54 UTC (permalink / raw)
  To: Siddhesh Poyarekar, Florian Weimer
  Cc: Zack Weinberg via Libc-alpha, Zack Weinberg, DJ Delorie



On 07/12/22 13:34, Siddhesh Poyarekar wrote:
> On 2022-12-07 05:01, Florian Weimer wrote:
>> * Siddhesh Poyarekar:
>>
>>> On 2022-12-05 15:35, Florian Weimer via Libc-alpha wrote:
>>>> I think it's a backwards-incompatible change.  The existing manual page
>>>> documents the function as MT-Safe.
>>>> With this new policy, I don't think malloc_usable_size is useful for
>>>> anything at all, and we can just deprecate it (with a deprecation
>>>> warning message) and eventually remove it from linking (after
>>>> considering the impact on replacement malloc implementations, but I
>>>> don't think it will be problematic).
>>>
>>> We don't have consensus on deprecation unfortunately.  DJ is of the
>>> opinion that the limited use (knowing the usable size but not being
>>> able to do anything with it) may be useful enough for some programs.
>>> With that position, making it clear that the extra space is never
>>> safely usable and then just leaving it at that is probably the least
>>> worst out.
>>
>> Maybe we could add a deprecation warning just for -D_FORTIFY_SOURCE=3?
> 
> I'm all for deprecation, at least partial if not full.
> 
> Thanks,
> Sid

I tend to agree with full deprecation, systemd MALLOC_SIZEOF_SAFE is an
example of what user needs to hack around with an ill defined interface and
_FORTIFY_SOURCE=3 warning should be clear that keep it is not a gain in long 
term (besides adding even more trouble for portability).

Another possibility would to make malloc_usable_size always return the malloc
size argument (although it would add some internal metadata costs).

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-07 16:54                   ` Adhemerval Zanella Netto via Libc-alpha
@ 2022-12-07 16:57                     ` Sam James via Libc-alpha
  2022-12-07 17:39                     ` Florian Weimer via Libc-alpha
  2022-12-09 15:42                     ` Siddhesh Poyarekar
  2 siblings, 0 replies; 25+ messages in thread
From: Sam James via Libc-alpha @ 2022-12-07 16:57 UTC (permalink / raw)
  To: Adhemerval Zanella Netto
  Cc: Siddhesh Poyarekar, Florian Weimer, Zack Weinberg via Libc-alpha,
	Zack Weinberg, DJ Delorie

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



> On 7 Dec 2022, at 16:54, Adhemerval Zanella Netto via Libc-alpha <libc-alpha@sourceware.org> wrote:
> [snip]

> I tend to agree with full deprecation, systemd MALLOC_SIZEOF_SAFE is an
> example of what user needs to hack around with an ill defined interface and
> _FORTIFY_SOURCE=3 warning should be clear that keep it is not a gain in long
> term (besides adding even more trouble for portability).
> 
> Another possibility would to make malloc_usable_size always return the malloc
> size argument (although it would add some internal metadata costs).

My position is already clear (full deprecation), but if someone does feel
it's useful fo them, they can always speak up over the lengthy
deprecation period anyway. It could always be reversed if necessary.


[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 358 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-07 16:54                   ` Adhemerval Zanella Netto via Libc-alpha
  2022-12-07 16:57                     ` Sam James via Libc-alpha
@ 2022-12-07 17:39                     ` Florian Weimer via Libc-alpha
  2022-12-09 15:42                     ` Siddhesh Poyarekar
  2 siblings, 0 replies; 25+ messages in thread
From: Florian Weimer via Libc-alpha @ 2022-12-07 17:39 UTC (permalink / raw)
  To: Adhemerval Zanella Netto
  Cc: Siddhesh Poyarekar, Zack Weinberg via Libc-alpha, Zack Weinberg,
	DJ Delorie

* Adhemerval Zanella Netto:

> Another possibility would to make malloc_usable_size always return the
> malloc size argument (although it would add some internal metadata
> costs).

We can probably implement it with little overhead, even on 32 bit, but a
size-class-based allocator will require more drastic changes.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-07 10:01               ` Florian Weimer via Libc-alpha
  2022-12-07 16:34                 ` Siddhesh Poyarekar
@ 2022-12-07 18:45                 ` DJ Delorie via Libc-alpha
  1 sibling, 0 replies; 25+ messages in thread
From: DJ Delorie via Libc-alpha @ 2022-12-07 18:45 UTC (permalink / raw)
  To: Florian Weimer; +Cc: siddhesh, libc-alpha, zack

Florian Weimer <fweimer@redhat.com> writes:
> DJ, what do you think?

The world seems set against me to get rid of this API, so don't let me
stop you.  I just don't see the point, especially as other packages use
it and will FTBFS when it's removed.

Also, BSD provides this API too.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC] Supporting malloc_usable_size
  2022-12-07 16:54                   ` Adhemerval Zanella Netto via Libc-alpha
  2022-12-07 16:57                     ` Sam James via Libc-alpha
  2022-12-07 17:39                     ` Florian Weimer via Libc-alpha
@ 2022-12-09 15:42                     ` Siddhesh Poyarekar
  2 siblings, 0 replies; 25+ messages in thread
From: Siddhesh Poyarekar @ 2022-12-09 15:42 UTC (permalink / raw)
  To: Adhemerval Zanella Netto, Florian Weimer
  Cc: Zack Weinberg via Libc-alpha, Zack Weinberg, DJ Delorie

On 2022-12-07 11:54, Adhemerval Zanella Netto wrote:
> I tend to agree with full deprecation, systemd MALLOC_SIZEOF_SAFE is an
> example of what user needs to hack around with an ill defined interface and
> _FORTIFY_SOURCE=3 warning should be clear that keep it is not a gain in long
> term (besides adding even more trouble for portability).
> 
> Another possibility would to make malloc_usable_size always return the malloc
> size argument (although it would add some internal metadata costs).
> 

Do we want to go down this path?  I was quite reluctant until I 
remembered that there's P0401R6 for C++ that would need this kind of 
information for support anyway.  The intent of that paper is different, 
it's to optimize for realloc and that would actually need us to endorse 
the chunk size as the actual size when we return it.  That would then 
disallow chunks from being consolidated, thus making usable size 
consistent through the lifetime of the object.

Basically, it looks like one way or another, there's value in making the 
return value of malloc_usable_size consistent and maybe even usable for 
writes if we are to support something like P0401R6 in future and 
instead, help the compiler see this usable size.

Thoughts?

Thanks,
Siddhesh

[1] 
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0401r6.html#deallocate

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2022-12-09 15:43 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-24 21:32 [RFC] Supporting malloc_usable_size Siddhesh Poyarekar
2022-12-02  4:42 ` DJ Delorie via Libc-alpha
2022-12-02  5:00   ` Sam James via Libc-alpha
2022-12-02  5:28     ` DJ Delorie via Libc-alpha
2022-12-02 12:36       ` Siddhesh Poyarekar
2022-12-02 19:16         ` DJ Delorie via Libc-alpha
2022-12-02 19:49           ` Siddhesh Poyarekar
2022-12-02 19:57             ` DJ Delorie via Libc-alpha
2022-12-02 12:03 ` Andreas Schwab
2022-12-02 12:22   ` Siddhesh Poyarekar
2022-12-02 12:34     ` Andreas Schwab
2022-12-02 12:39       ` Florian Weimer via Libc-alpha
2022-12-05 18:46         ` Zack Weinberg via Libc-alpha
2022-12-05 19:04           ` Siddhesh Poyarekar
2022-12-05 20:35           ` Florian Weimer via Libc-alpha
2022-12-06 19:25             ` Siddhesh Poyarekar
2022-12-07 10:01               ` Florian Weimer via Libc-alpha
2022-12-07 16:34                 ` Siddhesh Poyarekar
2022-12-07 16:54                   ` Adhemerval Zanella Netto via Libc-alpha
2022-12-07 16:57                     ` Sam James via Libc-alpha
2022-12-07 17:39                     ` Florian Weimer via Libc-alpha
2022-12-09 15:42                     ` Siddhesh Poyarekar
2022-12-07 18:45                 ` DJ Delorie via Libc-alpha
2022-12-02 12:54     ` Florian Weimer via Libc-alpha
  -- strict thread matches above, loose matches on Subject: below --
2022-12-02 13:54 Wilco Dijkstra via Libc-alpha

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).