Merge "meminfo: Fix dmabufinfo total ref accounting"
diff --git a/base/mapped_file.cpp b/base/mapped_file.cpp
index f7901af..faa845d 100644
--- a/base/mapped_file.cpp
+++ b/base/mapped_file.cpp
@@ -16,6 +16,8 @@
#include "android-base/mapped_file.h"
+#include <errno.h>
+
namespace android {
namespace base {
@@ -50,7 +52,14 @@
new MappedFile{static_cast<char*>(base), length, slop, handle});
#else
void* base = mmap(nullptr, file_length, prot, MAP_SHARED, fd, file_offset);
- if (base == MAP_FAILED) return nullptr;
+ if (base == MAP_FAILED) {
+ // http://b/119818070 "app crashes when reading asset of zero length".
+ // mmap fails with EINVAL for a zero length region.
+ if (errno == EINVAL && length == 0) {
+ return std::unique_ptr<MappedFile>(new MappedFile{nullptr, 0, 0});
+ }
+ return nullptr;
+ }
return std::unique_ptr<MappedFile>(new MappedFile{static_cast<char*>(base), length, slop});
#endif
}
diff --git a/base/mapped_file_test.cpp b/base/mapped_file_test.cpp
index 7e89723..cfde73c 100644
--- a/base/mapped_file_test.cpp
+++ b/base/mapped_file_test.cpp
@@ -25,7 +25,6 @@
#include <string>
#include "android-base/file.h"
-#include "android-base/unique_fd.h"
TEST(mapped_file, smoke) {
TemporaryFile tf;
@@ -37,3 +36,13 @@
ASSERT_EQ('l', m->data()[0]);
ASSERT_EQ('o', m->data()[1]);
}
+
+TEST(mapped_file, zero_length_mapping) {
+ // http://b/119818070 "app crashes when reading asset of zero length".
+ // mmap fails with EINVAL for a zero length region.
+ TemporaryFile tf;
+ ASSERT_TRUE(tf.fd != -1);
+
+ auto m = android::base::MappedFile::FromFd(tf.fd, 4096, 0, PROT_READ);
+ ASSERT_EQ(0u, m->size());
+}
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index c7d2cb9..b508b56 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -67,6 +67,13 @@
return ret;
}
+// determine if a filesystem is available
+bool fs_mgr_overlayfs_filesystem_available(const std::string& filesystem) {
+ std::string filesystems;
+ if (!android::base::ReadFileToString("/proc/filesystems", &filesystems)) return false;
+ return filesystems.find("\t" + filesystem + "\n") != std::string::npos;
+}
+
} // namespace
#if ALLOW_ADBD_DISABLE_VERITY == 0 // If we are a user build, provide stubs
@@ -321,6 +328,7 @@
bool fs_mgr_overlayfs_setup_one(const std::string& overlay, const std::string& mount_point,
bool* change) {
auto ret = true;
+ if (fs_mgr_overlayfs_already_mounted(mount_point)) return ret;
auto fsrec_mount_point = overlay + "/" + android::base::Basename(mount_point) + "/";
if (setfscreatecon(kOverlayfsFileContext)) {
@@ -531,7 +539,10 @@
std::vector<std::string> mounts;
auto verity = fs_mgr_overlayfs_verity_enabled_list();
for (auto& entry : *fstab) {
- if (!fs_mgr_wants_overlayfs(&entry)) continue;
+ if (!fs_mgr_overlayfs_already_mounted(entry.mount_point) &&
+ !fs_mgr_wants_overlayfs(&entry)) {
+ continue;
+ }
std::string new_mount_point(fs_mgr_mount_point(entry.mount_point.c_str()));
if (mount_point && (new_mount_point != mount_point)) continue;
if (std::find(verity.begin(), verity.end(), android::base::Basename(new_mount_point)) !=
@@ -625,8 +636,12 @@
// Only a suggestion for _first_ try during mounting
std::string fs_mgr_overlayfs_scratch_mount_type() {
- if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_access("/sys/fs/f2fs")) return "f2fs";
- if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_access("/sys/fs/ext4")) return "ext4";
+ if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("f2fs")) {
+ return "f2fs";
+ }
+ if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("ext4")) {
+ return "ext4";
+ }
return "auto";
}
@@ -657,7 +672,7 @@
if (mnt_type == "f2fs") {
command = kMkF2fs + " -w 4096 -f -d1 -l" + android::base::Basename(kScratchMountPoint);
} else if (mnt_type == "ext4") {
- command = kMkExt4 + " -b 4096 -t ext4 -m 0 -O has_journal -M " + kScratchMountPoint;
+ command = kMkExt4 + " -F -b 4096 -t ext4 -m 0 -O has_journal -M " + kScratchMountPoint;
} else {
errno = ESRCH;
LERROR << mnt_type << " has no mkfs cookbook";
@@ -821,7 +836,10 @@
auto scratch_can_be_mounted = true;
for (const auto& mount_point : fs_mgr_candidate_list(fstab)) {
- if (fs_mgr_overlayfs_already_mounted(mount_point)) continue;
+ if (fs_mgr_overlayfs_already_mounted(mount_point)) {
+ ret = true;
+ continue;
+ }
if (scratch_can_be_mounted) {
scratch_can_be_mounted = false;
auto scratch_device = fs_mgr_overlayfs_scratch_device();
@@ -1002,7 +1020,7 @@
if (fs_mgr_access("/sys/module/overlay/parameters/override_creds")) {
return OverlayfsValidResult::kOverrideCredsRequired;
}
- if (!fs_mgr_access("/sys/module/overlay")) {
+ if (!fs_mgr_overlayfs_filesystem_available("overlay")) {
return OverlayfsValidResult::kNotSupported;
}
struct utsname uts;
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index 4d9bc61..8298bf2 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -1,4 +1,15 @@
#! /bin/bash
+#
+# Divided into four section:
+#
+## USAGE
+## Helper Variables
+## Helper Functions
+## MAINLINE
+
+##
+## USAGE
+##
USAGE="USAGE: `basename ${0}` [-s <SerialNumber>]
@@ -17,20 +28,26 @@
exit 0
fi
-# Helper Variables
+##
+## Helper Variables
+##
SPACE=" "
# A _real_ embedded tab character
TAB="`echo | tr '\n' '\t'`"
# A _real_ embedded escape character
ESCAPE="`echo | tr '\n' '\033'`"
+# A _real_ embedded carriage return character
+CR="`echo | tr '\n' '\r'`"
GREEN="${ESCAPE}[38;5;40m"
RED="${ESCAPE}[38;5;196m"
ORANGE="${ESCAPE}[38;5;255:165:0m"
BLUE="${ESCAPE}[35m"
NORMAL="${ESCAPE}[0m"
-# Helper functions
+##
+## Helper Functions
+##
[ "USAGE: inFastboot
@@ -68,6 +85,8 @@
args="${args}${i}"
elif [ X"${i}" != X"${i#* }" ]; then
args="${args}'${i}'"
+ elif [ X"${i}" != X"${i#*${TAB}}" ]; then
+ args="${args}'${i}'"
else
args="${args}${i}"
fi
@@ -130,16 +149,62 @@
Returns: true if the reboot command succeeded" ]
adb_reboot() {
- adb reboot remount-test &&
+ adb reboot remount-test || true
sleep 2
}
+[ "USAGE: format_duration [<seconds>|<seconds>s|<minutes>m|<hours>h|<days>d]
+
+human readable output whole seconds, whole minutes or mm:ss" ]
+format_duration() {
+ if [ -z "${1}" ]; then
+ echo unknown
+ return
+ fi
+ duration="${1}"
+ if [ X"${duration}" != X"${duration%s}" ]; then
+ duration=${duration%s}
+ elif [ X"${duration}" != X"${duration%m}" ]; then
+ duration=`expr ${duration%m} \* 60`
+ elif [ X"${duration}" != X"${duration%h}" ]; then
+ duration=`expr ${duration%h} \* 3600`
+ elif [ X"${duration}" != X"${duration%d}" ]; then
+ duration=`expr ${duration%d} \* 86400`
+ fi
+ seconds=`expr ${duration} % 60`
+ minutes=`expr \( ${duration} / 60 \) % 60`
+ hours=`expr ${duration} / 3600`
+ if [ 0 -eq ${minutes} -a 0 -eq ${hours} ]; then
+ if [ 1 -eq ${duration} ]; then
+ echo 1 second
+ return
+ fi
+ echo ${duration} seconds
+ return
+ elif [ 60 -eq ${duration} ]; then
+ echo 1 minute
+ return
+ elif [ 0 -eq ${seconds} -a 0 -eq ${hours} ]; then
+ echo ${minutes} minutes
+ return
+ fi
+ if [ 0 -eq ${hours} ]; then
+ echo ${minutes}:`expr ${seconds} / 10``expr ${seconds} % 10`
+ return
+ fi
+ echo ${hours}:`expr ${minutes} / 10``expr ${minutes} % 10`:`expr ${seconds} / 10``expr ${seconds} % 10`
+}
+
[ "USAGE: adb_wait [timeout]
Returns: waits until the device has returned for adb or optional timeout" ]
adb_wait() {
if [ -n "${1}" ]; then
+ echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} "${CR}"
timeout --preserve-status --signal=KILL ${1} adb wait-for-device
+ retval=${?}
+ echo -n " ${CR}"
+ return ${retval}
else
adb wait-for-device
fi
@@ -152,10 +217,14 @@
# fastboot has no wait-for-device, but it does an automatic
# wait and requires (even a nonsensical) command to do so.
if [ -n "${1}" ]; then
- timeout --preserve-status --signal=KILL ${1} fastboot wait-for-device
+ echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} "${CR}"
+ timeout --preserve-status --signal=KILL ${1} fastboot wait-for-device >/dev/null 2>/dev/null
+ retval=${?}
+ echo -n " ${CR}"
+ ( exit ${retval} )
else
- fastboot wait-for-device >/dev/null
- fi >/dev/null 2>/dev/null ||
+ fastboot wait-for-device >/dev/null 2>/dev/null
+ fi ||
inFastboot
}
@@ -310,9 +379,14 @@
-e "^\(overlay\|tmpfs\|none\|sysfs\|proc\|selinuxfs\|debugfs\) " \
-e "^\(bpf\|cg2_bpf\|pstore\|tracefs\|adb\|mtp\|ptp\|devpts\) " \
-e "^\(/data/media\|/dev/block/loop[0-9]*\) " \
+ -e "^rootfs / rootfs rw," \
-e " /\(cache\|mnt/scratch\|mnt/vendor/persist\|persist\|metadata\) "
}
+##
+## MAINLINE
+##
+
if [ X"-s" = X"${1}" -a -n "${2}" ]; then
export ANDROID_SERIAL="${2}"
shift 2
@@ -320,7 +394,7 @@
inFastboot && die "device in fastboot mode"
if ! inAdb; then
- echo "${ORANGE}[ WARNING ]${NORMAL} device not in adb mode ... waiting 2 minutes"
+ echo "${ORANGE}[ WARNING ]${NORMAL} device not in adb mode"
adb_wait 2m
fi
inAdb || die "specified device not in adb mode"
@@ -331,19 +405,38 @@
enforcing=false
fi
-# Do something
+# Do something.
D=`get_property ro.serialno`
[ -n "${D}" ] || D=`get_property ro.boot.serialno`
[ -z "${D}" ] || ANDROID_SERIAL=${D}
+USB_SERIAL=
+[ -z "${ANDROID_SERIAL}" ] || USB_SERIAL=`find /sys/devices -name serial |
+ grep usb |
+ xargs grep -l ${ANDROID_SERIAL}`
+USB_ADDRESS=
+if [ -n "${USB_SERIAL}" ]; then
+ USB_ADDRESS=${USB_SERIAL%/serial}
+ USB_ADDRESS=usb${USB_ADDRESS##*/}
+fi
+[ -z "${ANDROID_SERIAL}${USB_ADDRESS}" ] ||
+ echo "${BLUE}[ INFO ]${NORMAL}" ${ANDROID_SERIAL} ${USB_ADDRESS} >&2
BUILD_DESCRIPTION=`get_property ro.build.description`
-echo "${BLUE}[ INFO ]${NORMAL} ${ANDROID_SERIAL} ${BUILD_DESCRIPTION}" >&2
+[ -z "${BUILD_DESCRIPTION}" ] ||
+ echo "${BLUE}[ INFO ]${NORMAL} ${BUILD_DESCRIPTION}" >&2
+
+VERITY_WAS_ENABLED=false
+if [ "orange" = "`get_property ro.boot.verifiedbootstate`" -a \
+ "2" = "`get_property partition.system.verified`" ]; then
+ VERITY_WAS_ENABLED=true
+fi
echo "${GREEN}[ RUN ]${NORMAL} Testing kernel support for overlayfs" >&2
overlayfs_supported=true;
adb_wait || die "wait for device failed"
-adb_sh ls -d /sys/module/overlay </dev/null >/dev/null &&
+adb_sh ls -d /sys/module/overlay </dev/null >/dev/null 2>/dev/null ||
+ adb_sh grep "nodev${TAB}overlay" /proc/filesystems </dev/null >/dev/null 2>/dev/null &&
echo "${GREEN}[ OK ]${NORMAL} overlay module present" >&2 ||
(
echo "${ORANGE}[ WARNING ]${NORMAL} overlay module not present" >&2 &&
@@ -391,9 +484,9 @@
echo "${ORANGE}[ WARNING ]${NORMAL} rebooting before test" >&2
adb_reboot &&
adb_wait 2m ||
- die "lost device after reboot after wipe"
+ die "lost device after reboot after wipe (USB stack broken?)"
adb_root ||
- die "lost device after elevation to root after wipe"
+ die "lost device after elevation to root after wipe (USB stack broken?)"
fi
D=`adb_sh df -k </dev/null` &&
H=`echo "${D}" | head -1` &&
@@ -455,9 +548,9 @@
L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
adb_reboot &&
adb_wait 2m ||
- die "lost device after reboot requested"
+ die "lost device after reboot requested (USB stack broken?)"
adb_root ||
- die "lost device after elevation to root"
+ die "lost device after elevation to root (USB stack broken?)"
rebooted=true
# re-disable verity to see the setup remarks expected
T=`adb_date`
@@ -544,7 +637,7 @@
echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
die "overlay takeover after remount"
!(adb_sh grep "^overlay " /proc/mounts </dev/null |
- grep -v "^overlay /\(vendor\|system\)/..* overlay ro," |
+ grep -v "^overlay /\(vendor\|system\|bionic\)/..* overlay ro," |
grep " overlay ro,") &&
!(adb_sh grep " rw," /proc/mounts </dev/null |
skip_administrative_mounts data) ||
@@ -555,7 +648,7 @@
fi
fi
-# Check something
+# Check something.
echo "${GREEN}[ RUN ]${NORMAL} push content to /system and /vendor" >&2
@@ -569,17 +662,22 @@
die "vendor hello"
check_eq "${A}" "${B}" /vendor before reboot
-# download libc.so, append some gargage, push back, and check if the file is updated.
+# Download libc.so, append some gargage, push back, and check if the file
+# is updated.
tempdir="`mktemp -d`"
cleanup() {
rm -rf ${tempdir}
}
-adb pull /system/lib/bootstrap/libc.so ${tempdir} || die "pull libc.so from device"
+adb pull /system/lib/bootstrap/libc.so ${tempdir} >/dev/null ||
+ die "pull libc.so from device"
garbage="`hexdump -n 16 -e '4/4 "%08X" 1 "\n"' /dev/random`"
echo ${garbage} >> ${tempdir}/libc.so
-adb push ${tempdir}/libc.so /system/lib/bootstrap/libc.so || die "push libc.so to device"
-adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice || die "pull libc.so from device"
-diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null || die "libc.so differ"
+adb push ${tempdir}/libc.so /system/lib/bootstrap/libc.so >/dev/null ||
+ die "push libc.so to device"
+adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
+ die "pull libc.so from device"
+diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null ||
+ die "libc.so differ"
echo "${GREEN}[ RUN ]${NORMAL} reboot to confirm content persistent" >&2
@@ -605,7 +703,7 @@
die "re-read /system/hello after reboot"
check_eq "${A}" "${B}" /system after reboot
echo "${GREEN}[ OK ]${NORMAL} /system content remains after reboot" >&2
-# Only root can read vendor if sepolicy permissions are as expected
+# Only root can read vendor if sepolicy permissions are as expected.
if ${enforcing}; then
adb_unroot
B="`adb_cat /vendor/hello`" &&
@@ -619,9 +717,9 @@
check_eq "${A}" "${B}" vendor after reboot
echo "${GREEN}[ OK ]${NORMAL} /vendor content remains after reboot" >&2
-# check if the updated libc.so is persistent after reboot
+# Check if the updated libc.so is persistent after reboot.
adb_root &&
- adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice ||
+ adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
die "pull libc.so from device"
diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null || die "libc.so differ"
rm -r ${tempdir}
@@ -677,7 +775,7 @@
fi
fastboot reboot ||
die "can not reboot out of fastboot"
- echo "${ORANGE}[ WARNING ]${NORMAL} adb after fastboot ... waiting 2 minutes"
+ echo "${ORANGE}[ WARNING ]${NORMAL} adb after fastboot"
adb_wait 2m ||
die "did not reboot after flash"
if ${overlayfs_needed}; then
@@ -719,9 +817,26 @@
echo "${GREEN}[ RUN ]${NORMAL} remove test content (cleanup)" >&2
T=`adb_date`
-adb remount &&
+H=`adb remount 2>&1`
+err=${?}
+L=
+D="${H%?Now reboot your device for settings to take effect}"
+if [ X"${H}" != X"${D}" ]; then
+ echo "${ORANGE}[ WARNING ]${NORMAL} adb remount requires a reboot after partial flash (legacy avb)"
+ L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
+ adb_reboot &&
+ adb_wait 2m &&
+ adb_root ||
+ die "failed to reboot"
+ T=`adb_date`
+ H=`adb remount 2>&1`
+ err=${?}
+fi
+echo "${H}"
+[ ${err} = 0 ] &&
( adb_sh rm /vendor/hello </dev/null 2>/dev/null || true ) &&
adb_sh rm /system/hello </dev/null ||
+ ( [ -n "${L}" ] && echo "${L}" && false ) ||
die -t ${T} "cleanup hello"
B="`adb_cat /system/hello`" &&
die "re-read /system/hello after rm"
@@ -768,12 +883,12 @@
die -t ${T} "setup for overlayfs"
fi
-echo "${GREEN}[ RUN ]${NORMAL} test raw remount command" >&2
+echo "${GREEN}[ RUN ]${NORMAL} test raw remount commands" >&2
-# prerequisite is a prepped device from above
+# Prerequisite is a prepped device from above.
adb_reboot &&
adb_wait 2m ||
- die "lost device after reboot to ro state"
+ die "lost device after reboot to ro state (USB stack broken?)"
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null &&
die "/vendor is not read-only"
adb_su mount -o rw,remount /vendor ||
@@ -782,4 +897,12 @@
die "/vendor is not read-write"
echo "${GREEN}[ OK ]${NORMAL} mount -o rw,remount command works" >&2
+if $VERITY_WAS_ENABLED && $overlayfs_supported; then
+ adb_root &&
+ adb enable-verity &&
+ adb_reboot &&
+ adb_wait 2m ||
+ die "failed to restore verity" >&2
+fi
+
echo "${GREEN}[ PASSED ]${NORMAL} adb remount" >&2
diff --git a/init/README.md b/init/README.md
index 3a7c71c..f0e5d55 100644
--- a/init/README.md
+++ b/init/README.md
@@ -161,11 +161,13 @@
Options are modifiers to services. They affect how and when init
runs the service.
-`capabilities <capability> [ <capability>\* ]`
+`capabilities [ <capability>\* ]`
> Set capabilities when exec'ing this service. 'capability' should be a Linux
capability without the "CAP\_" prefix, like "NET\_ADMIN" or "SETPCAP". See
http://man7.org/linux/man-pages/man7/capabilities.7.html for a list of Linux
capabilities.
+ If no capabilities are provided, then all capabilities are removed from this service, even if it
+ runs as root.
`class <name> [ <name>\* ]`
> Specify class names for the service. All services in a
diff --git a/init/service.cpp b/init/service.cpp
index d64f2f3..2186a85 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -218,12 +218,12 @@
Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
const std::vector<std::string>& args)
- : Service(name, 0, 0, 0, {}, 0, 0, "", subcontext_for_restart_commands, args) {}
+ : Service(name, 0, 0, 0, {}, 0, "", subcontext_for_restart_commands, args) {}
Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
- const std::vector<gid_t>& supp_gids, const CapSet& capabilities,
- unsigned namespace_flags, const std::string& seclabel,
- Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args)
+ const std::vector<gid_t>& supp_gids, unsigned namespace_flags,
+ const std::string& seclabel, Subcontext* subcontext_for_restart_commands,
+ const std::vector<std::string>& args)
: name_(name),
classnames_({"default"}),
flags_(flags),
@@ -232,7 +232,6 @@
uid_(uid),
gid_(gid),
supp_gids_(supp_gids),
- capabilities_(capabilities),
namespace_flags_(namespace_flags),
seclabel_(seclabel),
onrestart_(false, subcontext_for_restart_commands, "<Service '" + name + "' onrestart>", 0,
@@ -289,7 +288,7 @@
}
}
// Keep capabilites on uid change.
- if (capabilities_.any() && uid_) {
+ if (capabilities_ && uid_) {
// If Android is running in a container, some securebits might already
// be locked, so don't change those.
unsigned long securebits = prctl(PR_GET_SECUREBITS);
@@ -328,8 +327,8 @@
PLOG(FATAL) << "setpriority failed for " << name_;
}
}
- if (capabilities_.any()) {
- if (!SetCapsForExec(capabilities_)) {
+ if (capabilities_) {
+ if (!SetCapsForExec(*capabilities_)) {
LOG(FATAL) << "cannot set capabilities for " << name_;
}
} else if (uid_) {
@@ -420,7 +419,7 @@
}
unsigned int last_valid_cap = GetLastValidCap();
- if (last_valid_cap >= capabilities_.size()) {
+ if (last_valid_cap >= capabilities_->size()) {
LOG(WARNING) << "last valid run-time capability is larger than CAP_LAST_CAP";
}
@@ -435,7 +434,7 @@
return Error() << StringPrintf("capability '%s' not supported by the kernel",
arg.c_str());
}
- capabilities_[cap] = true;
+ (*capabilities_)[cap] = true;
}
return Success();
}
@@ -796,7 +795,7 @@
// clang-format off
static const Map option_parsers = {
{"capabilities",
- {1, kMax, &Service::ParseCapabilities}},
+ {0, kMax, &Service::ParseCapabilities}},
{"class", {1, kMax, &Service::ParseClass}},
{"console", {0, 1, &Service::ParseConsole}},
{"critical", {0, 0, &Service::ParseCritical}},
@@ -1268,7 +1267,6 @@
std::string name = "exec " + std::to_string(exec_count) + " (" + Join(str_args, " ") + ")";
unsigned flags = SVC_ONESHOT | SVC_TEMPORARY;
- CapSet no_capabilities;
unsigned namespace_flags = 0;
std::string seclabel = "";
@@ -1303,8 +1301,8 @@
}
}
- return std::make_unique<Service>(name, flags, *uid, *gid, supp_gids, no_capabilities,
- namespace_flags, seclabel, nullptr, str_args);
+ return std::make_unique<Service>(name, flags, *uid, *gid, supp_gids, namespace_flags, seclabel,
+ nullptr, str_args);
}
// Shutdown services in the opposite order that they were started.
diff --git a/init/service.h b/init/service.h
index c29723a..c42a5a3 100644
--- a/init/service.h
+++ b/init/service.h
@@ -68,9 +68,9 @@
const std::vector<std::string>& args);
Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
- const std::vector<gid_t>& supp_gids, const CapSet& capabilities,
- unsigned namespace_flags, const std::string& seclabel,
- Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args);
+ const std::vector<gid_t>& supp_gids, unsigned namespace_flags,
+ const std::string& seclabel, Subcontext* subcontext_for_restart_commands,
+ const std::vector<std::string>& args);
static std::unique_ptr<Service> MakeTemporaryOneshotService(const std::vector<std::string>& args);
@@ -192,7 +192,7 @@
uid_t uid_;
gid_t gid_;
std::vector<gid_t> supp_gids_;
- CapSet capabilities_;
+ std::optional<CapSet> capabilities_;
unsigned namespace_flags_;
// Pair of namespace type, path to namespace.
std::vector<std::pair<int, std::string>> namespaces_to_enter_;
diff --git a/init/service_test.cpp b/init/service_test.cpp
index 194aa2b..4bfaa6b 100644
--- a/init/service_test.cpp
+++ b/init/service_test.cpp
@@ -57,7 +57,7 @@
}
Service* service_in_old_memory2 = new (old_memory) Service(
- "test_old_memory", 0U, 0U, 0U, std::vector<gid_t>(), CapSet(), 0U, "", nullptr, dummy_args);
+ "test_old_memory", 0U, 0U, 0U, std::vector<gid_t>(), 0U, "", nullptr, dummy_args);
EXPECT_EQ(0U, service_in_old_memory2->flags());
EXPECT_EQ(0, service_in_old_memory2->pid());
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 0dbbc3f..fab4b4e 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -172,7 +172,10 @@
}
},
- shared_libs: ["liblog"],
+ shared_libs: [
+ "liblog",
+ "libbase",
+ ],
header_libs: [
"libbase_headers",
"libcutils_headers",
diff --git a/libcutils/ashmem-dev.cpp b/libcutils/ashmem-dev.cpp
index f65dc8b..e35b91a 100644
--- a/libcutils/ashmem-dev.cpp
+++ b/libcutils/ashmem-dev.cpp
@@ -29,17 +29,34 @@
#include <errno.h>
#include <fcntl.h>
#include <linux/ashmem.h>
+#include <linux/memfd.h>
+#include <log/log.h>
#include <pthread.h>
+#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
+#include <sys/mman.h>
#include <sys/stat.h>
+#include <sys/syscall.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <unistd.h>
-#include <log/log.h>
+
+#include <android-base/properties.h>
+#include <android-base/unique_fd.h>
#define ASHMEM_DEVICE "/dev/ashmem"
+/* Will be added to UAPI once upstream change is merged */
+#define F_SEAL_FUTURE_WRITE 0x0010
+
+/*
+ * The minimum vendor API level at and after which it is safe to use memfd.
+ * This is to facilitate deprecation of ashmem.
+ */
+#define MIN_MEMFD_VENDOR_API_LEVEL 29
+#define MIN_MEMFD_VENDOR_API_LEVEL_CHAR 'Q'
+
/* ashmem identity */
static dev_t __ashmem_rdev;
/*
@@ -72,6 +89,130 @@
}
#endif
+/*
+ * has_memfd_support() determines if the device can use memfd. memfd support
+ * has been there for long time, but certain things in it may be missing. We
+ * check for needed support in it. Also we check if the VNDK version of
+ * libcutils being used is new enough, if its not, then we cannot use memfd
+ * since the older copies may be using ashmem so we just use ashmem. Once all
+ * Android devices that are getting updates are new enough (ex, they were
+ * originally shipped with Android release > P), then we can just use memfd and
+ * delete all ashmem code from libcutils (while preserving the interface).
+ *
+ * NOTE:
+ * The sys.use_memfd property is set by default to false in Android
+ * to temporarily disable memfd, till vendor and apps are ready for it.
+ * The main issue: either apps or vendor processes can directly make ashmem
+ * IOCTLs on FDs they receive by assuming they are ashmem, without going
+ * through libcutils. Such fds could have very well be originally created with
+ * libcutils hence they could be memfd. Thus the IOCTLs will break.
+ *
+ * Set default value of sys.use_memfd property to true once the issue is
+ * resolved, so that the code can then self-detect if kernel support is present
+ * on the device. The property can also set to true from adb shell, for
+ * debugging.
+ */
+
+static bool debug_log = false; /* set to true for verbose logging and other debug */
+static bool pin_deprecation_warn = true; /* Log the pin deprecation warning only once */
+
+/* Determine if vendor processes would be ok with memfd in the system:
+ *
+ * If VNDK is using older libcutils, don't use memfd. This is so that the
+ * same shared memory mechanism is used across binder transactions between
+ * vendor partition processes and system partition processes.
+ */
+static bool check_vendor_memfd_allowed() {
+ std::string vndk_version = android::base::GetProperty("ro.vndk.version", "");
+
+ if (vndk_version == "") {
+ ALOGE("memfd: ro.vndk.version not defined or invalid (%s), this is mandated since P.\n",
+ vndk_version.c_str());
+ return false;
+ }
+
+ /* No issues if vendor is targetting current Dessert */
+ if (vndk_version == "current") {
+ return false;
+ }
+
+ /* Check if VNDK version is a number and act on it */
+ char* p;
+ long int vers = strtol(vndk_version.c_str(), &p, 10);
+ if (*p == 0) {
+ if (vers < MIN_MEMFD_VENDOR_API_LEVEL) {
+ ALOGI("memfd: device VNDK version (%s) is < Q so using ashmem.\n",
+ vndk_version.c_str());
+ return false;
+ }
+
+ return true;
+ }
+
+ /* If its not a number, assume string, but check if its a sane string */
+ if (tolower(vndk_version[0]) < 'a' || tolower(vndk_version[0]) > 'z') {
+ ALOGE("memfd: ro.vndk.version not defined or invalid (%s), this is mandated since P.\n",
+ vndk_version.c_str());
+ return false;
+ }
+
+ if (tolower(vndk_version[0]) < tolower(MIN_MEMFD_VENDOR_API_LEVEL_CHAR)) {
+ ALOGI("memfd: device is using VNDK version (%s) which is less than Q. Use ashmem only.\n",
+ vndk_version.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+
+/* Determine if memfd can be supported. This is just one-time hardwork
+ * which will be cached by the caller.
+ */
+static bool __has_memfd_support() {
+ if (check_vendor_memfd_allowed() == false) {
+ return false;
+ }
+
+ /* Used to turn on/off the detection at runtime, in the future this
+ * property will be removed once we switch everything over to ashmem.
+ * Currently it is used only for debugging to switch the system over.
+ */
+ if (!android::base::GetBoolProperty("sys.use_memfd", false)) {
+ if (debug_log) {
+ ALOGD("sys.use_memfd=false so memfd disabled\n");
+ }
+ return false;
+ }
+
+ /* Check if kernel support exists, otherwise fall back to ashmem */
+ android::base::unique_fd fd(
+ syscall(__NR_memfd_create, "test_android_memfd", MFD_ALLOW_SEALING));
+ if (fd == -1) {
+ ALOGE("memfd_create failed: %s, no memfd support.\n", strerror(errno));
+ return false;
+ }
+
+ if (fcntl(fd, F_ADD_SEALS, F_SEAL_FUTURE_WRITE) == -1) {
+ ALOGE("fcntl(F_ADD_SEALS) failed: %s, no memfd support.\n", strerror(errno));
+ return false;
+ }
+
+ if (debug_log) {
+ ALOGD("memfd: device has memfd support, using it\n");
+ }
+ return true;
+}
+
+static bool has_memfd_support() {
+ /* memfd_supported is the initial global per-process state of what is known
+ * about memfd.
+ */
+ static bool memfd_supported = __has_memfd_support();
+
+ return memfd_supported;
+}
+
/* logistics of getting file descriptor for ashmem */
static int __ashmem_open_locked()
{
@@ -177,11 +318,49 @@
return result;
}
+static bool memfd_is_ashmem(int fd) {
+ static bool fd_check_error_once = false;
+
+ if (__ashmem_is_ashmem(fd, 0) == 0) {
+ if (!fd_check_error_once) {
+ ALOGE("memfd: memfd expected but ashmem fd used - please use libcutils.\n");
+ fd_check_error_once = true;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
int ashmem_valid(int fd)
{
+ if (has_memfd_support() && !memfd_is_ashmem(fd)) {
+ return 1;
+ }
+
return __ashmem_is_ashmem(fd, 0) >= 0;
}
+static int memfd_create_region(const char* name, size_t size) {
+ android::base::unique_fd fd(syscall(__NR_memfd_create, name, MFD_ALLOW_SEALING));
+
+ if (fd == -1) {
+ ALOGE("memfd_create(%s, %zd) failed: %s\n", name, size, strerror(errno));
+ return -1;
+ }
+
+ if (ftruncate(fd, size) == -1) {
+ ALOGE("ftruncate(%s, %zd) failed for memfd creation: %s\n", name, size, strerror(errno));
+ return -1;
+ }
+
+ if (debug_log) {
+ ALOGE("memfd_create(%s, %zd) success. fd=%d\n", name, size, fd.get());
+ }
+ return fd.release();
+}
+
/*
* ashmem_create_region - creates a new ashmem region and returns the file
* descriptor, or <0 on error
@@ -193,6 +372,10 @@
{
int ret, save_errno;
+ if (has_memfd_support()) {
+ return memfd_create_region(name ? name : "none", size);
+ }
+
int fd = __ashmem_open();
if (fd < 0) {
return fd;
@@ -222,28 +405,78 @@
return ret;
}
+static int memfd_set_prot_region(int fd, int prot) {
+ /* Only proceed if an fd needs to be write-protected */
+ if (prot & PROT_WRITE) {
+ return 0;
+ }
+
+ if (fcntl(fd, F_ADD_SEALS, F_SEAL_FUTURE_WRITE) == -1) {
+ ALOGE("memfd_set_prot_region(%d, %d): F_SEAL_FUTURE_WRITE seal failed: %s\n", fd, prot,
+ strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
int ashmem_set_prot_region(int fd, int prot)
{
+ if (has_memfd_support() && !memfd_is_ashmem(fd)) {
+ return memfd_set_prot_region(fd, prot);
+ }
+
return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_SET_PROT_MASK, prot)));
}
int ashmem_pin_region(int fd, size_t offset, size_t len)
{
+ if (!pin_deprecation_warn || debug_log) {
+ ALOGE("Pinning is deprecated since Android Q. Please use trim or other methods.\n");
+ pin_deprecation_warn = true;
+ }
+
+ if (has_memfd_support() && !memfd_is_ashmem(fd)) {
+ return 0;
+ }
+
// TODO: should LP64 reject too-large offset/len?
ashmem_pin pin = { static_cast<uint32_t>(offset), static_cast<uint32_t>(len) };
-
return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_PIN, &pin)));
}
int ashmem_unpin_region(int fd, size_t offset, size_t len)
{
+ if (!pin_deprecation_warn || debug_log) {
+ ALOGE("Pinning is deprecated since Android Q. Please use trim or other methods.\n");
+ pin_deprecation_warn = true;
+ }
+
+ if (has_memfd_support() && !memfd_is_ashmem(fd)) {
+ return 0;
+ }
+
// TODO: should LP64 reject too-large offset/len?
ashmem_pin pin = { static_cast<uint32_t>(offset), static_cast<uint32_t>(len) };
-
return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_UNPIN, &pin)));
}
int ashmem_get_size_region(int fd)
{
+ if (has_memfd_support() && !memfd_is_ashmem(fd)) {
+ struct stat sb;
+
+ if (fstat(fd, &sb) == -1) {
+ ALOGE("ashmem_get_size_region(%d): fstat failed: %s\n", fd, strerror(errno));
+ return -1;
+ }
+
+ if (debug_log) {
+ ALOGD("ashmem_get_size_region(%d): %d\n", fd, static_cast<int>(sb.st_size));
+ }
+
+ return sb.st_size;
+ }
+
return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL)));
}
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index 59cbbc5..c95868d 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -88,6 +88,9 @@
{ 00755, AID_ROOT, AID_ROOT, 0, "system/etc/ppp" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/vendor" },
{ 00751, AID_ROOT, AID_SHELL, 0, "system/xbin" },
+ // TODO(b/123743953): eliminate the APEX name with better pattern matching
+ { 00755, AID_ROOT, AID_SHELL, 0, "system/apex/com.android.runtime.debug/bin" },
+ { 00755, AID_ROOT, AID_SHELL, 0, "system/apex/com.android.runtime.release/bin" },
{ 00751, AID_ROOT, AID_SHELL, 0, "vendor/bin" },
{ 00755, AID_ROOT, AID_SHELL, 0, "vendor" },
{ 00755, AID_ROOT, AID_ROOT, 0, 0 },
@@ -214,6 +217,9 @@
{ 00755, AID_ROOT, AID_ROOT, 0, "system/lib/valgrind/*" },
{ 00755, AID_ROOT, AID_ROOT, 0, "system/lib64/valgrind/*" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/*" },
+ // TODO(b/123743953): eliminate the APEX name with better pattern matching
+ { 00755, AID_ROOT, AID_SHELL, 0, "system/apex/com.android.runtime.debug/bin/*" },
+ { 00755, AID_ROOT, AID_SHELL, 0, "system/apex/com.android.runtime.release/bin/*" },
{ 00755, AID_ROOT, AID_SHELL, 0, "vendor/bin/*" },
{ 00755, AID_ROOT, AID_SHELL, 0, "vendor/xbin/*" },
{ 00644, AID_ROOT, AID_ROOT, 0, 0 },
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index a4e00bd..5394d7e 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -118,7 +118,16 @@
static constexpr const char* kRuntimeNamespaceName = "runtime";
+// classloader-namespace is a linker namespace that is created for the loaded
+// app. To be specific, it is created for the app classloader. When
+// System.load() is called from a Java class that is loaded from the
+// classloader, the classloader-namespace namespace associated with that
+// classloader is selected for dlopen. The namespace is configured so that its
+// search path is set to the app-local JNI directory and it is linked to the
+// default namespace with the names of libs listed in the public.libraries.txt.
+// This way an app can only load its own JNI libraries along with the public libs.
static constexpr const char* kClassloaderNamespaceName = "classloader-namespace";
+// Same thing for vendor APKs.
static constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace";
// (http://b/27588281) This is a workaround for apps using custom classloaders and calling
diff --git a/libpixelflinger/tests/Android.bp b/libpixelflinger/tests/Android.bp
index 820a84d..e20dd93 100644
--- a/libpixelflinger/tests/Android.bp
+++ b/libpixelflinger/tests/Android.bp
@@ -8,6 +8,7 @@
header_libs: ["libpixelflinger_internal"],
static_libs: [
+ "libbase",
"libcutils",
"liblog",
"libpixelflinger",
diff --git a/libprocessgroup/cgroup_map.cpp b/libprocessgroup/cgroup_map.cpp
index 12cfb7e..cd8ef94 100644
--- a/libprocessgroup/cgroup_map.cpp
+++ b/libprocessgroup/cgroup_map.cpp
@@ -19,6 +19,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <grp.h>
#include <pwd.h>
#include <sys/mman.h>
#include <sys/mount.h>
@@ -72,26 +73,28 @@
}
}
- passwd* uid_pwd = nullptr;
- passwd* gid_pwd = nullptr;
-
- if (!uid.empty()) {
- uid_pwd = getpwnam(uid.c_str());
- if (!uid_pwd) {
- PLOG(ERROR) << "Unable to decode UID for '" << uid << "'";
- return false;
- }
-
- if (!gid.empty()) {
- gid_pwd = getpwnam(gid.c_str());
- if (!gid_pwd) {
- PLOG(ERROR) << "Unable to decode GID for '" << gid << "'";
- return false;
- }
- }
+ if (uid.empty()) {
+ return true;
}
- if (uid_pwd && lchown(path.c_str(), uid_pwd->pw_uid, gid_pwd ? gid_pwd->pw_uid : -1) < 0) {
+ passwd* uid_pwd = getpwnam(uid.c_str());
+ if (!uid_pwd) {
+ PLOG(ERROR) << "Unable to decode UID for '" << uid << "'";
+ return false;
+ }
+
+ uid_t pw_uid = uid_pwd->pw_uid;
+ gid_t gr_gid = -1;
+ if (!gid.empty()) {
+ group* gid_pwd = getgrnam(gid.c_str());
+ if (!gid_pwd) {
+ PLOG(ERROR) << "Unable to decode GID for '" << gid << "'";
+ return false;
+ }
+ gr_gid = gid_pwd->gr_gid;
+ }
+
+ if (lchown(path.c_str(), pw_uid, gr_gid) < 0) {
PLOG(ERROR) << "lchown() failed for " << path;
return false;
}
@@ -128,7 +131,8 @@
std::string name = cgroups[i]["Controller"].asString();
descriptors->emplace(std::make_pair(
name,
- CgroupDescriptor(1, name, cgroups[i]["Path"].asString(), cgroups[i]["Mode"].asInt(),
+ CgroupDescriptor(1, name, cgroups[i]["Path"].asString(),
+ std::strtoul(cgroups[i]["Mode"].asString().c_str(), 0, 8),
cgroups[i]["UID"].asString(), cgroups[i]["GID"].asString())));
}
@@ -136,8 +140,8 @@
descriptors->emplace(std::make_pair(
CGROUPV2_CONTROLLER_NAME,
CgroupDescriptor(2, CGROUPV2_CONTROLLER_NAME, cgroups2["Path"].asString(),
- cgroups2["Mode"].asInt(), cgroups2["UID"].asString(),
- cgroups2["GID"].asString())));
+ std::strtoul(cgroups2["Mode"].asString().c_str(), 0, 8),
+ cgroups2["UID"].asString(), cgroups2["GID"].asString())));
return true;
}
diff --git a/libsystem/OWNERS b/libsystem/OWNERS
index aeb160c..fdea804 100644
--- a/libsystem/OWNERS
+++ b/libsystem/OWNERS
@@ -1,2 +1,9 @@
-jessehall@google.com
-olv@google.com
+# graphics/composer
+adyabr@google.com
+lpy@google.com
+marissaw@google.com
+stoza@google.com
+vhau@google.com
+
+# camera
+etalvala@google.com
diff --git a/libutils/FileMap.cpp b/libutils/FileMap.cpp
index 5feb2aa..1202c15 100644
--- a/libutils/FileMap.cpp
+++ b/libutils/FileMap.cpp
@@ -174,12 +174,6 @@
return false;
}
#else // !defined(__MINGW32__)
- int prot, flags, adjust;
- off64_t adjOffset;
- size_t adjLength;
-
- void* ptr;
-
assert(fd >= 0);
assert(offset >= 0);
assert(length > 0);
@@ -193,20 +187,23 @@
}
}
- adjust = offset % mPageSize;
- adjOffset = offset - adjust;
- adjLength = length + adjust;
+ int adjust = offset % mPageSize;
+ off64_t adjOffset = offset - adjust;
+ size_t adjLength = length + adjust;
- flags = MAP_SHARED;
- prot = PROT_READ;
- if (!readOnly)
- prot |= PROT_WRITE;
+ int flags = MAP_SHARED;
+ int prot = PROT_READ;
+ if (!readOnly) prot |= PROT_WRITE;
- ptr = mmap(nullptr, adjLength, prot, flags, fd, adjOffset);
+ void* ptr = mmap(nullptr, adjLength, prot, flags, fd, adjOffset);
if (ptr == MAP_FAILED) {
- ALOGE("mmap(%lld,%zu) failed: %s\n",
- (long long)adjOffset, adjLength, strerror(errno));
- return false;
+ if (errno == EINVAL && length == 0) {
+ ptr = nullptr;
+ adjust = 0;
+ } else {
+ ALOGE("mmap(%lld,%zu) failed: %s\n", (long long)adjOffset, adjLength, strerror(errno));
+ return false;
+ }
}
mBasePtr = ptr;
#endif // !defined(__MINGW32__)
@@ -217,8 +214,6 @@
mDataPtr = (char*) mBasePtr + adjust;
mDataLength = length;
- assert(mBasePtr != NULL);
-
ALOGV("MAP: base %p/%zu data %p/%zu\n",
mBasePtr, mBaseLength, mDataPtr, mDataLength);
diff --git a/libutils/tests/Android.bp b/libutils/tests/Android.bp
index 1390552..62f5acb 100644
--- a/libutils/tests/Android.bp
+++ b/libutils/tests/Android.bp
@@ -22,6 +22,7 @@
srcs: [
"BitSet_test.cpp",
+ "FileMap_test.cpp",
"LruCache_test.cpp",
"Mutex_test.cpp",
"Singleton_test.cpp",
diff --git a/libutils/tests/FileMap_test.cpp b/libutils/tests/FileMap_test.cpp
new file mode 100644
index 0000000..576d89b
--- /dev/null
+++ b/libutils/tests/FileMap_test.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * 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 "utils/FileMap.h"
+
+#include <gtest/gtest.h>
+
+#include "android-base/file.h"
+
+TEST(FileMap, zero_length_mapping) {
+ // http://b/119818070 "app crashes when reading asset of zero length".
+ // mmap fails with EINVAL for a zero length region.
+ TemporaryFile tf;
+ ASSERT_TRUE(tf.fd != -1);
+
+ android::FileMap m;
+ ASSERT_TRUE(m.create("test", tf.fd, 4096, 0, true));
+ ASSERT_STREQ("test", m.getFileName());
+ ASSERT_EQ(0u, m.getDataLength());
+ ASSERT_EQ(4096, m.getDataOffset());
+}
diff --git a/rootdir/cgroups.json b/rootdir/cgroups.json
index 6eb88c9..aa71956 100644
--- a/rootdir/cgroups.json
+++ b/rootdir/cgroups.json
@@ -3,40 +3,40 @@
{
"Controller": "cpu",
"Path": "/dev/cpuctl",
- "Mode": 0755,
+ "Mode": "0755",
"UID": "system",
"GID": "system"
},
{
"Controller": "cpuacct",
"Path": "/acct",
- "Mode": 0555
+ "Mode": "0555"
},
{
"Controller": "cpuset",
"Path": "/dev/cpuset",
- "Mode": 0755,
+ "Mode": "0755",
"UID": "system",
"GID": "system"
},
{
"Controller": "memory",
"Path": "/dev/memcg",
- "Mode": 0700,
+ "Mode": "0700",
"UID": "root",
"GID": "system"
},
{
"Controller": "schedtune",
"Path": "/dev/stune",
- "Mode": 0755,
+ "Mode": "0755",
"UID": "system",
"GID": "system"
}
],
"Cgroups2": {
"Path": "/dev/cg2_bpf",
- "Mode": 0600,
+ "Mode": "0600",
"UID": "root",
"GID": "root"
}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 59ed47a..370bc1c 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -593,6 +593,11 @@
# Set indication (checked by vold) that we have finished this action
#setprop vold.post_fs_data_done 1
+ # sys.memfd_use set to false by default, which keeps it disabled
+ # until it is confirmed that apps and vendor processes don't make
+ # IOCTLs on ashmem fds any more.
+ setprop sys.use_memfd false
+
# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
on zygote-start && property:ro.crypto.state=unencrypted