Am Dienstag, dem 19.11.2024 um 09:18 -0800 schrieb Kees Cook:
> On Tue, Nov 19, 2024 at 05:41:13PM +0100, Martin Uecker wrote:
> > Am Dienstag, dem 19.11.2024 um 10:47 -0500 schrieb Marek Polacek:
> > > On Mon, Nov 18, 2024 at 07:10:35PM +0100, Martin Uecker wrote:
> > > > Am Montag, dem 18.11.2024 um 17:55 +0000 schrieb Qing Zhao:
> > > > > Hi,
> > > > > 
> > > > > I am working on extending “counted_by” attribute to pointers inside a 
> > > > > structure per our previous discussion. 
> > > > > 
> > > > > I need advice on the following question:
> > > > > 
> > > > > Should -fsantize=bounds support array reference that was referenced 
> > > > > through a pointer that has counted_by attribute? 
> > > 
> > > I don't see why it couldn't, perhaps as part of -fsanitize=bounds-strict.
> > > Someone has to implement it, though.
> > 
> > I think Qing was volunteering to do this.  My point was that
> > this would not necessarily be undefined behavior, but instead
> > could trap for possibly defined behavior.  I would not mind, but
> > I point out that in the past people insisted that the sanitizers
> > are only intended to screen for undefined behavior.
> 
> I think it's a mistake to confuse the sanitizers with only addressing
> "undefined behavior". The UB sanitizers are just a subset of the
> sanitizers in general, and I think UB is a not a good category for how
> to group the behaviors.
> 
> For the Linux kernel, we want robustness. UB leads to ambiguity, so
> we're quite interested in getting rid of UB, but the bounds sanitizer is
> expected to implement bounds checking, regardless of UB-ness.
> 
> I would absolutely want -fsanitize=bounds to check the construct Qing
> mentioned.
> 
> Another aspect I want to capture for Linux is _pointer_ bounds, so that
> this would be caught:
> 
> #include <stdlib.h>
> 
> struct annotated {
>   int b;
>   int *c __attribute__ ((counted_by (b)));
> } *p_array_annotated;
> 
> void __attribute__((__noinline__)) setup (int annotated_count)
> {
>   p_array_annotated
>     = (struct annotated *)malloc (sizeof (struct annotated));
>   p_array_annotated->c = (int *) malloc (annotated_count *  sizeof (int));
>   p_array_annotated->b = annotated_count;
> 
>   return;
> }
> 
> int main(int argc, char *argv[])
> {
>   int i;
>   int *c;
> 
>   setup (10);
>   c = p_array_annotated->c;
>   for (i = 0; i < 11; i++)
>     *c++ = 2; // goes boom at i == 10
>   return 0;
> }
> 
> This may be a separate sanitizer, and it may require a totally different
> set of internal tracking, but being able to discover that we've run off
> the end of an allocation is needed.
> 
> Of course, the biggest deal is that
> __builtin_dynamic_object_size(p_array_annotated->c, 1) will return
> 10 * sizeof(*p_array_annotated->c)

I want this too. The plan preliminary discussed in WG14 is to
have a proper language extension for this, tentatively:

struct foo {
  int n;
  char (*p)[.n];
};

(details to change, the syntax is what I would like to havE)



> > 
> > >  
> > > > I think the question is what -fsanitize=bounds is meant to be.
> > > > 
> > > > I am a bit frustrated about the sanitizer.  On the
> > > > one hand, it is not doing enough to get spatial memory
> > > > safety even where this would be easily possible, on the
> > > > other hand, is pedantic about things which are technically
> > > > UB but not problematic and then one is prevented from
> > > > using it
> > > > 
> > > > When used in default mode, where execution continues, it
> > > > also does not mix well with many warning, creates more code,
> > > > and pulls in a libary dependency (and the library also depends
> > > > on upstream choices / progress which seems a limitation for
> > > > extensions).
> > > > 
> > > > What IMHO would be ideal is a protection mode for spatial
> > > > memory safety that simply adds traps (which then requires
> > > > no library, has no issues with other warnings, and could
> > > > evolve independently from clang) 
> > > > 
> > > > So shouldn't we just add a -fboundscheck (which would 
> > > > be like -fsanitize=bounds -fsanitize-trap=bounds just with
> > > > more checking) and make it really good? I think many people
> > > > would be very happy about this.
> > > 
> > > That's a separate concern.  We already have the -fbounds-check option,
> > > currently only used in Fortran (and D?), so perhaps we could make
> > > that option a shorthand for -fsanitize=bounds -fsanitize-trap=bounds.
> > 
> > I think it could share large parts of the implementation, but the
> > main reason for having a separate option would be to do something
> > better than the sanitizer.  So it could not simply be a shorthand.
> 
> I don't want to reinvent the wheel here -- the sanitizers already have 3
> modes of operation (trap, callback with details, callback without
> details), and Linux uses the first 2 modes already, and has had plans to
> use the third (smaller resulting image).
> 
> Most notably, Linux _must_ have a warn-only mode or the feature will
> never get merged (this is a hard requirement from Linus). All serious
> deployments of the feature will use either trap mode or use the
> trap-on-warn setting, of course. But for the feature to even see the
> light of day, Linus requires there be a warn-only mode.
> 
> So, given these requirements, continuing to use the sanitizer framework
> seems much simpler to me. :)

This sounds reasonable. My remaining issue with the sanitizers
is that they are difficult to extend.  If they had a single
entry point where you can synthesize a call that simply passes
the right message then this would be much easier.

Martin



Reply via email to