Support labeling shared private paths 54/58254/12
authorZofia Abramowska <z.abramowska@samsung.com>
Thu, 28 Jan 2016 14:36:40 +0000 (15:36 +0100)
committerZofia Abramowska <z.abramowska@samsung.com>
Mon, 1 Feb 2016 20:09:06 +0000 (21:09 +0100)
Created labels are unique per path by using crypt()
with salt generated from owner package id and path passed as
parameters.
Added getting smack label from file, this will be required to
ascertain that path is a private path of application.

Change-Id: Id82ee50249795be4158acecc6c377e1390ae2d85

src/common/CMakeLists.txt
src/common/include/smack-labels.h
src/common/smack-labels.cpp

index 6b3cbb8..b718e2f 100644 (file)
@@ -68,6 +68,7 @@ SET_TARGET_PROPERTIES(${TARGET_COMMON}
 
 TARGET_LINK_LIBRARIES(${TARGET_COMMON}
     ${COMMON_DEP_LIBRARIES}
+    -lcrypt
     )
 
 INSTALL(TARGETS ${TARGET_COMMON} DESTINATION ${LIB_INSTALL_DIR})
index fab0c2b..af5c623 100644 (file)
@@ -59,6 +59,14 @@ void setupPath(
 void setupAppBasePath(const std::string &pkgId, const std::string &basePath);
 
 /**
+ * Changes Smack label on path to enable private sharing
+ *
+ * @param pkgId[in] package identifier
+ * @param path[in] path
+ */
+void setupSharedPrivatePath(const std::string &pkgId, const std::string &path);
+
+/**
  * Generates application name for a label fetched from Cynara
  *
  * @param[in] label string to fetch application name for
@@ -100,6 +108,24 @@ std::string generatePkgLabel(const std::string &pkgId);
 std::string generatePkgROLabel(const std::string &pkgId);
 
 /**
+ * Generates unique label per path for private path sharing.
+ *
+ * @param[in] pkgId
+ * @param[in] path
+ * @return resulting Smack label
+ */
+std::string generateSharedPrivateLabel(const std::string &pkgId, const std::string &path);
+
+/*
+ * Generates label for trusted paths. Trusted paths are paths where all application
+ * of the same author have rw rights.
+ *
+ * @param[in] authorId
+ * @return resulting Smack label
+ */
+std::string generateAuthorLabel(const std::string &authorId);
+
+/**
  * Returns smack label for given socket
  *
  * @param[in] socket descriptor
@@ -115,14 +141,13 @@ std::string getSmackLabelFromSocket(int socketFd);
  */
 std::string getSmackLabelFromPid(pid_t pid);
 
-/*
- * Generates label for trusted paths. Trusted paths are paths where all application
- * of the same author have rw rights.
+/**
+ * Returns smack label for given path
  *
- * @param[in] authorId
+ * @param[in] process identifier
  * @return resulting Smack label
  */
-std::string generateAuthorLabel(const std::string &authorId);
+std::string getSmackLabelFromPath(const std::string &path);
 
 } // namespace SmackLabels
 } // namespace SecurityManager
index 4aad505..dbc6f4d 100644 (file)
@@ -24,6 +24,7 @@
  *
  */
 
+#include <crypt.h>
 #include <sys/stat.h>
 #include <sys/smack.h>
 #include <sys/xattr.h>
@@ -34,6 +35,7 @@
 #include <fstream>
 #include <string>
 #include <sstream>
+#include <algorithm>
 
 #include <dpl/log/log.h>
 
@@ -41,6 +43,7 @@
 #include "smack-labels.h"
 #include "zone-utils.h"
 
+
 namespace SecurityManager {
 namespace SmackLabels {
 
@@ -179,6 +182,10 @@ void setupAppBasePath(const std::string &pkgId, const std::string &basePath)
     pathSetSmack(pkgPath.c_str(), LABEL_FOR_APP_PUBLIC_RO_PATH, XATTR_NAME_SMACK);
 }
 
+void setupSharedPrivatePath(const std::string &pkgId, const std::string &path) {
+    pathSetSmack(path.c_str(), generateSharedPrivateLabel(pkgId, path), XATTR_NAME_SMACK);
+}
+
 std::string generateAppNameFromLabel(const std::string &label)
 {
     static const char prefix[] = "User::App::";
@@ -235,6 +242,22 @@ std::string generatePkgROLabel(const std::string &pkgId)
     return label;
 }
 
+std::string generateSharedPrivateLabel(const std::string &pkgId, const std::string &path) {
+    // Prefix $1$ causes crypt() to use MD5 function
+    std::string label = "User::Pkg::";
+    std::string salt = "$1$" + pkgId;
+
+    const char * cryptLabel = crypt(path.c_str(), salt.c_str());
+    if (!cryptLabel) {
+        ThrowMsg(SmackException::Base, "crypt error");
+    }
+    label += cryptLabel;
+    std::replace(label.begin(), label.end(), '/', '%');
+    if (smack_label_length(label.c_str()) <= 0)
+        ThrowMsg(SmackException::InvalidLabel, "Invalid Smack label generated from path " << path);
+    return label;
+}
+
 std::string getSmackLabelFromSocket(int socketFd)
 {
     char *label = nullptr;
@@ -275,5 +298,14 @@ std::string generateAuthorLabel(const std::string &authorId) {
     return "User::Author::" + authorId;
 }
 
+std::string getSmackLabelFromPath(const std::string &path) {
+    char label[SMACK_LABEL_LEN];
+    ssize_t realLen;
+    if ((realLen = lgetxattr(path.c_str(), XATTR_NAME_SMACK, label, SMACK_LABEL_LEN)) < 0) {
+        ThrowMsg(SmackException::FileError, "lgetxattr failed");
+    }
+    return std::string(label, label+realLen);
+}
+
 } // namespace SmackLabels
 } // namespace SecurityManager