All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cocci] Coccinelle rule for CVE-2019-18683
@ 2020-04-08 22:01 ` Alexander Popov
  0 siblings, 0 replies; 22+ messages in thread
From: Alexander Popov @ 2020-04-08 22:01 UTC (permalink / raw)
  To: Julia Lawall, Gilles Muller, Nicolas Palix, Michal Marek, cocci,
	kernel-hardening@lists.openwall.com, Jann Horn, Kees Cook,
	Hans Verkuil, Mauro Carvalho Chehab, Linux Media Mailing List,
	LKML

Hello!

Some time ago I fixed CVE-2019-18683 in the V4L2 subsystem of the Linux kernel.

I created a Coccinelle rule that detects that bug pattern. Let me show it.


Bug pattern
===========

CVE-2019-18683 refers to three similar vulnerabilities caused by the same
incorrect approach to locking that is used in vivid_stop_generating_vid_cap(),
vivid_stop_generating_vid_out(), and sdr_cap_stop_streaming().

For fixes please see the commit 6dcd5d7a7a29c1e4 (media: vivid: Fix wrong
locking that causes race conditions on streaming stop).

These three functions are called during streaming stopping with vivid_dev.mutex
locked. And they all do the same mistake while stopping their kthreads, which
need to lock this mutex as well. See the example from
vivid_stop_generating_vid_cap():
    /* shutdown control thread */
    vivid_grab_controls(dev, false);
    mutex_unlock(&dev->mutex);
    kthread_stop(dev->kthread_vid_cap);
    dev->kthread_vid_cap = NULL;
    mutex_lock(&dev->mutex);

But when this mutex is unlocked, another vb2_fop_read() can lock it instead of
the kthread and manipulate the buffer queue. That causes use-after-free.

I created a Coccinelle rule that detects mutex_unlock+kthread_stop+mutex_lock
within one function.


Coccinelle rule
===============

virtual report

@race exists@
expression E;
position stop_p;
position unlock_p;
position lock_p;
@@

mutex_unlock@unlock_p(E)
...
kthread_stop@stop_p(...)
...
mutex_lock@lock_p(E)

@script:python@
stop_p << race.stop_p;
unlock_p << race.unlock_p;
lock_p << race.lock_p;
E << race.E;
@@

coccilib.report.print_report(unlock_p[0], 'mutex_unlock(' + E + ') here')
coccilib.report.print_report(stop_p[0], 'kthread_stop here')
coccilib.report.print_report(lock_p[0], 'mutex_lock(' + E + ') here\n')


Testing the rule
================

I reverted the commit 6dcd5d7a7a29c1e4 and called:
COCCI=./scripts/coccinelle/kthread_race.cocci make coccicheck MODE=report

The result:

./drivers/media/platform/vivid/vivid-kthread-out.c:347:1-13: mutex_unlock(& dev
-> mutex) here
./drivers/media/platform/vivid/vivid-kthread-out.c:348:1-13: kthread_stop here
./drivers/media/platform/vivid/vivid-kthread-out.c:350:1-11: mutex_lock(& dev ->
mutex) here

./drivers/media/platform/vivid/vivid-sdr-cap.c:306:1-13: mutex_unlock(& dev ->
mutex) here
./drivers/media/platform/vivid/vivid-sdr-cap.c:307:1-13: kthread_stop here
./drivers/media/platform/vivid/vivid-sdr-cap.c:309:1-11: mutex_lock(& dev ->
mutex) here

./drivers/media/platform/vivid/vivid-kthread-cap.c:1001:1-13: mutex_unlock(& dev
-> mutex) here
./drivers/media/platform/vivid/vivid-kthread-cap.c:1002:1-13: kthread_stop here
./drivers/media/platform/vivid/vivid-kthread-cap.c:1004:1-11: mutex_lock(& dev
-> mutex) here

There are no other bugs detected.

Do you have any idea how to improve it?
Do we need that rule for regression testing in the upstream?

Thanks in advance!
Alexander
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

^ permalink raw reply	[flat|nested] 22+ messages in thread
* Re: [Cocci] Coccinelle rule for CVE-2019-18683
@ 2020-04-09  8:41 ` Markus Elfring
  0 siblings, 0 replies; 22+ messages in thread
From: Markus Elfring @ 2020-04-09  8:41 UTC (permalink / raw)
  To: Alexander Popov, cocci, kernel-hardening
  Cc: Michal Marek, Kees Cook, Gilles Muller, Jann Horn, Nicolas Palix,
	linux-kernel, Hans Verkuil, Julia Lawall, Mauro Carvalho Chehab,
	linux-media

> Do you have any idea how to improve it?

I see further software development possibilities of varying relevance
also for this script of the semantic patch language.

* The SmPL variables “lock_p”, “unlock_p” and “stop_p” could be declared
  in a more succinct way just by listing them in the same statement.

* The source code search pattern can be too generic.
  How do you think about to consider additional constraints
  for safer data control flow analysis?

* Other operation modes might become helpful.

Regards,
Markus
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2020-04-11  5:08 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-08 22:01 [Cocci] Coccinelle rule for CVE-2019-18683 Alexander Popov
2020-04-08 22:01 ` Alexander Popov
2020-04-08 22:26 ` [Cocci] " Jann Horn
2020-04-08 22:26   ` Jann Horn
2020-04-09 19:41   ` [Cocci] " Alexander Popov
2020-04-09 19:41     ` Alexander Popov
2020-04-11  0:10     ` [Cocci] " Alexander Popov
2020-04-11  0:10       ` Alexander Popov
2020-04-11  5:07       ` [Cocci] " Markus Elfring
2020-04-11  5:07         ` Markus Elfring
2020-04-09 10:53 ` [Cocci] " Julia Lawall
2020-04-09 10:53   ` Julia Lawall
2020-04-09 19:56   ` Alexander Popov
2020-04-09 19:56     ` Alexander Popov
2020-04-09 20:45     ` Julia Lawall
2020-04-09 20:45       ` Julia Lawall
  -- strict thread matches above, loose matches on Subject: below --
2020-04-09  8:41 Markus Elfring
2020-04-09  8:41 ` Markus Elfring
2020-04-09 18:11 ` Alexander Popov
2020-04-09 18:11   ` Alexander Popov
2020-04-10 13:16   ` Markus Elfring
2020-04-10 13:16     ` Markus Elfring

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.