installer: Fix the /mnt/stateful_partition/unencrypted permission.
This patch introduces a postinstall fix (read as hack) to change the
permission of /mnt/stateful_partition/unencrypted (if it exists) to
0755 owned by root:root. This solves some issues with devices coming
out of the factory with these permission wrong, not being able to
read the files pre-populated there.
The patch introces three syscall calls: stat, chmod and chown, that
only log a message to stdout or stderr when they succeed or fail
respectively. All errors are non-fatal.
BUG=chromium:432774
TEST=Manual local test.
Procedure executed in the chroot after commenting out some code that
requires cgpt working on a real device (just to get to run this patch).
Setup:
$ emerge-link chromeos-install
$ mkdir /tmp/foo3
$ cp /build/link/usr/bin/cros_installer /tmp/foo3/
$ mkdir -p /tmp/foo3/proc && echo cros_legacy > /tmp/foo3/proc/cmdline
$ mkdir -p /tmp/foo3/etc
$ echo "CHROMEOS_RELEASE_VERSION=1.2.3.4" > /tmp/foo3/etc/lsb-release
$ touch /tmp/foo3/foo2 && touch /tmp/foo3/foo3
$ cp /build/link/usr/bin/cros_installer /tmp/foo3/
Tests the four cases:
$ sudo chroot /tmp/foo3 /cros_installer postinst / /foo3
...
Couldn't check the current permission, ignored: No such file or directory
...
$ sudo mkdir -p /tmp/foo3//mnt/stateful_partition/unencrypted/foo
$ sudo chroot /tmp/foo3 /cros_installer postinst / /foo3
...
Checking /mnt/stateful_partition/unencrypted permission.
Permission is ok.
...
$ sudo chown 1234:5678 /tmp/foo3/mnt/stateful_partition/unencrypted
$ sudo chroot /tmp/foo3 /cros_installer postinst / /foo3
...
Checking /mnt/stateful_partition/unencrypted permission.
Permission changed successfully.
...
$ ls -la /tmp/foo3/mnt/stateful_partition/unencrypted
drwxr-xr-x 3 root root 4096 Nov 14 23:30 .
...
$ sudo chmod 766 /tmp/foo3/mnt/stateful_partition/unencrypted
$ sudo chroot /tmp/foo3 /cros_installer postinst / /foo3
...
Checking /mnt/stateful_partition/unencrypted permission.
Permission changed successfully.
...
$ ls -la /tmp/foo3/mnt/stateful_partition/unencrypted
drwxr-xr-x 3 root root 4096 Nov 14 23:30 .
...
Change-Id: Ib8a3d70e281c1abc5ae80b72f60bdc7f6bc3d2d8
Previous-Reviewed-on: https://chromium-review.googlesource.com/229983
(cherry picked from commit 21489894e6983d197f19b711d918980fa0632238)
Previous-Reviewed-on: https://chromium-review.googlesource.com/230764
(cherry picked from commit 721bc2a15d64f3a2b6175a2768f811e7928b4483)
Reviewed-on: https://chromium-review.googlesource.com/232951
Reviewed-by: Don Garrett <dgarrett@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
diff --git a/installer/chromeos_postinst.cc b/installer/chromeos_postinst.cc
index 6fccfd9..eb9c9c3 100644
--- a/installer/chromeos_postinst.cc
+++ b/installer/chromeos_postinst.cc
@@ -6,6 +6,8 @@
#include <stdio.h>
#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <unistd.h>
#include "installer/cgpt_manager.h"
@@ -16,6 +18,10 @@
using std::string;
+namespace {
+const char kStatefulMount[] = "/mnt/stateful_partition";
+} // namespace
+
bool ConfigureInstall(const string& install_dev,
const string& install_path,
BiosType bios_type,
@@ -145,6 +151,37 @@
return result;
}
+// Fix the unencrypted permission. The permission on this file have been
+// deployed with wrong values (0766 for the permission) and/or the wrong
+// uid:gid.
+void FixUnencryptedPermission() {
+ string unencrypted_dir = string(kStatefulMount) + "/unencrypted";
+ printf("Checking %s permission.\n", unencrypted_dir.c_str());
+ struct stat unencrypted_stat;
+ const mode_t target_mode = S_IFDIR | S_IRWXU | (S_IRGRP | S_IXGRP) | (
+ S_IROTH | S_IXOTH); // 040755
+ if (stat(unencrypted_dir.c_str(), &unencrypted_stat) != 0) {
+ perror("Couldn't check the current permission, ignored");
+ } else if (unencrypted_stat.st_uid == 0 &&
+ unencrypted_stat.st_gid == 0 &&
+ unencrypted_stat.st_mode == target_mode) {
+ printf("Permission is ok.\n");
+ } else {
+ bool ok = true;
+ // chmod(2) only takes the last four octal digits, so we flip the IFDIR bit.
+ if (chmod(unencrypted_dir.c_str(), target_mode ^ S_IFDIR) != 0) {
+ perror("chmod");
+ ok = false;
+ }
+ if (chown(unencrypted_dir.c_str(), 0, 0) != 0) {
+ perror("chown");
+ ok = false;
+ }
+ if (ok)
+ printf("Permission changed successfully.\n");
+ }
+}
+
// Do post install stuff.
//
// Install kernel, set up the proper bootable partition in
@@ -252,6 +289,7 @@
// and a reboot will boot into it. Thus, it's important that any future
// errors in this script do not cause this script to return failure unless
// in factory mode.
+ FixUnencryptedPermission();
// We have a new image, making the ureadahead pack files
// out-of-date. Delete the files so that ureadahead will
@@ -266,8 +304,7 @@
// Create a file indicating that the install is completed. The file
// will be used in /sbin/chromeos_startup to run tasks on the next boot.
// See comments above about removing ureadahead files.
- string stateful_mnt = "/mnt/stateful_partition";
- string install_completed = stateful_mnt + "/.install_completed";
+ string install_completed = string(kStatefulMount) + "/.install_completed";
if (!Touch(install_completed)) {
printf("Touch(%s) FAILED\n", install_completed.c_str());
if (is_factory_install)
@@ -276,7 +313,7 @@
// If present, remove firmware checking completion file to force a disk
// firmware check at reboot.
- string disk_fw_check_complete = stateful_mnt +
+ string disk_fw_check_complete = string(kStatefulMount) +
"/unencrypted/cache/.disk_firmware_upgrade_completed";
unlink(disk_fw_check_complete.c_str());
@@ -372,7 +409,7 @@
}
// If we can read in the stateful lsb-release we are updating FROM, log it.
- if (ReadFileToString("/mnt/stateful_partition/etc/lsb-release",
+ if (ReadFileToString(string(kStatefulMount) + "/etc/lsb-release",
&lsb_contents)) {
printf("\nFROM (stateful):\n%s", lsb_contents.c_str());
}