Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Jun 2019 23:02:16 -0600
From:      Warner Losh <imp@bsdimp.com>
To:        Fuqian Huang <huangfq.daxian@gmail.com>
Cc:        FreeBSD Hackers <freebsd-hackers@freebsd.org>
Subject:   Re: Dev:Ciss: A kernel address leakage in sys/dev/ciss/ciss.c
Message-ID:  <CANCZdfqEnV0gLF5mG19cxMaAoU%2Bt8xhHx4FoEsC6ScKhpCZ6Og@mail.gmail.com>
In-Reply-To: <CABXRUiQ30KkP0fjYVrJCaLgCM4uPOOS1RShF6p9TDd58ZDhF3w@mail.gmail.com>
References:  <CABXRUiTJAxRWdTsBP5K-5axAV-EZO0ddxhStwWGDDWoi7Hwsww@mail.gmail.com> <CANCZdfoJH4y4aOZ459rarUX7L6Fd==24YGHPidEdEMrbOuAbhw@mail.gmail.com> <CABXRUiQ30KkP0fjYVrJCaLgCM4uPOOS1RShF6p9TDd58ZDhF3w@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Because CISS_FLAG_NOTIFY_OK will be clear in sc->ciss_flags. It's only set
when we have the notifier armed, which is only armed when we have outanding
commands in the CISS hardware. Since we know that all the outstanding
requests have completed before the close, it should be clear. But again,
this only gets called at the end of ciss_attach (on the error path before
the notifier is setup) or in ciss_detach (which is only called when the
ciss driver is unloaded with the device attached, but unused, or if the
user has administratively put the interface down). So even if I've read
things and a notifier is running, the only way to provoke it is to do a
root-only operation. Disclosing kernel addresses to root doesn't seem like
a big deal, especially since the dmesg can be secured from non-root users.

This is why I've said this is more theoretical than actual. You need root
permissions to provoke it, and then root permissions to read the dmesg.
I'll commit a #if 0 out of an abundance of caution, but I'm having trouble
seeing how non-root users could provoke it.

Then again, the ciss driver is for older hardware that is somewhat rare
these days.

Thanks for the report...

Warner

On Wed, Jun 12, 2019 at 8:54 PM Fuqian Huang <huangfq.daxian@gmail.com>
wrote:

> But, why there will be no commands that are printed?
> 'cr' is get from ciss_get_request and 'cr->cr_data' is the result of
> malloc in ciss_notify_abort, and they are freed after the 'out' label.
> At the printing point, some address has been printed out.
> I know what you mean that this only happens when detaching the device.
> But it seems that some address is printed out before the free
> operation, and is it necessary to print the address?
>
> Warner Losh <imp@bsdimp.com> =E6=96=BC 2019=E5=B9=B46=E6=9C=8813=E6=97=A5=
=E9=80=B1=E5=9B=9B =E4=B8=8A=E5=8D=885:51=E5=AF=AB=E9=81=93=EF=BC=9A
> >
> >
> >
> > On Wed, Jun 12, 2019 at 7:02 AM Fuqian Huang <huangfq.daxian@gmail.com>
> wrote:
> >>
> >> In freebsd/sys/dev/ciss/ciss.c, function ciss_print_request will dump
> >> the address of a kernel object cr to user space. Each time when a
> >> device is detached, it will call
> >> ciss_free->ciss_notify_abort->ciss_print_request, and this finally
> >> dump a kernel address to user space.
> >
> >
> > This is, at best, a theoretical concern. ciss_detach isn't called excep=
t
> when detaching the device. This only happens if you are unloading the
> module or using devctl to detach it. Second, the bit you chopped out of
> ciss_detach ensure that the controller isn't open. Close is only called
> when there's no pending requests from geom to the device, and we get call=
ed
> for the LAST close, meaning nothing else has it open. This means there wi=
ll
> be no commands to abort when ciss_notify_abort() is called. Since there's
> no commands to abort, there will be no commands that are printed, so no
> user address will be disclosed.
> >
> > Having said that, do you have a test case that can trigger this? It
> would be most unexpected indeed...
> >
> > Warner
> >
> >>
> >> static int
> >> ciss_detach(device_t dev)
> >> {
> >>   struct ciss_softc   *sc =3D device_get_softc(dev);
> >>   ...
> >>   ciss_free(sc);
> >>   return (0);
> >> }
> >>
> >> static void
> >> ciss_free(struct ciss_softc *sc)
> >> {
> >>   ...
> >> ->  ciss_notify_abort(sc);
> >>   ...
> >> }
> >>
> >> static int
> >> ciss_notify_abort(struct ciss_softc *sc)
> >> {
> >>   struct ciss_request *cr;
> >>   ...
> >>   if ((error =3D ciss_get_request(sc, &cr))
> >>     goto out;
> >>   ...
> >> ->  ciss_print_request(cr);
> >>   ...
> >> }
> >>
> >> static void
> >> ciss_print_request(struct ciss_request *cr)
> >> {
> >>   struct ciss_softc   *sc;
> >>   ...
> >>   sc =3D cr->cr_sc;
> >>   ...
> >> ->  ciss_printf(sc, "REQUEST @ %p\n", cr);
> >> ciss_printf(sc, "  data %p/%d  tag %d  flags %b\n",
> >>       cr->cr_data, cr->cr_length, cr->cr_tag, cr->cr_flags,
> >>       "\20\1mapped\2sleep\3poll\4dataout\5datain\n");
> >> }
> >> _______________________________________________
> >> freebsd-hackers@freebsd.org mailing list
> >> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> >> To unsubscribe, send any mail to "
> freebsd-hackers-unsubscribe@freebsd.org"
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CANCZdfqEnV0gLF5mG19cxMaAoU%2Bt8xhHx4FoEsC6ScKhpCZ6Og>