toolkit/mozapps/update/updater/automounter_gonk.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include <android/log.h>
     8 #include <cutils/android_reboot.h>
     9 #include <errno.h>
    10 #include <stdlib.h>
    11 #include <sys/mount.h>
    12 #include <sys/reboot.h>
    13 #include <sys/types.h>
    14 #include <unistd.h>
    16 #include "automounter_gonk.h"
    17 #include "updatedefines.h"
    18 #include "updatelogging.h"
    20 #define LOG_TAG "GonkAutoMounter"
    22 #define GONK_LOG(level, format, ...) \
    23   LOG((LOG_TAG ": " format "\n", ##__VA_ARGS__)); \
    24   __android_log_print(level, LOG_TAG, format, ##__VA_ARGS__)
    26 #define LOGI(format, ...) GONK_LOG(ANDROID_LOG_INFO, format, ##__VA_ARGS__)
    27 #define LOGE(format, ...) GONK_LOG(ANDROID_LOG_ERROR, format, ##__VA_ARGS__)
    29 const char *kGonkMountsPath = "/proc/mounts";
    30 const char *kGonkSystemPath = "/system";
    32 GonkAutoMounter::GonkAutoMounter() : mDevice(nullptr), mAccess(Unknown)
    33 {
    34   if (!RemountSystem(ReadWrite)) {
    35     LOGE("Could not remount %s as read-write.", kGonkSystemPath);
    36   }
    37 }
    39 GonkAutoMounter::~GonkAutoMounter()
    40 {
    41   bool result = RemountSystem(ReadOnly);
    42   free(mDevice);
    44   if (!result) {
    45     // Don't take any chances when remounting as read-only fails, just reboot.
    46     Reboot();
    47   }
    48 }
    50 void
    51 GonkAutoMounter::Reboot()
    52 {
    53   // The android_reboot wrapper provides more safety, doing fancier read-only
    54   // remounting and attempting to sync() the filesystem first. If this fails
    55   // our only hope is to force a reboot directly without these protections.
    56   // For more, see system/core/libcutils/android_reboot.c
    57   LOGE("Could not remount %s as read-only, forcing a system reboot.",
    58        kGonkSystemPath);
    59   LogFlush();
    61   if (android_reboot(ANDROID_RB_RESTART, 0, nullptr) != 0) {
    62     LOGE("Safe system reboot failed, attempting to force");
    63     LogFlush();
    65     if (reboot(RB_AUTOBOOT) != 0) {
    66       LOGE("CRITICAL: Failed to force restart");
    67     }
    68   }
    69 }
    71 static const char *
    72 MountAccessToString(MountAccess access)
    73 {
    74   switch (access) {
    75     case ReadOnly: return "read-only";
    76     case ReadWrite: return "read-write";
    77     default: return "unknown";
    78   }
    79 }
    81 bool
    82 GonkAutoMounter::RemountSystem(MountAccess access)
    83 {
    84   if (!UpdateMountStatus()) {
    85     return false;
    86   }
    88   if (mAccess == access) {
    89     return true;
    90   }
    92   unsigned long flags = MS_REMOUNT;
    93   if (access == ReadOnly) {
    94     flags |= MS_RDONLY;
    95     // Give the system a chance to flush file buffers
    96     sync();
    97   }
    99   if (!MountSystem(flags)) {
   100     return false;
   101   }
   103   // Check status again to verify /system has been properly remounted
   104   if (!UpdateMountStatus()) {
   105     return false;
   106   }
   108   if (mAccess != access) {
   109     LOGE("Updated mount status %s should be %s",
   110          MountAccessToString(mAccess),
   111          MountAccessToString(access));
   112     return false;
   113   }
   115   return true;
   116 }
   118 bool
   119 GonkAutoMounter::UpdateMountStatus()
   120 {
   121   FILE *mountsFile = NS_tfopen(kGonkMountsPath, "r");
   123   if (mountsFile == nullptr) {
   124     LOGE("Error opening %s: %s", kGonkMountsPath, strerror(errno));
   125     return false;
   126   }
   128   // /proc/mounts returns a 0 size from fstat, so we use the same
   129   // pre-allocated buffer size that ADB does here
   130   const int mountsMaxSize = 4096;
   131   char mountData[mountsMaxSize];
   132   size_t read = fread(mountData, 1, mountsMaxSize - 1, mountsFile);
   133   mountData[read + 1] = '\0';
   135   if (ferror(mountsFile)) {
   136     LOGE("Error reading %s, %s", kGonkMountsPath, strerror(errno));
   137     fclose(mountsFile);
   138     return false;
   139   }
   141   char *token, *tokenContext;
   142   bool foundSystem = false;
   144   for (token = strtok_r(mountData, "\n", &tokenContext);
   145        token;
   146        token = strtok_r(nullptr, "\n", &tokenContext))
   147   {
   148     if (ProcessMount(token)) {
   149       foundSystem = true;
   150       break;
   151     }
   152   }
   154   fclose(mountsFile);
   156   if (!foundSystem) {
   157     LOGE("Couldn't find %s mount in %s", kGonkSystemPath, kGonkMountsPath);
   158   }
   159   return foundSystem;
   160 }
   162 bool
   163 GonkAutoMounter::ProcessMount(const char *mount)
   164 {
   165   const int strSize = 256;
   166   char mountDev[strSize];
   167   char mountDir[strSize];
   168   char mountAccess[strSize];
   170   int rv = sscanf(mount, "%255s %255s %*s %255s %*d %*d\n",
   171                   mountDev, mountDir, mountAccess);
   172   mountDev[strSize - 1] = '\0';
   173   mountDir[strSize - 1] = '\0';
   174   mountAccess[strSize - 1] = '\0';
   176   if (rv != 3) {
   177     return false;
   178   }
   180   if (strcmp(kGonkSystemPath, mountDir) != 0) {
   181     return false;
   182   }
   184   free(mDevice);
   185   mDevice = strdup(mountDev);
   186   mAccess = Unknown;
   188   char *option, *optionContext;
   189   for (option = strtok_r(mountAccess, ",", &optionContext);
   190        option;
   191        option = strtok_r(nullptr, ",", &optionContext))
   192   {
   193     if (strcmp("ro", option) == 0) {
   194       mAccess = ReadOnly;
   195       break;
   196     } else if (strcmp("rw", option) == 0) {
   197       mAccess = ReadWrite;
   198       break;
   199     }
   200   }
   202   return true;
   203 }
   205 bool
   206 GonkAutoMounter::MountSystem(unsigned long flags)
   207 {
   208   if (!mDevice) {
   209     LOGE("No device was found for %s", kGonkSystemPath);
   210     return false;
   211   }
   213   const char *readOnly = flags & MS_RDONLY ? "read-only" : "read-write";
   214   int result = mount(mDevice, kGonkSystemPath, "none", flags, nullptr);
   216   if (result != 0) {
   217     LOGE("Error mounting %s as %s: %s", kGonkSystemPath, readOnly,
   218          strerror(errno));
   219     return false;
   220   }
   222   LOGI("Mounted %s partition as %s", kGonkSystemPath, readOnly);
   223   return true;
   224 }

mercurial