Change to use klay for managing namespace and cgroup 63/132163/4 accepted/tizen/4.0/unified/20170816.011648 accepted/tizen/4.0/unified/20170816.014839 accepted/tizen/unified/20170627.043411 accepted/tizen/unified/20170629.085717 submit/tizen/20170621.051505 submit/tizen/20170626.035422 submit/tizen_4.0/20170811.094300 submit/tizen_4.0/20170814.115522 submit/tizen_4.0_unified/20170814.115522
authorSungbae Yoo <sungbae.yoo@samsung.com>
Thu, 1 Jun 2017 08:57:27 +0000 (17:57 +0900)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Wed, 14 Jun 2017 10:34:05 +0000 (19:34 +0900)
Change-Id: I8121d1c605cf65672e080909fe0d627935538b4a
Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
module/CMakeLists.txt
module/common/session.cpp [deleted file]
module/common/session.h [deleted file]
module/krate-builder.cpp
module/krate-builder.h
module/krate-guard.h [deleted file]
module/krate.cpp
server/manager.cpp

index e0e6faa..18f1e21 100644 (file)
@@ -15,7 +15,6 @@
 #
 FILE(GLOB PAM_SRCS     krate.cpp
                                        krate-builder.cpp
-                                       common/session.cpp
 )
 
 SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
diff --git a/module/common/session.cpp b/module/common/session.cpp
deleted file mode 100644 (file)
index 4fcd9df..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License
- */
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-
-#include "session.h"
-
-#include <klay/exception.h>
-#include <klay/filesystem.h>
-
-bool isValidSessionLeader(pid_t pid)
-{
-       runtime::File proc("/proc/" + std::to_string(pid));
-       return proc.exists();
-}
-
-void createSession(const runtime::User& user, const SessionBuilder& sessionBuilder)
-{
-       runtime::File file("/var/run/krate/" + user.getName());
-       if (file.exists()) {
-               if (isValidSessionLeader(getSessionLeader(user))) {
-                       throw runtime::Exception("Session already opened");
-               }
-               file.remove();
-       } else {
-               file.makeBaseDirectory();
-       }
-
-       sessionBuilder(user);
-
-       file.create(0600);
-       file.lock();
-       file.chown(user.getUid(), user.getGid());
-       pid_t pid = ::getpid();
-       file.write(&pid, sizeof(pid_t));
-       file.unlock();
-}
-
-pid_t getSessionLeader(const runtime::User& user)
-{
-       runtime::File file("/var/run/krate/" + user.getName(), O_RDONLY);
-       file.lock();
-       pid_t pid = -1;
-       file.read(&pid, sizeof(pid_t));
-       file.unlock();
-
-       return pid;
-}
-
-void destroySession(const runtime::User& user)
-{
-       std::string path = "/var/run/krate/" + user.getName();
-       ::unlink(path.c_str());
-}
diff --git a/module/common/session.h b/module/common/session.h
deleted file mode 100644 (file)
index ebb053e..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License
- */
-
-#ifndef __KRATE_SESSION_ENV_H__
-#define __KRATE_SESSION_ENV_H__
-
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <string>
-#include <functional>
-
-#include <klay/auth/user.h>
-
-typedef std::function<void(const runtime::User& user)> SessionBuilder;
-
-bool isValidSessionLeader(pid_t pid);
-void createSession(const runtime::User& user, const SessionBuilder& sessionBuilder);
-pid_t getSessionLeader(const runtime::User& user);
-void destroySession(const runtime::User& user);
-
-#endif //!__KRATE_SESSION_ENV_H__
index b50e3b6..07fee11 100644 (file)
@@ -51,19 +51,6 @@ void KrateBuilder::bindFilesystemNode(const std::string& source, const std::stri
        runtime::Mount::mountEntry(source, target, type, options);
 }
 
