lmkd: limit capability set to minimum

Set F() capability set and 'drop' lmkd from AID_ROOT to AID_LMKD uid
and from AID_ROOT to AID_LMKD and AID_SYSTEM gid.

/dev/memcg/memory.pressure defaults to root.root mode 0000, set it up
as root.system mode 0040 to allow lmkd read access.

Instrument failure to set SCHED_FIFO.

Annotate access points that require elevated capabilities.

Test: check /proc/`pidof lmkd`/status for capability set
Test: lmkd_unit_test
Bug: 77650566
Change-Id: I986081a0434cf6e842b63a55726380205b30a3ea
This commit is contained in:
Mark Salyzyn 2018-04-09 09:50:32 -07:00
parent 22dc27b9fa
commit 64d97d8761
4 changed files with 21 additions and 4 deletions

View file

@ -129,6 +129,7 @@
#define AID_STATSD 1066 /* statsd daemon */
#define AID_INCIDENTD 1067 /* incidentd daemon */
#define AID_SECURE_ELEMENT 1068 /* secure element subsystem */
#define AID_LMKD 1069 /* low memory killer daemon */
/* Changes to this file must be made in AOSP, *not* in internal branches. */
#define AID_SHELL 2000 /* adb and debug shell user */

View file

@ -68,6 +68,7 @@
#define MEMINFO_PATH "/proc/meminfo"
#define LINE_MAX 128
/* gid containing AID_SYSTEM required */
#define INKERNEL_MINFREE_PATH "/sys/module/lowmemorykiller/parameters/minfree"
#define INKERNEL_ADJ_PATH "/sys/module/lowmemorykiller/parameters/adj"
@ -455,6 +456,9 @@ static void cmd_procprio(LMKD_CTRL_PACKET packet) {
return;
}
/* gid containing AID_READPROC required */
/* CAP_SYS_RESOURCE required */
/* CAP_DAC_OVERRIDE required */
snprintf(path, sizeof(path), "/proc/%d/oom_score_adj", params.pid);
snprintf(val, sizeof(val), "%d", params.oomadj);
if (!writefilestring(path, val, false)) {
@ -496,8 +500,7 @@ static void cmd_procprio(LMKD_CTRL_PACKET packet) {
soft_limit_mult = 64;
}
snprintf(path, sizeof(path),
"/dev/memcg/apps/uid_%d/pid_%d/memory.soft_limit_in_bytes",
snprintf(path, sizeof(path), MEMCG_SYSFS_PATH "apps/uid_%d/pid_%d/memory.soft_limit_in_bytes",
params.uid, params.pid);
snprintf(val, sizeof(val), "%d", soft_limit_mult * EIGHT_MEGA);
@ -859,6 +862,7 @@ static int proc_get_size(int pid) {
int total;
ssize_t ret;
/* gid containing AID_READPROC required */
snprintf(path, PATH_MAX, "/proc/%d/statm", pid);
fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd == -1)
@ -882,6 +886,7 @@ static char *proc_get_name(int pid) {
char *cp;
ssize_t ret;
/* gid containing AID_READPROC required */
snprintf(path, PATH_MAX, "/proc/%d/cmdline", pid);
fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd == -1)
@ -949,6 +954,7 @@ static int kill_one_process(struct proc* procp, int min_score_adj,
TRACE_KILL_START(pid);
/* CAP_KILL required */
r = kill(pid, SIGKILL);
ALOGI(
"Killing '%s' (%d), uid %d, adj %d\n"
@ -1267,6 +1273,7 @@ static bool init_mp_common(enum vmpressure_level level) {
int level_idx = (int)level;
const char *levelstr = level_name[level_idx];
/* gid containing AID_SYSTEM required */
mpfd = open(MEMCG_SYSFS_PATH "memory.pressure_level", O_RDONLY | O_CLOEXEC);
if (mpfd < 0) {
ALOGI("No kernel memory.pressure_level support (errno=%d)", errno);
@ -1478,11 +1485,15 @@ int main(int argc __unused, char **argv __unused) {
* pins MCL_CURRENT, converging to just MCL_CURRENT as we fault
* in pages.
*/
/* CAP_IPC_LOCK required */
if (mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT) && (errno != EINVAL)) {
ALOGW("mlockall failed %s", strerror(errno));
}
sched_setscheduler(0, SCHED_FIFO, &param);
/* CAP_NICE required */
if (sched_setscheduler(0, SCHED_FIFO, &param)) {
ALOGW("set SCHED_FIFO failed %s", strerror(errno));
}
}
mainloop();

View file

@ -1,6 +1,8 @@
service lmkd /system/bin/lmkd
class core
group root readproc
user lmkd
group lmkd system readproc
capabilities DAC_OVERRIDE KILL IPC_LOCK SYS_NICE SYS_RESOURCE
critical
socket lmkd seqpacket 0660 system system
writepid /dev/cpuset/system-background/tasks

View file

@ -34,6 +34,9 @@ on early-init
# root memory control cgroup, used by lmkd
mkdir /dev/memcg 0700 root system
mount cgroup none /dev/memcg nodev noexec nosuid memory
# memory.pressure_level used by lmkd
chown root system /dev/memcg/memory.pressure_level
chmod 0040 /dev/memcg/memory.pressure_level
# app mem cgroups, used by activity manager, lmkd and zygote
mkdir /dev/memcg/apps/ 0755 system system
# cgroup for system_server and surfaceflinger