drm/linux: Fix potential ww mutex induced panics master
authorFrançois Tigeot <ftigeot@wolfpond.org>
Mon, 15 Oct 2018 20:17:54 +0000 (22:17 +0200)
committerFrançois Tigeot <ftigeot@wolfpond.org>
Mon, 15 Oct 2018 20:31:40 +0000 (22:31 +0200)
ww mutex locking functions can be called with a NULL ctx and were
happily setting both lock->acquired to non-zero and lock->ctx to
NULL, a combination which other parts of our ww mutex implementation
assume is not possible.

Obtained-from: OpenBSD

sys/dev/drm/include/linux/ww_mutex.h

index 5382ca9..3a9ec5a 100644 (file)
@@ -132,6 +132,7 @@ ww_mutex_trylock(struct ww_mutex *lock) {
  * calling the slow path as this could lead to deadlocks.
  *
  * When `intr` is `true`, the ssleep will be interruptable.
+ * `ctx` can be NULL in order to acquire only a single lock.
  */
 static inline int
 __ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx, bool slow, bool intr) {
@@ -180,7 +181,8 @@ __ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx, bool slow, bo
                          *   the `younger` process gives up all it's
                          *   resources.
                         */
-                       if (slow || ctx == NULL || ctx->stamp < lock->ctx->stamp) {
+                       if (slow || ctx == NULL ||
+                           (lock->ctx != NULL && ctx->stamp < lock->ctx->stamp)) {
                                int s = ssleep(lock, &lock->lock,
                                               intr ? PCATCH : 0,
                                               ctx ? ctx->ww_class->name : "ww_mutex_lock", 0);