[Bug] Fix installation/deinstallation mode with smack 29/46429/7
authorTomasz Iwanek <t.iwanek@samsung.com>
Thu, 20 Aug 2015 07:24:23 +0000 (09:24 +0200)
committerPawel Sikorski <p.sikorski@samsung.com>
Thu, 20 Aug 2015 13:20:08 +0000 (06:20 -0700)
As stated in: https://review.tizen.org/gerrit/#/c/46420/

"""
On uninstall steps, old code runs StepRevokeSecurity before
StepRemoveFiles. With SMACK enabled, once StepRevokeSecurity
is finished, the installer processes(tpk and wgt) don't have
an authority to remove files, so the app
directory($HOME/apps_rw/[pkgid]) is still remained. When the
same app is installed again, the installer process crashes,
as the boost::exists() to the app destination directory raises
an exception on SMACK denial. This patch moves the
StepRevokeSecurity to the end of the list of steps on uninstall,
to give the privilege to delete the app directory to the installers.
"""

Splitting StepRevokeSecurity into two parts so that deinstallation
and deinstallation rollback should work.

Splitting StepRegisterSecurity into 2 steps. Because we need to
remove files before revoking security on rollback.

Change-Id: If597a3c256e09d57aa923566f5c3454d497c0593

src/common/CMakeLists.txt
src/common/step/step_register_security.cc
src/common/step/step_register_security.h
src/common/step/step_revoke_security.cc
src/common/step/step_revoke_security.h
src/common/step/step_rollback_deinstallation_security.cc [new file with mode: 0644]
src/common/step/step_rollback_deinstallation_security.h [new file with mode: 0644]
src/common/step/step_rollback_installation_security.cc [new file with mode: 0644]
src/common/step/step_rollback_installation_security.h [new file with mode: 0644]
src/tpk/tpk_installer.cc
src/wgt/wgt_installer.cc

index 83907f9..4d2869c 100644 (file)
@@ -37,6 +37,8 @@ SET(SRCS
   step/step_remove_temporary_directory.cc
   step/step_revoke_security.cc
   step/step_register_security.cc
+  step/step_rollback_deinstallation_security.cc
+  step/step_rollback_installation_security.cc
   step/step_unregister_app.cc
   step/step_update_app.cc
   step/step_update_security.cc
index e735846..6331058 100644 (file)
@@ -46,14 +46,5 @@ Step::Status StepRegisterSecurity::process() {
   return Status::OK;
 }
 
-Step::Status StepRegisterSecurity::undo() {
-  if (!UnregisterSecurityContextForApps(
-      context_->pkgid.get(), context_->manifest_data.get())) {
-    return Status::ERROR;
-  }
-  LOG(DEBUG) << "Security context uninstalled";
-  return Status::OK;
-}
-
 }  // namespace security
 }  // namespace common_installer
