Change db schema of package_info table 72/74672/1
authorKyungwook Tak <k.tak@samsung.com>
Wed, 15 Jun 2016 07:20:10 +0000 (16:20 +0900)
committerKyungwook Tak <k.tak@samsung.com>
Wed, 15 Jun 2016 07:20:10 +0000 (16:20 +0900)
pkg_id cannot be used as primary key because the case of symlink exist
in package path. On symlink existing case, pkg id will be same on both
of symlink path and original path(resolved path) so it could be conflict
on package_info table with same pkg_id.

Change-Id: Iaf9580c5979ad6bcb32170743d47c34602295c16
Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
data/scripts/create_schema.sql
src/framework/db/manager.cpp
src/framework/db/manager.h
src/framework/db/query.h
src/framework/service/cs-logic.cpp
src/framework/service/fs-utils.cpp

index 76dae66..453bc64 100644 (file)
@@ -67,10 +67,10 @@ CREATE TABLE IF NOT EXISTS PACKAGE_INFO (
        pkg_id TEXT NOT NULL,
        idx INTEGER NOT NULL,
        worst_filepath_idx TEXT NOT NULL,
+       i INTEGER PRIMARY KEY AUTOINCREMENT,
 
        FOREIGN KEY(idx) REFERENCES NAMES(idx) ON DELETE CASCADE,
-       FOREIGN KEY(worst_filepath_idx) REFERENCES DETECTED_MALWARE(filepath_idx) ON DELETE CASCADE,
-       PRIMARY KEY(pkg_id)
+       FOREIGN KEY(worst_filepath_idx) REFERENCES DETECTED_MALWARE(filepath_idx) ON DELETE CASCADE
 );
 
 CREATE VIEW IF NOT EXISTS [join_p_d] AS
index d547518..d8aa1a5 100644 (file)
@@ -304,10 +304,10 @@ RowShPtrs Manager::getDetectedByFilepathOnDir(const std::string &dir)
        return rows;
 }
 
