ksummit.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: "NeilBrown" <neilb@suse.de>
To: "Arnd Bergmann" <arnd@arndb.de>
Cc: "Laurent Pinchart" <laurent.pinchart@ideasonboard.com>,
	"Geert Uytterhoeven" <geert@linux-m68k.org>,
	"Dan Carpenter" <dan.carpenter@oracle.com>,
	ksummit@lists.linux.dev, "Julia Lawall" <julia.lawall@inria.fr>
Subject: Re: Potential static analysis ideas
Date: Tue, 27 Jul 2021 07:43:09 +1000	[thread overview]
Message-ID: <162733578909.4153.5076277531962816764@noble.neil.brown.name> (raw)
In-Reply-To: <CAK8P3a2nm0fTf9-_sy9RTEaQv0yRqPHv_v+ZMX1yU=Pqj7idzw@mail.gmail.com>

On Mon, 26 Jul 2021, Arnd Bergmann wrote:
> On Sun, Jul 25, 2021 at 1:45 AM NeilBrown <neilb@suse.de> wrote:
> > On Sun, 25 Jul 2021, Laurent Pinchart wrote:
> > > >
> > > > To make it work well, you need to know if frob() and/or the current
> > > > function return an error code or not.  While you can use some heuristics
> > > > (e.g. is there any return -Exxx), perhaps we can add an annotation to
> > > > indicate if a function returns an error code, or an error pointer?
> > >
> > > https://lore.kernel.org/linux-media/YNMvarFl%2FKU1pGCG@pendragon.ideasonboard.com/
> > >
> > > I think it would be useful, if not for the tools, at least for
> > > developers.
> >
> > Agreed.  I added some code to smatch so that I could annotate pointers to
> > say if they are allowed to be NULL.  The implementation isn't perfect,
> > but I love having that extra documentation about when I do or don't have
> > to check for NULL.
> 
> I can think of four different annotations that limit what a pointer return from
> a function can be:
> 
> a) either a valid pointer or NULL, but never an error pointer,
> b) either a valid pointer or an error pointer, but not NULL,
> c) always a valid pointer, never NULL or an error,
> d) always NULL, but callers are expected to check for error pointers.
> 
> The last one is the tricky bit because there are a couple of subsystems
> that intentionally return an opaque NULL pointer to indicate success
> when the subsystem is compile-time disabled, and expect callers to not
> dereference that pointer but instead pass it into other stubbed-out
> interfaces. I think this one is rather specific to the kernel, but also really
> useful to have in a static checker because everyone gets those wrong.

And now we see the worms wriggling their way out of the can....

Some pointers can also have the 'lsb' overloaded, sometimes as a
bit-spin-lock.
And pointers stored in a structure can have temporal type requirements -
different at various places in the life cycle.
Most obviously, "non-NULL" pointers can be NULL (or unitiallised) during
inititalization, and may have other inconsistencies during finalization.
But it isn't hard to find more complexity.

"context" structures are particularly suseptible to this.  I've been
looking at 'struct fs_context' recently.  Normally you would use one of
the allocation functions which will always set ->ops and a few other
fields. So maybe ->ops is "always valid".
Then you initialize some extra bits.  Maybe call vfs_parse_fs_string()
etc.
Finally you call vfs_create_mount().  But you *can* call
vfs_create_mount() after only setting ->root ->sb_flags and ->source.
->ops can be uninitialised!

So what annotations would you give to the various fields? To capture
this completely you would need a series of sub-types of 'fs_context',
each with different guarantees or requirements about the values of
different fields.

I love contemplating what the "perfect" system would be, but I doubt a
near-perfect system would be much fun to program in, and that last 20%
to get to perfection would take a while.

So if we wanted to do something like this, it would need to be
completely opt-in.  The default would be current behaviour, and we would
want to have annotations for both what is, and what isn't, promised.

"what is" would be something like "this pointer is never NULL".
"what isn't" would be more like __must_check.  "this pointer might be
NULL and you really have to check before you dereference it".
For an unannotated pointer, it is not an error to test if it is NULL, or
to dereference without testing.

And, of course, we would need to be able to cast between the different
promises.

NeilBrown

  parent reply	other threads:[~2021-07-26 21:43 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-23 19:10 Potential static analysis ideas Dan Carpenter
2021-07-24 13:33 ` Geert Uytterhoeven
2021-07-24 13:40   ` Julia Lawall
2021-07-24 14:08   ` Arnd Bergmann
2021-07-24 23:18   ` Laurent Pinchart
2021-07-24 23:45     ` NeilBrown
2021-07-26  7:25       ` Arnd Bergmann
2021-07-26  7:53         ` Geert Uytterhoeven
2021-07-26  8:20           ` Arnd Bergmann
2021-07-26  8:39             ` Geert Uytterhoeven
2021-07-26  8:52               ` Arnd Bergmann
2021-07-26  9:11                 ` Geert Uytterhoeven
2021-07-26  8:55             ` Julia Lawall
2021-07-26  9:08               ` Hannes Reinecke
2021-07-26  9:16                 ` Geert Uytterhoeven
2021-07-26  9:28                   ` Julia Lawall
2021-07-26  9:35                     ` Hannes Reinecke
2021-07-26 10:03                       ` Julia Lawall
2021-07-26 17:54                   ` James Bottomley
2021-07-26 18:16                     ` Linus Torvalds
2021-07-26 21:53                       ` NeilBrown
2021-07-26 18:31                     ` Laurent Pinchart
2021-07-26  9:17                 ` Dan Carpenter
2021-07-26  9:13             ` Dan Carpenter
2021-07-26 21:43         ` NeilBrown [this message]
2021-07-26  7:05   ` Dan Carpenter
2021-07-26 15:50 ` Paul E. McKenney
2021-07-27  9:38   ` Dan Carpenter
2021-07-27  9:50     ` Geert Uytterhoeven
2021-07-27 16:06     ` Paul E. McKenney

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=162733578909.4153.5076277531962816764@noble.neil.brown.name \
    --to=neilb@suse.de \
    --cc=arnd@arndb.de \
    --cc=dan.carpenter@oracle.com \
    --cc=geert@linux-m68k.org \
    --cc=julia.lawall@inria.fr \
    --cc=ksummit@lists.linux.dev \
    --cc=laurent.pinchart@ideasonboard.com \
    /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 NNTP newsgroup(s).