Zbigniew Jędrzejewski-Szmek 708deb
From fc808616227115ccab8c04f00f8f7472c7353ae5 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 708deb
From: David Herrmann <dh.herrmann@gmail.com>
Zbigniew Jędrzejewski-Szmek 708deb
Date: Thu, 2 Oct 2014 08:31:28 +0200
Zbigniew Jędrzejewski-Szmek 708deb
Subject: [PATCH] barrier: fix up constructor error handling
Zbigniew Jędrzejewski-Szmek 708deb
Zbigniew Jędrzejewski-Szmek 708deb
We cannot rely on "errno" to be non-zero on failure, if we perform
Zbigniew Jędrzejewski-Szmek 708deb
multiple glibc calls. That is, if the first eventfd() call fails, but the
Zbigniew Jędrzejewski-Szmek 708deb
second succeeds, we cleanup the barrier but return 0.
Zbigniew Jędrzejewski-Szmek 708deb
Zbigniew Jędrzejewski-Szmek 708deb
Fix this by always testing the return value immediately. This should also
Zbigniew Jędrzejewski-Szmek 708deb
fix all the coverity warnings.
Zbigniew Jędrzejewski-Szmek 708deb
---
Zbigniew Jędrzejewski-Szmek 708deb
 src/shared/barrier.c | 19 ++++++++++++++-----
Zbigniew Jędrzejewski-Szmek 708deb
 src/shared/barrier.h |  2 ++
Zbigniew Jędrzejewski-Szmek 708deb
 2 files changed, 16 insertions(+), 5 deletions(-)
Zbigniew Jędrzejewski-Szmek 708deb
Zbigniew Jędrzejewski-Szmek 708deb
diff --git a/src/shared/barrier.c b/src/shared/barrier.c
Zbigniew Jędrzejewski-Szmek 708deb
index 4a5544de27..f65363a67b 100644
Zbigniew Jędrzejewski-Szmek 708deb
--- a/src/shared/barrier.c
Zbigniew Jędrzejewski-Szmek 708deb
+++ b/src/shared/barrier.c
Zbigniew Jędrzejewski-Szmek 708deb
@@ -112,15 +112,24 @@
Zbigniew Jędrzejewski-Szmek 708deb
  * Returns: 0 on success, negative error code on failure.
Zbigniew Jędrzejewski-Szmek 708deb
  */
Zbigniew Jędrzejewski-Szmek 708deb
 int barrier_create(Barrier *b) {
Zbigniew Jędrzejewski-Szmek 708deb
+        _cleanup_(barrier_destroyp) Barrier *staging = b;
Zbigniew Jędrzejewski-Szmek 708deb
+        int r;
Zbigniew Jędrzejewski-Szmek 708deb
+
Zbigniew Jędrzejewski-Szmek 708deb
         assert(b);
Zbigniew Jędrzejewski-Szmek 708deb
 
Zbigniew Jędrzejewski-Szmek 708deb
-        if ((b->me = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)) < 0 ||
Zbigniew Jędrzejewski-Szmek 708deb
-            (b->them = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)) < 0 ||
Zbigniew Jędrzejewski-Szmek 708deb
-            pipe2(b->pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
Zbigniew Jędrzejewski-Szmek 708deb
-                barrier_destroy(b);
Zbigniew Jędrzejewski-Szmek 708deb
+        b->me = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
Zbigniew Jędrzejewski-Szmek 708deb
+        if (b->me < 0)
Zbigniew Jędrzejewski-Szmek 708deb
+                return -errno;
Zbigniew Jędrzejewski-Szmek 708deb
+
Zbigniew Jędrzejewski-Szmek 708deb
+        b->them = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
Zbigniew Jędrzejewski-Szmek 708deb
+        if (b->them < 0)
Zbigniew Jędrzejewski-Szmek 708deb
+                return -errno;
Zbigniew Jędrzejewski-Szmek 708deb
+
Zbigniew Jędrzejewski-Szmek 708deb
+        r = pipe2(b->pipe, O_CLOEXEC | O_NONBLOCK);
Zbigniew Jędrzejewski-Szmek 708deb
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek 708deb
                 return -errno;
Zbigniew Jędrzejewski-Szmek 708deb
-        }
Zbigniew Jędrzejewski-Szmek 708deb
 
Zbigniew Jędrzejewski-Szmek 708deb
+        staging = NULL;
Zbigniew Jędrzejewski-Szmek 708deb
         return 0;
Zbigniew Jędrzejewski-Szmek 708deb
 }
Zbigniew Jędrzejewski-Szmek 708deb
 
Zbigniew Jędrzejewski-Szmek 708deb
diff --git a/src/shared/barrier.h b/src/shared/barrier.h
Zbigniew Jędrzejewski-Szmek 708deb
index 53b4439fb2..c55e311344 100644
Zbigniew Jędrzejewski-Szmek 708deb
--- a/src/shared/barrier.h
Zbigniew Jędrzejewski-Szmek 708deb
+++ b/src/shared/barrier.h
Zbigniew Jędrzejewski-Szmek 708deb
@@ -62,6 +62,8 @@ struct Barrier {
Zbigniew Jędrzejewski-Szmek 708deb
 int barrier_create(Barrier *obj);
Zbigniew Jędrzejewski-Szmek 708deb
 void barrier_destroy(Barrier *b);
Zbigniew Jędrzejewski-Szmek 708deb
 
Zbigniew Jędrzejewski-Szmek 708deb
+DEFINE_TRIVIAL_CLEANUP_FUNC(Barrier*, barrier_destroy);
Zbigniew Jędrzejewski-Szmek 708deb
+
Zbigniew Jędrzejewski-Szmek 708deb
 void barrier_set_role(Barrier *b, unsigned int role);
Zbigniew Jędrzejewski-Szmek 708deb
 
Zbigniew Jędrzejewski-Szmek 708deb
 bool barrier_place(Barrier *b);