-void KrateBuilder::unshareNamespace()
-{
-       int nsFlags = CLONE_NEWIPC | CLONE_NEWNS;
-
-       if (::unshare(nsFlags)) {
-               throw runtime::Exception("Failed to unshare namespace");
-       }
-
-       if (::mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) == -1) {
-               throw runtime::Exception("Failed to mount root filesystem");
-       }
-}
-
 void KrateBuilder::mountOwnFilesystem()
 {
        if (manifest.get()) {
index 5bb05d5..7947c6b 100644 (file)
@@ -29,7 +29,6 @@ public:
        KrateBuilder(const runtime::User& user, const std::string& manifestPath);
        virtual ~KrateBuilder();
 
-       void unshareNamespace();
        void mountOwnFilesystem();
 
 protected:
diff --git a/module/krate-guard.h b/module/krate-guard.h
deleted file mode 100644 (file)
index a19781a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef __KRATE_GUARD_H__
-#define __KRATE_GUARD_H__
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <semaphore.h>
-#include <sys/stat.h>
-
-#include <string>
-
-#include <klay/exception.h>
-
-class KrateGuard final {
-public:
-       KrateGuard(const std::string& name) :
-               krateName(name), semaphore(nullptr)
-       {
-               semaphore = ::sem_open(krateName.c_str(), O_CREAT, 0700, 1);
-               if (semaphore == nullptr) {
-                       throw runtime::Exception("Filed to create semaphore for krate guard");
-               }
-       }
-
-       ~KrateGuard()
-       {
-               if (semaphore == nullptr) {
-                       return;
-               }
-
-               ::sem_post(semaphore);
-               ::sem_close(semaphore);
-               ::sem_unlink(krateName.c_str());
-       }
-
-       void wait()
-       {
-               while ((::sem_wait(semaphore) == -1) && (errno == EINTR));
-       }
-
-private:
-       std::string krateName;
-       sem_t* semaphore;
-};
-
-#endif //!__KRATE_GUARD_H__
index bb7c293..bc8b091 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <dlfcn.h>
 #include <syslog.h>
+#include <unistd.h>
 #include <security/pam_ext.h>
 #include <security/pam_modules.h>
 
 #include <vector>
 #include <iostream>
 
-#include "krate-guard.h"
 #include "krate-builder.h"
-#include "common/session.h"
 
+#include <klay/cgroup.h>
+#include <klay/namespace.h>
 #include <klay/exception.h>
 #include <klay/filesystem.h>
 #include <klay/xml/parser.h>
 #include <klay/xml/document.h>
 
+#define CGROUP_SUBSYSTEM "krate"
+
 #define KRATE_UID_MIN 60001
 #define KRATE_UID_MAX 60100
 
@@ -54,6 +57,28 @@ std::string getKrateName(pam_handle_t* handle)
        return static_cast<const char*>(retItem);
 }
 
+void enterKrate(const std::string& name)
+{
+       std::string path = CGROUP_SUBSYSTEM "/" + name;
+       pid_t pid = 0;
+
+       if (runtime::Cgroup::exist(CGROUP_SUBSYSTEM, path)) {
+               auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, path);
+               if (pids.size() > 0) {
+                       pid  = pids[0];
+               }
+       } else {
+               runtime::Cgroup::create(CGROUP_SUBSYSTEM, path);
+       }
+
+       if (pid == 0) {
+               runtime::Cgroup::addProcess(CGROUP_SUBSYSTEM, path, ::getpid());
+               runtime::Namespace::unshare(CLONE_NEWNS | CLONE_NEWIPC);
+       } else {
+               runtime::Namespace::attach(pid);
+       }
+}
+
 static int wait_condition(void)
 {
     int r;
@@ -99,14 +124,8 @@ int container_preprocess(char* id) {
        std::cout << "kraterize (UID " << id << ")..." << std::endl << std::flush;
        try {
                runtime::User user(std::stoi(std::string(id)));
-               KrateGuard krateGuard(user.getName());
-               krateGuard.wait();
 
-               auto sessionBuilder = [](const runtime::User& user) {
-                       KrateBuilder builder(user, buildKrateManifestPath(user.getName()));
-                       builder.unshareNamespace();
-               };
-               createSession(user, sessionBuilder);
+               enterKrate(user.getName());
 
                if (user.getUid() >= KRATE_UID_MIN && user.getUid() <= KRATE_UID_MAX ) {
                        wait_condition();
@@ -140,15 +159,11 @@ int pam_sm_open_session(pam_handle_t* pamh, int flags, int argc, const char* arg
 {
        try {
                runtime::User user(getKrateName(pamh));
-               KrateGuard krateGuard(user.getName());
-               krateGuard.wait();
-
-               auto sessionBuilder = [](const runtime::User& user) {
-                       KrateBuilder builder(user, buildKrateManifestPath(user.getName()));
-                       builder.unshareNamespace();
-                       builder.mountOwnFilesystem();
-               };
-               createSession(user, sessionBuilder);
+
+               enterKrate(user.getName());
+
+               KrateBuilder builder(user, buildKrateManifestPath(user.getName()));
+               builder.mountOwnFilesystem();
        } catch (runtime::Exception& e) {
                ::pam_syslog(pamh, LOG_ERR, "%s", e.what());
                return PAM_SESSION_ERR;
@@ -161,11 +176,12 @@ PAM_EXTERN  __attribute__((visibility("default")))
 int pam_sm_close_session(pam_handle_t* pamh, int flags, int argc, const char* argv[])
 {
        try {
-               runtime::User user(getKrateName(pamh));
-               KrateGuard krateGuard(user.getName());
-               krateGuard.wait();
-
-               destroySession(user);
+               std::string name = getKrateName(pamh);
+               auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, name);
+               if (pids.size() <= 1) {
+                       std::string path = CGROUP_SUBSYSTEM "/" + name;
+                       runtime::Cgroup::destroy(CGROUP_SUBSYSTEM, path);
+               }
        } catch (runtime::Exception& e) {
                ::pam_syslog(pamh, LOG_ERR, "%s", e.what());
                return PAM_SESSION_ERR;
index 2747e3b..90836b4 100644 (file)
@@ -28,6 +28,7 @@
 #include <gum/gum-user-service.h>
 #include <gum/common/gum-user-types.h>
 #include <klay/error.h>
+#include <klay/cgroup.h>
 #include <klay/process.h>
 #include <klay/filesystem.h>
 #include <klay/auth/user.h>
@@ -41,6 +42,7 @@
 
 #include "rmi/manager.h"
 
+#define CGROUP_SUBSYSTEM "krate"
 #define PRIVILEGE_INTERNAL_PLATFORM "http://tizen.org/privilege/internal/default/platform"
 #define KRATE_DELEGATOR_APP  "org.tizen.keyguard"
 #define DEFAULT_ICON_PATH  ICON_PATH "/default_icon.png"
@@ -500,6 +502,9 @@ Manager::Manager(KrateControlContext& ctx) :
        context.createNotification("Manager::created");
        context.createNotification("Manager::removed");
 
+       runtime::Cgroup::createSubsystem(CGROUP_SUBSYSTEM);
+       runtime::Cgroup::create(CGROUP_SUBSYSTEM, CGROUP_SUBSYSTEM);
+
        KRATE_DEFAULT_OWNER = ::tzplatform_getenv(TZ_SYS_DEFAULT_USER);
 
        PackageManager& packageManager = PackageManager::instance();