#
FILE(GLOB PAM_SRCS krate.cpp
krate-builder.cpp
- common/session.cpp
)
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
+++ /dev/null
-/*
- * 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());
-}
+++ /dev/null
-/*
- * 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__
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()) {
KrateBuilder(const runtime::User& user, const std::string& manifestPath);
virtual ~KrateBuilder();
- void unshareNamespace();
void mountOwnFilesystem();
protected:
+++ /dev/null
-/*
- * 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__
#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
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;
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();
{
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;
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;
#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>
#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"
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();