Fix memory leak and add EINTR error handling. 60/22760/5
authorMarcin Lis <m.lis@samsung.com>
Wed, 11 Jun 2014 08:39:54 +0000 (10:39 +0200)
committerMarcin Lis <m.lis@samsung.com>
Thu, 12 Jun 2014 11:11:51 +0000 (13:11 +0200)
One memory leak was missed in the Installer service.
Introduce retries on EINTR error while trying to open a file.
Also add close() error handling.

Change-Id: I946ba0b7effbe8a2fd429a86d5d7b387be076546
Signed-off-by: Marcin Lis <m.lis@samsung.com>
src/server/service/installer.cpp
src/server/service/smack-rules.cpp

index 92d98ad170ea49eb5c043e4e2b7c6769b0e31ee3..90608d77f6819c81102f36c646507c857aacb991 100644 (file)
@@ -100,24 +100,25 @@ FileDecision labelLinksToExecs(const FTSENT *ftsent)
     LogSecureDebug("Entering function: " << __func__);
 
     struct stat buf;
-    char *target;
 
     // check if it's a link
     if ( !S_ISLNK(ftsent->fts_statp->st_mode))
         return FileDecision::SKIP;
 
-    target = realpath(ftsent->fts_path, NULL);
-    if (!target) {
+    std::unique_ptr<char, std::function<void(void*)>> target(realpath(ftsent->fts_path, NULL), free);
+
+    if (!target.get()) {
         LogSecureError("Getting link target for " << ftsent->fts_path << " failed (Error = " << strerror(errno) << ")");
         return FileDecision::ERROR;
     }
-    if (-1 == stat(target, &buf)) {
-        LogSecureError("stat failed for " << target << " (Error = " << strerror(errno) << ")");
+
+    if (-1 == stat(target.get(), &buf)) {
+        LogSecureError("stat failed for " << target.get() << " (Error = " << strerror(errno) << ")");
         return FileDecision::ERROR;
     }
     // skip if link target is not a regular executable file
     if (buf.st_mode != (buf.st_mode | S_IXUSR | S_IFREG)) {
-        LogSecureDebug(target << "is not a regular executable file. Skipping.");
+        LogSecureDebug(target.get() << "is not a regular executable file. Skipping.");
         return FileDecision::SKIP;
     }
 
index 4319ca99061ac24ffa3cc480bc5db5dfc9d612f4..687795ef5b2e1b16f0a8cf1e63407c6a48e1eee4 100644 (file)
@@ -29,6 +29,7 @@
 #include <sys/smack.h>
 #include <fcntl.h>
 #include <fstream>
+#include <cstring>
 
 #include <dpl/log/log.h>
 
@@ -74,7 +75,7 @@ bool SmackRules::loadFromFile(const std::string &path)
     int fd;
     bool ret = true;
 
-    fd = open(path.c_str(), O_RDONLY);
+    fd = TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY));
     if (fd == -1) {
         LogError("Failed to open file: %s" << path);
         return false;
@@ -85,7 +86,11 @@ bool SmackRules::loadFromFile(const std::string &path)
         ret = false;
     }
 
-    close(fd);
+    if (close(fd) == -1) {
+        // don't change the return code, the descriptor should be closed despite the error.
+        LogWarning("Error while closing the file: " << path << ", error: " << strerror(errno));
+    }
+
     return ret;
 }
 
@@ -94,7 +99,7 @@ bool SmackRules::saveToFile(const std::string &path) const
     int fd;
     bool ret = true;
 
-    fd = open(path.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644);
+    fd = TEMP_FAILURE_RETRY(open(path.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644));
     if (fd == -1) {
         LogError("Failed to create file: %s" << path);
         return false;
@@ -106,7 +111,18 @@ bool SmackRules::saveToFile(const std::string &path) const
         ret = false;
     }
 
-    close(fd);
+    if (close(fd) == -1) {
+        if (errno == EIO) {
+            LogError("I/O Error occured while closing the file: " << path << ", error: " << strerror(errno));
+            unlink(path.c_str());
+            return false;
+        } else {
+            // non critical error
+            // don't change the return code, the descriptor should be closed despite the error.
+            LogWarning("Error while closing the file: " << path << ", error: " << strerror(errno));
+        }
+    }
+
     return ret;
 }