index e2ef7c3..75fabc9 100644 (file)
@@ -16,7 +16,7 @@ class StepRegisterSecurity : public Step {
   using Step::Step;
 
   Status process() override;
-  Status undo() override;
+  Status undo() override { return Status::OK; }
   Status clean() override { return Status::OK; }
   Status precheck() override;
 
index 750850a..f162a55 100644 (file)
@@ -24,7 +24,7 @@ Step::Status StepRevokeSecurity::precheck() {
   return Step::Status::OK;
 }
 
-Step::Status StepRevokeSecurity::process() {
+Step::Status StepRevokeSecurity::clean() {
   if (!UnregisterSecurityContextForApps(
       context_->pkgid.get(), context_->manifest_data.get())) {
     LOG(ERROR) << "Failure on unregistering security context for app "
@@ -35,17 +35,5 @@ Step::Status StepRevokeSecurity::process() {
   return Status::OK;
 }
 
-Step::Status StepRevokeSecurity::undo() {
-  if (!RegisterSecurityContextForApps(
-      context_->pkgid.get(), context_->pkg_path.get(),
-      context_->manifest_data.get())) {
-    LOG(ERROR) << "Failure on re-installing security context for app "
-               << context_->pkgid.get();
-    return Status::ERROR;
-  }
-  LOG(DEBUG) << "Security context installed";
-  return Status::OK;
-}
-
 }  // namespace security
 }  // namespace common_installer
index 7613d24..a652b3d 100644 (file)
@@ -12,13 +12,15 @@ namespace common_installer {
 namespace security {
 
 // Step that is used during uninstallation
+// Security rules are revoked on cleanup as until that point we need to keep
+// package files present for rollback
 class StepRevokeSecurity : public Step {
  public:
   using Step::Step;
 
-  Status process() override;
-  Status undo() override;
-  Status clean() override { return Status::OK; }
+  Status process() override { return Status::OK; }
+  Status undo() override { return Status::OK; }
+  Status clean() override;
   Status precheck() override;
 
   SCOPE_LOG_TAG(RevokeSecurity)
diff --git a/src/common/step/step_rollback_deinstallation_security.cc b/src/common/step/step_rollback_deinstallation_security.cc
new file mode 100644 (file)
index 0000000..f2e2428
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/step_rollback_deinstallation_security.h"
+
+#include <boost/filesystem.hpp>
+
+#include "common/security_registration.h"
+
+namespace common_installer {
+namespace security {
+
+Step::Status StepRollbackDeinstallationSecurity::precheck() {
+  if (context_->pkgid.get().empty()) {
+    LOG(ERROR) << "pkgid attribute is empty";
+    return Step::Status::INVALID_VALUE;
+  }
+  if (!context_->manifest_data.get()) {
+    LOG(ERROR) << "manifest_data attribute is empty";
+    return Step::Status::INVALID_VALUE;
+  }
+
+  return Step::Status::OK;
+}
+
+Step::Status StepRollbackDeinstallationSecurity::undo() {
+  if (!RegisterSecurityContextForApps(
+      context_->pkgid.get(), context_->pkg_path.get(),
+      context_->manifest_data.get())) {
+    LOG(ERROR) << "Failure on re-installing security context for app "
+               << context_->pkgid.get();
+    return Status::ERROR;
+  }
+  LOG(DEBUG) << "Security context installed";
+  return Status::OK;
+}
+
+}  // namespace security
+}  // namespace common_installer
+
diff --git a/src/common/step/step_rollback_deinstallation_security.h b/src/common/step/step_rollback_deinstallation_security.h
new file mode 100644 (file)
index 0000000..9100d17
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_STEP_ROLLBACK_DEINSTALLATION_SECURITY_H_
+#define COMMON_STEP_STEP_ROLLBACK_DEINSTALLATION_SECURITY_H_
+
+#include "common/step/step.h"
+#include "common/utils/logging.h"
+
+namespace common_installer {
+namespace security {
+
+// Step that is used during uninstallation to rollback security changes if
+// deinstallation fails
+class StepRollbackDeinstallationSecurity : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override { return Status::OK; }
+  Status undo() override;
+  Status clean() override { return Status::OK; }
+  Status precheck() override;
+
+  SCOPE_LOG_TAG(RollbackDeinstallationSecurity)
+};
+
+}  // namespace security
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_STEP_ROLLBACK_DEINSTALLATION_SECURITY_H_
diff --git a/src/common/step/step_rollback_installation_security.cc b/src/common/step/step_rollback_installation_security.cc
new file mode 100644 (file)
index 0000000..40f15a9
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/step_rollback_installation_security.h"
+
+#include <boost/filesystem.hpp>
+
+#include "common/security_registration.h"
+
+namespace common_installer {
+namespace security {
+
+Step::Status StepRollbackInstallationSecurity::precheck() {
+  if (context_->pkgid.get().empty()) {
+    LOG(ERROR) << "pkgid attribute is empty";
+    return Step::Status::INVALID_VALUE;
+  }
+  if (!context_->manifest_data.get()) {
+    LOG(ERROR) << "manifest_data attribute is empty";
+    return Step::Status::INVALID_VALUE;
+  }
+
+  return Step::Status::OK;
+}
+
+Step::Status StepRollbackInstallationSecurity::undo() {
+  if (!UnregisterSecurityContextForApps(
+      context_->pkgid.get(), context_->manifest_data.get())) {
+    return Status::ERROR;
+  }
+  LOG(DEBUG) << "Security context uninstalled";
+  return Status::OK;
+}
+
+}  // namespace security
+}  // namespace common_installer
diff --git a/src/common/step/step_rollback_installation_security.h b/src/common/step/step_rollback_installation_security.h
new file mode 100644 (file)
index 0000000..afde537
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_STEP_ROLLBACK_INSTALLATION_SECURITY_H_
+#define COMMON_STEP_STEP_ROLLBACK_INSTALLATION_SECURITY_H_
+
+#include "common/step/step.h"
+#include "common/utils/logging.h"
+
+namespace common_installer {
+namespace security {
+
+// Step that is used during installation to rollback security changes if
+// installation fails. Those changes cannot be reverted in StepSecurity
+// because its to early. We need to remove package files first.
+class StepRollbackInstallationSecurity : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override { return Status::OK; }
+  Status undo() override;
+  Status clean() override { return Status::OK; }
+  Status precheck() override;
+
+  SCOPE_LOG_TAG(RollbackInstallationSecurity)
+};
+
+}  // namespace security
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_STEP_ROLLBACK_INSTALLATION_SECURITY_H_
index 6e15cdd..d56325a 100644 (file)
@@ -26,6 +26,8 @@
 #include "common/step/step_revoke_security.h"
 #include "common/step/step_remove_temporary_directory.h"
 #include "common/step/step_register_security.h"
+#include "common/step/step_rollback_deinstallation_security.h"
+#include "common/step/step_rollback_installation_security.h"
 #include "common/step/step_check_signature.h"
 #include "common/step/step_unregister_app.h"
 #include "common/step/step_unzip.h"
@@ -83,6 +85,7 @@ void TpkInstaller::InstallSteps() {
   AddStep<ci::filesystem::StepUnzip>();
   AddStep<tpk::parse::StepParse>();
   AddStep<ci::security::StepCheckSignature>();
+  AddStep<ci::security::StepRollbackInstallationSecurity>();
   AddStep<ci::filesystem::StepCopy>();
   AddStep<ci::filesystem::StepCreateStorageDirectories>();
   AddStep<tpk::filesystem::StepCreateSymbolicLink>();
@@ -116,9 +119,10 @@ void TpkInstaller::UninstallSteps() {
   AddStep<ci::parse::StepParse>();
   AddStep<ci::backup::StepBackupManifest>();
   AddStep<ci::pkgmgr::StepUnregisterApplication>();
-  AddStep<ci::security::StepRevokeSecurity>();
+  AddStep<ci::security::StepRollbackDeinstallationSecurity>();
   AddStep<ci::filesystem::StepRemoveFiles>();
   AddStep<ci::filesystem::StepRemoveIcons>();
+  AddStep<ci::security::StepRevokeSecurity>();
 }
 
 void TpkInstaller::ReinstallSteps() {
index 7609060..c900cad 100644 (file)
@@ -29,6 +29,8 @@
 #include "common/step/step_remove_temporary_directory.h"
 #include "common/step/step_revoke_security.h"
 #include "common/step/step_register_security.h"
+#include "common/step/step_rollback_deinstallation_security.h"
+#include "common/step/step_rollback_installation_security.h"
 #include "common/step/step_old_manifest.h"
 #include "common/step/step_check_signature.h"
 #include "common/step/step_unregister_app.h"
@@ -66,6 +68,7 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
       AddStep<wgt::security::StepCheckSettingsLevel>();
       AddStep<wgt::encrypt::StepEncryptResources>();
       AddStep<wgt::filesystem::StepWgtResourceDirectory>();
+      AddStep<ci::security::StepRollbackInstallationSecurity>();
       AddStep<ci::filesystem::StepCopy>();
       AddStep<wgt::filesystem::StepWgtCreateStorageDirectories>();
       AddStep<wgt::filesystem::StepCreateSymbolicLink>();
@@ -100,10 +103,11 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
       AddStep<ci::parse::StepParse>();
       AddStep<ci::backup::StepBackupManifest>();
       AddStep<ci::pkgmgr::StepUnregisterApplication>();
-      AddStep<ci::security::StepRevokeSecurity>();
+      AddStep<ci::security::StepRollbackDeinstallationSecurity>();
       AddStep<ci::filesystem::StepRemoveFiles>();
       AddStep<ci::filesystem::StepRemoveIcons>();
       AddStep<wgt::encrypt::StepRemoveEncryptionData>();
+      AddStep<ci::security::StepRevokeSecurity>();
       break;
     }
     case ci::RequestType::Reinstall: {