lmkd: Restrict lmkd unsolicited notifications only to subscribed recipients

am: 36baf44179

Change-Id: Iccb0b07c089bcf345e2dd8b5b08f412f3a891b9a
This commit is contained in:
Suren Baghdasaryan 2019-12-23 15:02:33 -08:00 committed by android-build-merger
commit 9c7233e6c7
2 changed files with 47 additions and 2 deletions

View File

@ -32,7 +32,8 @@ enum lmk_cmd {
LMK_PROCREMOVE, /* Unregister a process */ LMK_PROCREMOVE, /* Unregister a process */
LMK_PROCPURGE, /* Purge all registered processes */ LMK_PROCPURGE, /* Purge all registered processes */
LMK_GETKILLCNT, /* Get number of kills */ LMK_GETKILLCNT, /* Get number of kills */
LMK_PROCKILL, /* Unsolicited msg to system_server on proc kills */ LMK_SUBSCRIBE, /* Subscribe for asynchronous events */
LMK_PROCKILL, /* Unsolicited msg to subscribed clients on proc kills */
}; };
/* /*
@ -202,6 +203,36 @@ static inline size_t lmkd_pack_set_getkillcnt_repl(LMKD_CTRL_PACKET packet, int
return 2 * sizeof(int); return 2 * sizeof(int);
} }
/* Types of asyncronous events sent from lmkd to its clients */
enum async_event_type {
LMK_ASYNC_EVENT_FIRST,
LMK_ASYNC_EVENT_KILL = LMK_ASYNC_EVENT_FIRST,
LMK_ASYNC_EVENT_COUNT,
};
/* LMK_SUBSCRIBE packet payload */
struct lmk_subscribe {
enum async_event_type evt_type;
};
/*
* For LMK_SUBSCRIBE packet get its payload.
* Warning: no checks performed, caller should ensure valid parameters.
*/
static inline void lmkd_pack_get_subscribe(LMKD_CTRL_PACKET packet, struct lmk_subscribe* params) {
params->evt_type = (enum async_event_type)ntohl(packet[1]);
}
/**
* Prepare LMK_SUBSCRIBE packet and return packet size in bytes.
* Warning: no checks performed, caller should ensure valid parameters.
*/
static inline size_t lmkd_pack_set_subscribe(LMKD_CTRL_PACKET packet, enum async_event_type evt_type) {
packet[0] = htonl(LMK_SUBSCRIBE);
packet[1] = htonl((int)evt_type);
return 2 * sizeof(int);
}
/** /**
* Prepare LMK_PROCKILL unsolicited packet and return packet size in bytes. * Prepare LMK_PROCKILL unsolicited packet and return packet size in bytes.
* Warning: no checks performed, caller should ensure valid parameters. * Warning: no checks performed, caller should ensure valid parameters.

View File

@ -242,6 +242,7 @@ struct event_handler_info {
struct sock_event_handler_info { struct sock_event_handler_info {
int sock; int sock;
pid_t pid; pid_t pid;
uint32_t async_event_mask;
struct event_handler_info handler_info; struct event_handler_info handler_info;
}; };
@ -749,7 +750,7 @@ static void ctrl_data_write_lmk_kill_occurred(pid_t pid, uid_t uid) {
size_t len = lmkd_pack_set_prockills(packet, pid, uid); size_t len = lmkd_pack_set_prockills(packet, pid, uid);
for (int i = 0; i < MAX_DATA_CONN; i++) { for (int i = 0; i < MAX_DATA_CONN; i++) {
if (data_sock[i].sock >= 0) { if (data_sock[i].sock >= 0 && data_sock[i].async_event_mask & 1 << LMK_ASYNC_EVENT_KILL) {
ctrl_data_write(i, (char*)packet, len); ctrl_data_write(i, (char*)packet, len);
} }
} }
@ -1211,6 +1212,13 @@ static void cmd_procpurge(struct ucred *cred) {
} }
} }
static void cmd_subscribe(int dsock_idx, LMKD_CTRL_PACKET packet) {
struct lmk_subscribe params;
lmkd_pack_get_subscribe(packet, &params);
data_sock[dsock_idx].async_event_mask |= 1 << params.evt_type;
}
static void inc_killcnt(int oomadj) { static void inc_killcnt(int oomadj) {
int slot = ADJTOSLOT(oomadj); int slot = ADJTOSLOT(oomadj);
uint8_t idx = killcnt_idx[slot]; uint8_t idx = killcnt_idx[slot];
@ -1401,6 +1409,11 @@ static void ctrl_command_handler(int dsock_idx) {
if (ctrl_data_write(dsock_idx, (char *)packet, len) != len) if (ctrl_data_write(dsock_idx, (char *)packet, len) != len)
return; return;
break; break;
case LMK_SUBSCRIBE:
if (nargs != 1)
goto wronglen;
cmd_subscribe(dsock_idx, packet);
break;
case LMK_PROCKILL: case LMK_PROCKILL:
/* This command code is NOT expected at all */ /* This command code is NOT expected at all */
ALOGE("Received unexpected command code %d", cmd); ALOGE("Received unexpected command code %d", cmd);
@ -1461,6 +1474,7 @@ static void ctrl_connect_handler(int data __unused, uint32_t events __unused,
/* use data to store data connection idx */ /* use data to store data connection idx */
data_sock[free_dscock_idx].handler_info.data = free_dscock_idx; data_sock[free_dscock_idx].handler_info.data = free_dscock_idx;
data_sock[free_dscock_idx].handler_info.handler = ctrl_data_handler; data_sock[free_dscock_idx].handler_info.handler = ctrl_data_handler;
data_sock[free_dscock_idx].async_event_mask = 0;
epev.events = EPOLLIN; epev.events = EPOLLIN;
epev.data.ptr = (void *)&(data_sock[free_dscock_idx].handler_info); epev.data.ptr = (void *)&(data_sock[free_dscock_idx].handler_info);
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, data_sock[free_dscock_idx].sock, &epev) == -1) { if (epoll_ctl(epollfd, EPOLL_CTL_ADD, data_sock[free_dscock_idx].sock, &epev) == -1) {