-RowShPtr Manager::getWorstByPkgId(const std::string &pkgId)
+RowShPtr Manager::getWorstByPkgPath(const std::string &pkgPath)
 {
-       Statement stmt(this->m_conn, Query::SEL_WORST_BY_PKGID);
-       stmt.bind(pkgId);
+       Statement stmt(this->m_conn, Query::SEL_WORST_BY_PKGPATH);
+       stmt.bind(pkgPath);
 
        if (!stmt.step())
                return nullptr;
@@ -321,7 +321,7 @@ RowShPtr Manager::getWorstByPkgId(const std::string &pkgId)
        row->detailedUrl = stmt.getText(); // detailed_url
        row->severity = static_cast<csr_cs_severity_level_e>(stmt.getInt()); // severity
        row->ts = static_cast<time_t>(stmt.getInt64()); // detected_time
-       row->pkgId = pkgId;
+       row->pkgId = stmt.getText(); // pkg_id
        row->isApp = true;
 
        return row;
index 6746763..4fbc0ba 100644 (file)
@@ -64,7 +64,7 @@ public:
        RowShPtr getDetectedByNameOnPath(const std::string &path);
        RowShPtrs getDetectedByNameOnDir(const std::string &dir);
        RowShPtrs getDetectedByFilepathOnDir(const std::string &dir);
-       RowShPtr getWorstByPkgId(const std::string &pkgId);
+       RowShPtr getWorstByPkgPath(const std::string &pkgPath);
 
        void insertName(const std::string &name);
        void insertDetected(const CsDetected &, const std::string &filename,
index eb7ce8a..524c6ee 100644 (file)
@@ -68,11 +68,11 @@ const std::string SEL_DETECTED_BY_FILEPATH_ON_DIR =
        " from join_detecteds_by_file_path"
        " where file_path like ? || '%'";
 
-const std::string SEL_WORST_BY_PKGID =
+const std::string SEL_WORST_BY_PKGPATH =
        "select name, file_path, data_version, malware_name, detailed_url, severity,"
-       "       detected_time"
+       "       detected_time, pkg_id"
        " from join_p_d"
-       " where pkg_id = ?";
+       " where name = ?";
 
 const std::string INS_NAME =
        "insert or replace into NAMES(name) values(?)";
index a15d6ad..3a7e541 100644 (file)
@@ -265,14 +265,14 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &pkgPath)
                return this->scanAppOnCloud(context, pkgPath, pkgId);
 
        // old history
-       auto history = this->m_db->getWorstByPkgId(pkgId);
+       auto history = this->m_db->getWorstByPkgPath(pkgPath);
        // riskiest detected among newly scanned files
        std::string riskiestPath;
        auto riskiest = this->scanAppDelta(pkgPath, pkgId, riskiestPath);
        // history after delta scan. if worst file is changed, it's rescanned in scanAppDelta
        // and deleted from db if it's cured. if history != nullptr && after == nullptr,
        // it means worst detected item is cured anyway.
-       auto after = this->m_db->getWorstByPkgId(pkgId);
+       auto after = this->m_db->getWorstByPkgPath(pkgPath);
        if (history && after && riskiest) {
                if (*history < *riskiest) {
                        INFO("worst case is remained but the more worst newly detected. on pkg[" <<
index aab708a..638afdf 100644 (file)
@@ -26,6 +26,7 @@
 #include <cerrno>
 #include <unistd.h>
 #include <sys/types.h>
+#include <dirent.h>
 #include <pwd.h>
 
 #include <csr-error.h>
 #include "common/exception.h"
 #include "common/audit/logger.h"
 
-namespace Csr {
+namespace {
 
-bool isReadable(const std::string &target)
+std::unique_ptr<struct stat> getStatInternal(const std::string &target)
 {
-       FILE *f = ::fopen(target.c_str(), "rb");
+       std::unique_ptr<struct stat> statptr(new struct stat);
+       ::memset(statptr.get(), 0x00, sizeof(struct stat));
+
+       if (::stat(target.c_str(), statptr.get()) != 0) {
+               const int err = errno;
+
+               if (err == ENOENT)
+                       WARN("target not exist: " << target);
+               else if (err == EACCES)
+                       WARN("no permission to read path: " << target);
+               else
+                       ERROR("stat() failed on target: " << target << " errno: " << err);
+
+               return nullptr;
+       }
+
+       return statptr;
+}
 
+bool isFileReadable(const std::string &filepath)
+{
+       FILE *f = ::fopen(filepath.c_str(), "rb");
        if (f == nullptr) {
                return false;
        } else {
@@ -47,6 +68,23 @@ bool isReadable(const std::string &target)
        }
 }
 
+} // namespace anonymous
+
+namespace Csr {
+
+bool isReadable(const std::string &target)
+{
+       auto s = ::getStatInternal(target);
+
+       if (s == nullptr)
+               return false;
+
+       if (S_ISDIR(s->st_mode))
+               return true;
+
+       return ::isFileReadable(target);
+}
+
 uid_t getUid(const std::string &username)
 {
        auto bufsize = ::sysconf(_SC_GETPW_R_SIZE_MAX);
@@ -71,25 +109,17 @@ uid_t getUid(const std::string &username)
 
 std::unique_ptr<struct stat> getStat(const std::string &target)
 {
-       std::unique_ptr<struct stat> statptr(new struct stat);
-       ::memset(statptr.get(), 0x00, sizeof(struct stat));
-
-       if (::stat(target.c_str(), statptr.get()) != 0) {
-               const int err = errno;
-
-               if (err == ENOENT)
-                       WARN("target not exist: " << target);
-               else if (err == EACCES)
-                       WARN("no permission to read path: " << target);
-               else
-                       ERROR("stat() failed on target: " << target << " errno: " << err);
+       auto s = ::getStatInternal(target);
 
+       // if no permission to read, return nullptr
+       if (s == nullptr)
                return nullptr;
-       }
 
-       // if no permission to read, return nullptr
-       if (isReadable(target))
-               return statptr;
+       if (S_ISDIR(s->st_mode))
+               return s;
+
+       if (::isFileReadable(target))
+               return s;
        else
                return nullptr;
 }