Dev:Ciss: A kernel address leakage in sys/dev/ciss/ciss.c

Fuqian Huang huangfq.daxian at gmail.com
Thu Jun 13 02:54:59 UTC 2019


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 at bsdimp.com> 於 2019年6月13日週四 上午5:51寫道:
>
>
>
> On Wed, Jun 12, 2019 at 7:02 AM Fuqian Huang <huangfq.daxian at 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 except 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 called for the LAST close, meaning nothing else has it open. This means there will 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 = 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 = 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 = 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 at freebsd.org mailing list
>> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe at freebsd.org"


More information about the freebsd-hackers mailing list