Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Jan 2014 21:05:54 -0500 (EST)
From:      Rick Macklem <rmacklem@uoguelph.ca>
To:        Roman Divacky <rdivacky@freebsd.org>
Cc:        Dimitry Andric <dim@FreeBSD.org>, fs@FreeBSD.org
Subject:   Re: BUG: possible NULL pointer dereference in nfs server
Message-ID:  <1647701889.16319715.1390701954380.JavaMail.root@uoguelph.ca>
In-Reply-To: <20140126051258.M1750@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Bruce Evans wrote:
> On Sat, 25 Jan 2014, Dimitry Andric wrote:
> 
> > On 25 Jan 2014, at 01:38, Rick Macklem <rmacklem@uoguelph.ca>
> > wrote:
> > ...
> > If it inlines this, the result looks approximately like:
> >
> >     1	{
> >     2		fhandle_t *fhp = NULL;
> >     3		struct nfslockfile *new_lfp;
> >     4		int error;
> >     5
> >     6		if (new_stp->ls_flags & NFSLCK_OPEN) {
> >     7			new_lfp = *NULL;
> >     8			fhp = &new_lfp->lf_fh;
> >     9		} else if (&nfh) {
> >    10			fhp = &nfh;
> >    11		} else {
> >    12			panic("nfsrv_getlockfh");
> >    13		}
> >    14		error = nfsvno_getfh(vp, fhp, p);
> >    15		NFSEXITCODE(error);
> >    16		getlckret = error;
> >    17	}
> >
> > The code in line 7 is the problematic part.  Since this is
> > undefined,
> > the compiler inserts a trap instruction here.  I think the problem
> > Roman
> > encountered is that on sparc64, there is no equivalent to x86's ud2
> > instruction, so it inserts a call to abort() instead, and that
> > function
> > is not available in kernel-land.
> 
> Compiler bug.  abort() is not available in freestanding
> implementations.
> The behaviour is only undefined if the null pointer is dereferenced
> at
> runtime, so it doesn't include failing to link to abort() at compile
> time.
> 
> > ...
> >> Sorry, I'm not a compiler guy, so I don't know why a compiler
> >> would
> >> generate a trap instruction, but since new_lfpp is never NULL when
> >> this is executed, I don't see a problem.
> >>
> >> If others feel that this needs to be re-coded, please let me know
> >> what
> >> you think the code should look like? (A test for non-NULL with a
> >> panic()
> >> before it is used?)
> >>
> >> Is a trap instruction that never gets executed a problem?
> >
> > It's better to avoid undefined behavior in any case.  Just add a
> > NULL
> > check, that should be sufficient.
> 
> That might only add bloat and unimprove debugging.  Since the null
> pointer
> case cannot happen, it cannot be handed properly.  It can be
> mishandled in
> the following ways:
> - return an error, so that all callers have to handle the null
> pointer case
>    that can't happen.  If the compiler is too smart, it will notice
>    more
>    undefined behaviour (that can't happen) in callers and "force" you
>    to
>    handle it there too
> - KASSERT() that the pointer cannot be null.  Then:
>    - on production systems where KASSERT() is null, this won't work
>    around
>      the compiler bug.  Use a panic() instead.  To maximize source
>      code
>      bloat, ifdef all of this.
>    - when KASSERT() is not null, it will work around the compiler
>    bug.
>      If the case that can't happen actually happens, then this
>      unimproves
>      the debugging by messing up stack traces and turning restartable
>      null pointer or SIGILL traps to non-restartable panics.
>      Optimizations that replace a large block of code ending with a
>      null pointer trap by a single unimplemented instruction would
>      probably break restarting anyway.
> 
> Bruce
> 
So Roman, all I can suggest is to try adding something like:
   if (new_lfpp == NULL)
        panic("new_lfpp NULL");
after line#6. If that makes the compiler happy, I can commit it in
April. (Can't do commits before then.)
I agree with Bruce, but the check might be a good idea, in case a
future code change introduces a bug where the function is called with
new_lfpp NULL and NFSLCK_OPEN set.

If this doesn't make the compiler happy, all I can suggest is to
play around until you come up with something that works.

Have fun with it, rick
ps: I haven't seen this reported by tinderbox. Is the problem
    specific to your setup?



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1647701889.16319715.1390701954380.JavaMail.root>