summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/platform/msm/Kconfig7
-rw-r--r--drivers/platform/msm/Makefile1
-rw-r--r--drivers/platform/msm/seemp_core/Makefile3
-rw-r--r--drivers/platform/msm/seemp_core/seemp_event_encoder.c167
-rw-r--r--drivers/platform/msm/seemp_core/seemp_event_encoder.h21
-rw-r--r--drivers/platform/msm/seemp_core/seemp_logk.c764
-rw-r--r--drivers/platform/msm/seemp_core/seemp_logk.h161
-rw-r--r--drivers/platform/msm/seemp_core/seemp_ringbuf.c164
-rw-r--r--drivers/platform/msm/seemp_core/seemp_ringbuf.h29
-rw-r--r--fs/proc/base.c8
-rw-r--r--include/linux/seemp_instrumentation.h156
-rw-r--r--include/uapi/linux/Kbuild2
-rw-r--r--include/uapi/linux/seemp_api.h418
-rw-r--r--include/uapi/linux/seemp_param_id.h70
-rw-r--r--net/socket.c6
15 files changed, 1977 insertions, 0 deletions
diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig
index b9f6af465fa8..74c6ccbb9f3c 100644
--- a/drivers/platform/msm/Kconfig
+++ b/drivers/platform/msm/Kconfig
@@ -90,4 +90,11 @@ config MSM_11AD
If you choose to build it as a module, it will be called
msm_11ad_proxy.
+config SEEMP_CORE
+ tristate "SEEMP Core"
+ help
+ This option enables Qualcomm Snapdragron Smart Protection to detect
+ anomalies in various activities. It records task activities in
+ a log and rates the actions according to whether a typical user would
+ use the tools.
endmenu
diff --git a/drivers/platform/msm/Makefile b/drivers/platform/msm/Makefile
index 299fc6f38c26..0d8519dca129 100644
--- a/drivers/platform/msm/Makefile
+++ b/drivers/platform/msm/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_SPS) += sps/
obj-$(CONFIG_EP_PCIE) += ep_pcie/
obj-$(CONFIG_GPIO_USB_DETECT) += gpio-usbdetect.o
obj-$(CONFIG_MSM_11AD) += msm_11ad/
+obj-$(CONFIG_SEEMP_CORE) += seemp_core/
diff --git a/drivers/platform/msm/seemp_core/Makefile b/drivers/platform/msm/seemp_core/Makefile
new file mode 100644
index 000000000000..a26db430718d
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/Makefile
@@ -0,0 +1,3 @@
+ccflags-y += -Iinclude/linux
+obj-$(CONFIG_SEEMP_CORE) += seemp_core.o
+seemp_core-objs:= seemp_logk.o seemp_ringbuf.o seemp_event_encoder.o \ No newline at end of file
diff --git a/drivers/platform/msm/seemp_core/seemp_event_encoder.c b/drivers/platform/msm/seemp_core/seemp_event_encoder.c
new file mode 100644
index 000000000000..1d2b67bf267d
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_event_encoder.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define PROVIDE_PARAM_ID
+
+#include <linux/seemp_param_id.h>
+#include "seemp_event_encoder.h"
+#include "seemp_logk.h"
+
+static char *scan_id(char *s);
+static void encode_seemp_section(char *section_start, char *section_eq,
+ char *section_end, bool param, bool numeric,
+ int id, __s32 numeric_value);
+
+static void check_param_range(char *section_eq, char **s, char ch, bool *param,
+ bool *numeric, int val_len, __s32 *numeric_value)
+{
+ long long_value = 0;
+
+ if (*param && *numeric) {
+ /*check if 2 bytes & in[-99999,999999]*/
+ *numeric = (val_len >= 2);
+ if ((val_len >= 2) && (val_len <= 6)) {
+ if (kstrtol(section_eq + 1, 10, &long_value)
+ != 0) {
+ *numeric = false;
+ } else {
+ *numeric_value = (__s16)long_value;
+ *numeric = (*numeric_value >= -32768) &&
+ (*numeric_value <= 32767);
+ }
+ **s = ch;
+ }
+ }
+}
+
+void encode_seemp_params(struct seemp_logk_blk *blk)
+{
+ char *s = blk->payload.msg + 1;
+
+ blk->payload.msg[BLK_MAX_MSG_SZ - 1] = 0; /* zero-terminate */
+
+ while (true) {
+ char *section_start = s;
+ char *section_eq = scan_id(s);
+ bool param = (section_eq - section_start >= 2) &&
+ (*section_eq == '=') && (section_eq[1] != ' ');
+ bool numeric = false;
+ int id = -1;
+ __s32 numeric_value = 0;
+ int id_len;
+ int val_len;
+ char ch;
+
+ if (param) {
+ id = param_id_index(section_start, section_eq);
+
+ if (id < 0)
+ param = false;
+ }
+
+ if (!param) {
+ s = section_eq;
+ while ((*s != 0) && (*s != ','))
+ s++;
+ } else {
+ s = section_eq + 1; /* equal sign */
+ numeric = (*s == '-') || ((*s >= '0') && (*s <= '9'));
+
+ if (numeric)
+ s++; /* first char of number */
+
+ while ((*s != 0) && (*s != ',')) {
+ if (*s == '=')
+ param = false;
+ else if (!((*s >= '0') && (*s <= '9')))
+ numeric = false;
+
+ s++;
+ }
+
+ if (param) {
+ id_len = section_eq - section_start;
+ val_len = s - (section_eq + 1);
+ param = (id_len >= 2) && (id_len <= 31)
+ && (val_len <= 31);
+ ch = *s;
+ *s = 0;
+
+ check_param_range(section_eq, &s, ch, &param,
+ &numeric, val_len, &numeric_value);
+ }
+ }
+
+ encode_seemp_section(section_start, section_eq, s, param,
+ numeric, id, numeric_value);
+
+ if (*s == 0)
+ break;
+
+ s++;
+ }
+
+ blk->len = s - blk->payload.msg;
+}
+
+static char *scan_id(char *s)
+{
+ while ((*s == '_') ||
+ ((*s >= 'A') && (*s <= 'Z')) ||
+ ((*s >= 'a') && (*s <= 'z'))) {
+ s++;
+ }
+
+ return s;
+}
+
+static void encode_seemp_section(char *section_start, char *section_eq,
+ char *section_end, bool param, bool numeric,
+ int id, __s32 numeric_value) {
+ param = param && (section_eq + 1 < section_end);
+
+ if (!param) {
+ /* Encode skip section */
+ int skip_len = section_end - section_start;
+ char skip_len_hi = skip_len & 0xE0;
+ char skip_len_lo = skip_len & 0x1F;
+
+ if (skip_len < 32) {
+ section_start[-1] = 0xC0 | skip_len_lo;
+ /* [1:1:0:0 0000] */
+ } else {
+ section_start[-1] = 0xE0 | skip_len_lo;
+ /* [1:1:1:0 0000] */
+
+ if (skip_len_hi & 0x20)
+ section_start[0] |= 0x80;
+
+ if (skip_len_hi & 0x40)
+ section_start[1] |= 0x80;
+
+ if (skip_len_hi & 0x80)
+ section_start[2] |= 0x80;
+ }
+ } else {
+ /* Encode ID=VALUE section */
+ char id_len = section_eq - section_start;
+ char value_len = section_end - (section_eq + 1);
+
+ section_start[-1] = 0x00 | id_len;
+ *(__s16 *)section_start = id;
+ section_eq[0] = (!numeric ? 0x80 : 0x00) | value_len;
+
+ if (numeric)
+ *(__s16 *)(section_eq + 1) = numeric_value;
+ }
+}
diff --git a/drivers/platform/msm/seemp_core/seemp_event_encoder.h b/drivers/platform/msm/seemp_core/seemp_event_encoder.h
new file mode 100644
index 000000000000..b75816573fbb
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_event_encoder.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __SEEMP_EVENT_ENCODER_H__
+#define __SEEMP_EVENT_ENCODER_H__
+
+#include "seemp_logk.h"
+
+void encode_seemp_params(struct seemp_logk_blk *blk);
+
+#endif /* __SEEMP_EVENT_ENCODER_H__ */
diff --git a/drivers/platform/msm/seemp_core/seemp_logk.c b/drivers/platform/msm/seemp_core/seemp_logk.c
new file mode 100644
index 000000000000..9901712b647c
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_logk.c
@@ -0,0 +1,764 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "seemp: %s: " fmt, __func__
+
+#include "seemp_logk.h"
+#include "seemp_ringbuf.h"
+
+#ifndef VM_RESERVED
+#define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
+#endif
+
+#define MASK_BUFFER_SIZE 256
+#define FOUR_MB 4
+#define USER_APP_START_UID 10000
+#define YEAR_BASE 1900
+
+static struct seemp_logk_dev *slogk_dev;
+
+static unsigned int ring_sz = FOUR_MB;
+
+/*
+ * default is besteffort, apps do not get blocked
+ */
+static unsigned int block_apps;
+
+
+/*
+ * When this flag is turned on,
+ * kmalloc should be used for ring buf allocation
+ * otherwise it is vmalloc.
+ * default is to use vmalloc
+ * kmalloc has a limit of 4MB
+ */
+unsigned int kmalloc_flag;
+
+static struct class *cl;
+
+static rwlock_t filter_lock;
+static struct seemp_source_mask *pmask;
+static unsigned int num_sources;
+
+static long seemp_logk_reserve_rdblks(
+ struct seemp_logk_dev *sdev, unsigned long arg);
+static long seemp_logk_set_mask(unsigned long arg);
+static long seemp_logk_set_mapping(unsigned long arg);
+static long seemp_logk_check_filter(unsigned long arg);
+static int get_uid_from_message_for_system_event(const char *buffer);
+
+void* (*seemp_logk_kernel_begin)(char **buf);
+
+void (*seemp_logk_kernel_end)(void *blck);
+
+/*
+ * the last param is the permission bits *
+ * kernel logging is done in three steps:
+ * (1) fetch a block, fill everything except payload.
+ * (2) return payload pointer to the caller.
+ * (3) caller fills its data directly into the payload area.
+ * (4) caller invoked finish_record(), to finish writing.
+ */
+void *seemp_logk_kernel_start_record(char **buf)
+{
+ struct seemp_logk_blk *blk;
+ struct timespec now;
+ struct tm ts;
+ int idx;
+ int ret;
+
+ DEFINE_WAIT(write_wait);
+
+ ret = 0;
+ idx = 0;
+ now = current_kernel_time();
+ blk = ringbuf_fetch_wr_block(slogk_dev);
+ if (!blk) {
+ /*
+ * there is no blk to write
+ * if block_apps == 0; quietly return
+ */
+ if (!block_apps) {
+ *buf = NULL;
+ return NULL;
+ }
+ /*else wait for the blks to be available*/
+ while (1) {
+ mutex_lock(&slogk_dev->lock);
+ prepare_to_wait(&slogk_dev->writers_wq,
+ &write_wait, TASK_INTERRUPTIBLE);
+ ret = (slogk_dev->num_write_avail_blks <= 0);
+ if (!ret) {
+ /* don't have to wait*/
+ break;
+ }
+ mutex_unlock(&slogk_dev->lock);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ break;
+ }
+ schedule();
+ }
+
+ finish_wait(&slogk_dev->writers_wq, &write_wait);
+ if (ret)
+ return NULL;
+
+ idx = slogk_dev->write_idx;
+ slogk_dev->write_idx =
+ (slogk_dev->write_idx + 1) % slogk_dev->num_tot_blks;
+ slogk_dev->num_write_avail_blks--;
+ slogk_dev->num_write_in_prog_blks++;
+ slogk_dev->num_writers++;
+
+ blk = &slogk_dev->ring[idx];
+ /*mark block invalid*/
+ blk->status = 0x0;
+ mutex_unlock(&slogk_dev->lock);
+ }
+
+ blk->version = OBSERVER_VERSION;
+ blk->pid = current->tgid;
+ blk->tid = current->pid;
+ blk->uid = (current_uid()).val;
+ blk->sec = now.tv_sec;
+ blk->nsec = now.tv_nsec;
+ strlcpy(blk->appname, current->comm, TASK_COMM_LEN);
+ time_to_tm(now.tv_sec, 0, &ts);
+ ts.tm_year += YEAR_BASE;
+ ts.tm_mon += 1;
+
+ snprintf(blk->ts, TS_SIZE, "%04ld-%02d-%02d %02d:%02d:%02d",
+ ts.tm_year, ts.tm_mon, ts.tm_mday,
+ ts.tm_hour, ts.tm_min, ts.tm_sec);
+
+ *buf = blk->payload.msg;
+
+ return blk;
+}
+
+void seemp_logk_kernel_end_record(void *blck)
+{
+ int current_uid_val = 0;
+ int parsed_current_uid = 0;
+ struct seemp_logk_blk *blk = (struct seemp_logk_blk *)blck;
+
+ if (blk) {
+ /*update status at the very end*/
+ blk->status |= 0x1;
+ current_uid_val = (current_uid()).val;
+ if (current_uid_val < USER_APP_START_UID) {
+ parsed_current_uid =
+ get_uid_from_message_for_system_event(blk->payload.msg);
+ if (parsed_current_uid != -1)
+ blk->uid = parsed_current_uid;
+ else
+ blk->uid = current_uid_val;
+ } else
+ blk->uid = current_uid_val;
+
+ ringbuf_finish_writer(slogk_dev, blk);
+ }
+}
+
+/*
+ * get_uid_from_message_for_system_event() - helper function to get the
+ * uid of the actual app that is changing the state and updating it
+ * accordingly rather than with the system UID = 1000
+ * NOTE: Not a very efficient implementation. This does a N*8 character
+ * comparisons everytime a message with UID less than 10000 is seen
+ */
+static int get_uid_from_message_for_system_event(const char *buffer)
+{
+ char asciiuid[6];
+ long appuid = 0;
+ int aindex = 0;
+ char *comparator_string = "app_uid=";
+ int ret = 0;
+
+ char *p1 = (char *)buffer;
+
+ while (*p1) {
+ char *p1begin = p1;
+ char *p2 = (char *)comparator_string;
+
+ aindex = 0;
+
+ while (*p1 && *p2 && *p1 == *p2) {
+ p1++;
+ p2++;
+ }
+
+ if (*p2 == '\0') {
+ while ((*p1) && (aindex < 5)
+ && (*p1 != ',')) {
+ asciiuid[aindex++] = *p1;
+ p1++;
+ }
+ if (*p1 != ',') {
+ pr_err("Failed to get app_id\n");
+ return -EPERM;
+ }
+ asciiuid[aindex] = '\0';
+
+ /*
+ * now get the integer value of this ascii
+ * string number
+ */
+ ret = kstrtol(asciiuid, 10, &appuid);
+ if (ret != 0) {
+ pr_err("failed in the kstrtol function uid:%s\n",
+ asciiuid);
+ return ret;
+ } else {
+ return (int)(appuid);
+ }
+ }
+
+ p1 = p1begin + 1;
+ }
+ return -EPERM;
+}
+
+static int seemp_logk_usr_record(const char __user *buf, size_t count)
+{
+ struct seemp_logk_blk *blk;
+ struct seemp_logk_blk usr_blk;
+ struct seemp_logk_blk *local_blk;
+ struct timespec now;
+ struct tm ts;
+ int idx, ret;
+ int currentuid;
+ int parsedcurrentuid;
+ DEFINE_WAIT(write_wait);
+
+ if (buf) {
+ local_blk = (struct seemp_logk_blk *)buf;
+ if (copy_from_user(&usr_blk.pid, &local_blk->pid,
+ sizeof(usr_blk.pid)) != 0)
+ return -EFAULT;
+ if (copy_from_user(&usr_blk.tid, &local_blk->tid,
+ sizeof(usr_blk.tid)) != 0)
+ return -EFAULT;
+ if (copy_from_user(&usr_blk.uid, &local_blk->uid,
+ sizeof(usr_blk.uid)) != 0)
+ return -EFAULT;
+ if (copy_from_user(&usr_blk.len, &local_blk->len,
+ sizeof(usr_blk.len)) != 0)
+ return -EFAULT;
+ if (copy_from_user(&usr_blk.payload, &local_blk->payload,
+ sizeof(struct blk_payload)) != 0)
+ return -EFAULT;
+ }
+ idx = ret = 0;
+ now = current_kernel_time();
+ blk = ringbuf_fetch_wr_block(slogk_dev);
+ if (!blk) {
+ if (!block_apps)
+ return 0;
+ while (1) {
+ mutex_lock(&slogk_dev->lock);
+ prepare_to_wait(&slogk_dev->writers_wq,
+ &write_wait,
+ TASK_INTERRUPTIBLE);
+ ret = (slogk_dev->num_write_avail_blks <= 0);
+ if (!ret)
+ break;
+ mutex_unlock(&slogk_dev->lock);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ break;
+ }
+ schedule();
+ }
+ finish_wait(&slogk_dev->writers_wq, &write_wait);
+ if (ret)
+ return -EINTR;
+
+ idx = slogk_dev->write_idx;
+ slogk_dev->write_idx =
+ (slogk_dev->write_idx + 1) % slogk_dev->num_tot_blks;
+ slogk_dev->num_write_avail_blks--;
+ slogk_dev->num_write_in_prog_blks++;
+ slogk_dev->num_writers++;
+ blk = &slogk_dev->ring[idx];
+ /*mark block invalid*/
+ blk->status = 0x0;
+ mutex_unlock(&slogk_dev->lock);
+ }
+ if (usr_blk.len > sizeof(struct blk_payload)-1)
+ usr_blk.len = sizeof(struct blk_payload)-1;
+
+ memcpy(&blk->payload, &usr_blk.payload, sizeof(struct blk_payload));
+ blk->pid = usr_blk.pid;
+ currentuid = usr_blk.uid;
+ if (currentuid <= USER_APP_START_UID) {
+ parsedcurrentuid = get_uid_from_message_for_system_event
+ (blk->payload.msg);
+ if (parsedcurrentuid != -EPERM)
+ blk->uid = parsedcurrentuid;
+ else
+ blk->uid = currentuid;
+ } else
+ blk->uid = currentuid;
+ blk->tid = usr_blk.tid;
+ blk->sec = now.tv_sec;
+ blk->nsec = now.tv_nsec;
+ time_to_tm(now.tv_sec, 0, &ts);
+ ts.tm_year += YEAR_BASE;
+ ts.tm_mon += 1;
+ snprintf(blk->ts, TS_SIZE, "%02ld-%02d-%02d %02d:%02d:%02d",
+ ts.tm_year, ts.tm_mon, ts.tm_mday,
+ ts.tm_hour, ts.tm_min, ts.tm_sec);
+ strlcpy(blk->appname, current->comm, TASK_COMM_LEN);
+ blk->status |= 0x1;
+ ringbuf_finish_writer(slogk_dev, blk);
+ return ret;
+}
+
+static void seemp_logk_attach(void)
+{
+ seemp_logk_kernel_end = seemp_logk_kernel_end_record;
+ seemp_logk_kernel_begin = seemp_logk_kernel_start_record;
+}
+
+static void seemp_logk_detach(void)
+{
+ seemp_logk_kernel_begin = NULL;
+ seemp_logk_kernel_end = NULL;
+}
+
+static ssize_t
+seemp_logk_write(struct file *file, const char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ return seemp_logk_usr_record(buf, count);
+}
+
+static int
+seemp_logk_open(struct inode *inode, struct file *filp)
+{
+ int ret;
+
+ /*disallow seeks on this file*/
+ ret = nonseekable_open(inode, filp);
+ if (ret) {
+ pr_err("ret= %d\n", ret);
+ return ret;
+ }
+
+ slogk_dev->minor = iminor(inode);
+ filp->private_data = slogk_dev;
+
+ return 0;
+}
+
+static bool seemp_logk_get_bit_from_vector(__u8 *pVec, __u32 index)
+{
+ unsigned int byte_num = index/8;
+ unsigned int bit_num = index%8;
+ unsigned char byte = pVec[byte_num];
+
+ return !(byte & (1 << bit_num));
+}
+
+static long seemp_logk_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct seemp_logk_dev *sdev;
+ int ret;
+
+ sdev = (struct seemp_logk_dev *) filp->private_data;
+
+ if (cmd == SEEMP_CMD_RESERVE_RDBLKS) {
+ return seemp_logk_reserve_rdblks(sdev, arg);
+ } else if (cmd == SEEMP_CMD_RELEASE_RDBLKS) {
+ mutex_lock(&sdev->lock);
+ sdev->read_idx = (sdev->read_idx + sdev->num_read_in_prog_blks)
+ % sdev->num_tot_blks;
+ sdev->num_write_avail_blks += sdev->num_read_in_prog_blks;
+ ret = sdev->num_read_in_prog_blks;
+ sdev->num_read_in_prog_blks = 0;
+ /*wake up any waiting writers*/
+ mutex_unlock(&sdev->lock);
+ if (ret && block_apps)
+ wake_up_interruptible(&sdev->writers_wq);
+ return 0;
+ } else if (cmd == SEEMP_CMD_GET_RINGSZ) {
+ if (copy_to_user((unsigned int *)arg, &sdev->ring_sz,
+ sizeof(unsigned int)))
+ return -EFAULT;
+ } else if (cmd == SEEMP_CMD_GET_BLKSZ) {
+ if (copy_to_user((unsigned int *)arg, &sdev->blk_sz,
+ sizeof(unsigned int)))
+ return -EFAULT;
+ } else if (SEEMP_CMD_SET_MASK == cmd) {
+ return seemp_logk_set_mask(arg);
+ } else if (SEEMP_CMD_SET_MAPPING == cmd) {
+ return seemp_logk_set_mapping(arg);
+ } else if (SEEMP_CMD_CHECK_FILTER == cmd) {
+ return seemp_logk_check_filter(arg);
+ }
+ pr_err("Invalid Request %X\n", cmd);
+ return -ENOIOCTLCMD;
+}
+
+static long seemp_logk_reserve_rdblks(
+ struct seemp_logk_dev *sdev, unsigned long arg)
+{
+ int ret;
+ struct read_range rrange;
+
+ DEFINE_WAIT(read_wait);
+
+ mutex_lock(&sdev->lock);
+ if (sdev->num_writers > 0 || sdev->num_read_avail_blks <= 0) {
+ ret = -EPERM;
+ pr_debug("(reserve): blocking, cannot read.\n");
+ pr_debug("num_writers=%d num_read_avail_blks=%d\n",
+ sdev->num_writers,
+ sdev->num_read_avail_blks);
+ mutex_unlock(&sdev->lock);
+ /*
+ * unlock the device
+ * wait on a wait queue
+ * after wait, grab the dev lock again
+ */
+ while (1) {
+ mutex_lock(&sdev->lock);
+ prepare_to_wait(&sdev->readers_wq, &read_wait,
+ TASK_INTERRUPTIBLE);
+ ret = (sdev->num_writers > 0 ||
+ sdev->num_read_avail_blks <= 0);
+ if (!ret) {
+ /*don't have to wait*/
+ break;
+ }
+ mutex_unlock(&sdev->lock);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ break;
+ }
+ schedule();
+ }
+
+ finish_wait(&sdev->readers_wq, &read_wait);
+ if (ret)
+ return -EINTR;
+ }
+
+ /*sdev->lock is held at this point*/
+ sdev->num_read_in_prog_blks = sdev->num_read_avail_blks;
+ sdev->num_read_avail_blks = 0;
+ rrange.start_idx = sdev->read_idx;
+ rrange.num = sdev->num_read_in_prog_blks;
+ mutex_unlock(&sdev->lock);
+
+ if (copy_to_user((unsigned int *)arg, &rrange,
+ sizeof(struct read_range)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static long seemp_logk_set_mask(unsigned long arg)
+{
+ __u8 buffer[256];
+ int i;
+ unsigned int num_elements;
+
+ if (copy_from_user(&num_elements,
+ (unsigned int __user *) arg, sizeof(unsigned int)))
+ return -EFAULT;
+
+ read_lock(&filter_lock);
+ if (0 == num_sources) {
+ read_unlock(&filter_lock);
+ return -EINVAL;
+ }
+
+ if (num_elements == 0 ||
+ MASK_BUFFER_SIZE < DIV_ROUND_UP(num_sources, 8)) {
+ read_unlock(&filter_lock);
+ return -EINVAL;
+ }
+
+ if (copy_from_user(buffer,
+ (__u8 *)arg, DIV_ROUND_UP(num_sources, 8))) {
+ read_unlock(&filter_lock);
+ return -EFAULT;
+ }
+
+ read_unlock(&filter_lock);
+ write_lock(&filter_lock);
+ if (num_elements != num_sources) {
+ write_unlock(&filter_lock);
+ return -EPERM;
+ }
+
+ for (i = 0; i < num_sources; i++) {
+ pmask[i].isOn =
+ seemp_logk_get_bit_from_vector(
+ (__u8 *)buffer, i);
+ }
+ write_unlock(&filter_lock);
+ return 0;
+}
+
+static long seemp_logk_set_mapping(unsigned long arg)
+{
+ __u32 num_elements;
+ __u32 *pbuffer;
+ int i;
+ struct seemp_source_mask *pnewmask;
+
+ if (copy_from_user(&num_elements,
+ (__u32 __user *)arg, sizeof(__u32)))
+ return -EFAULT;
+
+ if ((0 == num_elements) || (num_elements >
+ (UINT_MAX / sizeof(struct seemp_source_mask))))
+ return -EFAULT;
+
+ write_lock(&filter_lock);
+ if (NULL != pmask) {
+ /*
+ * Mask is getting set again.
+ * seemp_core was probably restarted.
+ */
+ struct seemp_source_mask *ptempmask;
+
+ num_sources = 0;
+ ptempmask = pmask;
+ pmask = NULL;
+ kfree(ptempmask);
+ }
+ write_unlock(&filter_lock);
+ pbuffer = kmalloc(sizeof(struct seemp_source_mask)
+ * num_elements, GFP_KERNEL);
+ if (NULL == pbuffer)
+ return -ENOMEM;
+
+ /*
+ * Use our new table as scratch space for now.
+ * We copy an ordered list of hash values into our buffer.
+ */
+ if (copy_from_user(pbuffer, &((__u32 __user *)arg)[1],
+ num_elements*sizeof(unsigned int))) {
+ kfree(pbuffer);
+ return -EFAULT;
+ }
+ /*
+ * We arrange the user data into a more usable form.
+ * This is done in-place.
+ */
+ pnewmask = (struct seemp_source_mask *) pbuffer;
+ for (i = num_elements - 1; i >= 0; i--) {
+ pnewmask[i].hash = pbuffer[i];
+ /* Observer is off by default*/
+ pnewmask[i].isOn = 0;
+ }
+ write_lock(&filter_lock);
+ pmask = pnewmask;
+ num_sources = num_elements;
+ write_unlock(&filter_lock);
+ return 0;
+}
+
+static long seemp_logk_check_filter(unsigned long arg)
+{
+ int i;
+ unsigned int hash = (unsigned int) arg;
+
+ /*
+ * This lock may be a bit long.
+ * If it is a problem, it can be fixed.
+ */
+ read_lock(&filter_lock);
+ for (i = 0; i < num_sources; i++) {
+ if (hash == pmask[i].hash) {
+ int result = pmask[i].isOn;
+
+ read_unlock(&filter_lock);
+ return result;
+ }
+ }
+ read_unlock(&filter_lock);
+ return 0;
+}
+
+static int seemp_logk_mmap(struct file *filp,
+ struct vm_area_struct *vma)
+{
+ int ret;
+ char *vptr;
+ unsigned long length, pfn;
+ unsigned long start = vma->vm_start;
+
+ length = vma->vm_end - vma->vm_start;
+
+ if (length > (unsigned long) slogk_dev->ring_sz) {
+ pr_err("len check failed\n");
+ return -EIO;
+ }
+
+ vma->vm_flags |= VM_RESERVED | VM_SHARED;
+ vptr = (char *) slogk_dev->ring;
+ ret = 0;
+
+ if (kmalloc_flag) {
+ ret = remap_pfn_range(vma,
+ start,
+ virt_to_phys((void *)
+ ((unsigned long)slogk_dev->ring)) >> PAGE_SHIFT,
+ length,
+ vma->vm_page_prot);
+ if (ret != 0) {
+ pr_err("remap_pfn_range() fails with ret = %d\n",
+ ret);
+ return -EAGAIN;
+ }
+ } else {
+ while (length > 0) {
+ pfn = vmalloc_to_pfn(vptr);
+
+ ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE,
+ vma->vm_page_prot);
+ if (ret < 0) {
+ pr_err("remap_pfn_range() fails with ret = %d\n",
+ ret);
+ return ret;
+ }
+ start += PAGE_SIZE;
+ vptr += PAGE_SIZE;
+ length -= PAGE_SIZE;
+ }
+ }
+
+ return 0;
+}
+
+static const struct file_operations seemp_logk_fops = {
+ .write = seemp_logk_write,
+ .open = seemp_logk_open,
+ .unlocked_ioctl = seemp_logk_ioctl,
+ .compat_ioctl = seemp_logk_ioctl,
+ .mmap = seemp_logk_mmap,
+};
+
+__init int seemp_logk_init(void)
+{
+ int ret;
+ int devno = 0;
+
+ num_sources = 0;
+ kmalloc_flag = 0;
+ block_apps = 0;
+ pmask = NULL;
+
+ if (kmalloc_flag && ring_sz > FOUR_MB) {
+ pr_err("kmalloc cannot allocate > 4MB\n");
+ return -ENOMEM;
+ }
+
+ ring_sz = ring_sz * SZ_1M;
+ if (ring_sz <= 0) {
+ pr_err("Too small a ring_sz=%d\n", ring_sz);
+ return -EINVAL;
+ }
+
+ slogk_dev = kmalloc(sizeof(*slogk_dev), GFP_KERNEL);
+ if (!slogk_dev)
+ return -ENOMEM;
+
+ slogk_dev->ring_sz = ring_sz;
+ slogk_dev->blk_sz = sizeof(struct seemp_logk_blk);
+ /*initialize ping-pong buffers*/
+ ret = ringbuf_init(slogk_dev);
+ if (ret < 0) {
+ pr_err("Init Failed, ret = %d\n", ret);
+ goto pingpong_fail;
+ }
+
+ ret = alloc_chrdev_region(&devno, 0, seemp_LOGK_NUM_DEVS,
+ seemp_LOGK_DEV_NAME);
+ if (ret < 0) {
+ pr_err("alloc_chrdev_region failed with ret = %d\n",
+ ret);
+ goto register_fail;
+ }
+
+ slogk_dev->major = MAJOR(devno);
+
+ pr_debug("logk: major# = %d\n", slogk_dev->major);
+
+ cl = class_create(THIS_MODULE, seemp_LOGK_DEV_NAME);
+ if (cl == NULL) {
+ pr_err("class create failed");
+ goto cdev_fail;
+ }
+ if (device_create(cl, NULL, devno, NULL,
+ seemp_LOGK_DEV_NAME) == NULL) {
+ pr_err("device create failed");
+ goto class_destroy_fail;
+ }
+ cdev_init(&(slogk_dev->cdev), &seemp_logk_fops);
+
+ slogk_dev->cdev.owner = THIS_MODULE;
+ ret = cdev_add(&(slogk_dev->cdev), MKDEV(slogk_dev->major, 0), 1);
+ if (ret) {
+ pr_err("cdev_add failed with ret = %d", ret);
+ goto class_destroy_fail;
+ }
+
+ seemp_logk_attach();
+ mutex_init(&slogk_dev->lock);
+ init_waitqueue_head(&slogk_dev->readers_wq);
+ init_waitqueue_head(&slogk_dev->writers_wq);
+ rwlock_init(&filter_lock);
+ return 0;
+class_destroy_fail:
+ class_destroy(cl);
+cdev_fail:
+ unregister_chrdev_region(devno, seemp_LOGK_NUM_DEVS);
+register_fail:
+ ringbuf_cleanup(slogk_dev);
+pingpong_fail:
+ kfree(slogk_dev);
+ return -EPERM;
+}
+
+__exit void seemp_logk_cleanup(void)
+{
+ dev_t devno = MKDEV(slogk_dev->major, slogk_dev->minor);
+
+ seemp_logk_detach();
+
+ cdev_del(&slogk_dev->cdev);
+
+ unregister_chrdev_region(devno, seemp_LOGK_NUM_DEVS);
+ ringbuf_cleanup(slogk_dev);
+ kfree(slogk_dev);
+
+ if (NULL != pmask) {
+ kfree(pmask);
+ pmask = NULL;
+ }
+}
+
+module_init(seemp_logk_init);
+module_exit(seemp_logk_cleanup);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("seemp Observer");
+
diff --git a/drivers/platform/msm/seemp_core/seemp_logk.h b/drivers/platform/msm/seemp_core/seemp_logk.h
new file mode 100644
index 000000000000..30f998b3368a
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_logk.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __SEEMP_LOGK_H__
+#define __SEEMP_LOGK_H__
+
+#define OBSERVER_VERSION 0x01
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+#include <linux/vmalloc.h>
+#include <asm/ioctls.h>
+
+#define seemp_LOGK_NUM_DEVS 1
+#define seemp_LOGK_DEV_NAME "seemplog"
+
+/*
+ * The logcat driver on Android uses four 256k ring buffers
+ * here, we use two ring buffers of the same size.
+ * we think this is reasonable
+ */
+#define FULL_BUF_SIZE (64 * 1024 * 1024)
+#define HALF_BUF_SIZE (32 * 1024 * 1024)
+#define FULL_BLOCKS (8 * 1024)
+#define HALF_BLOCKS (4 * 1024)
+
+#define READER_NOT_READY 0
+#define READER_READY 1
+
+#define MAGIC 'z'
+
+#define SEEMP_CMD_RESERVE_RDBLKS _IOR(MAGIC, 1, int)
+#define SEEMP_CMD_RELEASE_RDBLKS _IO(MAGIC, 2)
+#define SEEMP_CMD_GET_RINGSZ _IOR(MAGIC, 3, int)
+#define SEEMP_CMD_GET_BLKSZ _IOR(MAGIC, 4, int)
+#define SEEMP_CMD_SET_MASK _IO(MAGIC, 5)
+#define SEEMP_CMD_SET_MAPPING _IO(MAGIC, 6)
+#define SEEMP_CMD_CHECK_FILTER _IOR(MAGIC, 7, int)
+
+struct read_range {
+ int start_idx;
+ int num;
+};
+
+struct seemp_logk_dev {
+ unsigned int major;
+ unsigned int minor;
+
+ struct cdev cdev;
+ struct class *cls;
+ /*the full buffer*/
+ struct seemp_logk_blk *ring;
+ /*an array of blks*/
+ unsigned int ring_sz;
+ unsigned int blk_sz;
+
+ int num_tot_blks;
+
+ int num_write_avail_blks;
+ int num_write_in_prog_blks;
+
+ int num_read_avail_blks;
+ int num_read_in_prog_blks;
+
+ int num_writers;
+
+ /*
+ * there is always one reader
+ * which is the observer daemon
+ * therefore there is no necessity
+ * for num_readers variable
+ */
+
+ /*
+ * read_idx and write_idx loop through from zero to ring_sz,
+ * and then back to zero in a circle, as they advance
+ * based on the reader's and writers' accesses
+ */
+ int read_idx;
+
+ int write_idx;
+
+ /*
+ * wait queues
+ * readers_wq: implement wait for readers
+ * writers_wq: implement wait for writers
+ *
+ * whether writers are blocked or not is driven by the policy:
+ * case 1: (best_effort_logging == 1)
+ * writers are not blocked, and
+ * when there is no mem in the ring to store logs,
+ * the logs are simply dropped.
+ * case 2: (best_effort_logging == 0)
+ * when there is no mem in the ring to store logs,
+ * the process gets blocked until there is space.
+ */
+ wait_queue_head_t readers_wq;
+ wait_queue_head_t writers_wq;
+
+ /*
+ * protects everything in the device
+ * including ring buffer and all the num_ variables
+ * spinlock_t lock;
+ */
+ struct mutex lock;
+};
+
+#define BLK_SIZE 256
+#define BLK_HDR_SIZE 68
+#define TS_SIZE 20
+#define BLK_MAX_MSG_SZ (BLK_SIZE - BLK_HDR_SIZE)
+
+struct blk_payload {
+ __u32 api_id; /* event API id */
+ char msg[BLK_MAX_MSG_SZ]; /* event parameters */
+} __packed;
+
+struct seemp_logk_blk {
+ __u8 status; /* bits: 0->valid/invalid; 1-7: unused as of now! */
+ __u16 len; /* length of the payload */
+ __u8 version; /* version number */
+ __s32 pid; /* generating process's pid */
+ __s32 uid; /* generating process's uid - app specific */
+ __s32 tid; /* generating process's tid */
+ __s32 sec; /* seconds since Epoch */
+ __s32 nsec; /* nanoseconds */
+ char ts[TS_SIZE]; /* Time Stamp */
+ char appname[TASK_COMM_LEN];
+ struct blk_payload payload;
+} __packed;
+
+
+extern unsigned int kmalloc_flag;
+
+struct seemp_source_mask {
+ __u32 hash;
+ bool isOn;
+};
+#endif
diff --git a/drivers/platform/msm/seemp_core/seemp_ringbuf.c b/drivers/platform/msm/seemp_core/seemp_ringbuf.c
new file mode 100644
index 000000000000..d77b4eff8d9c
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_ringbuf.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+*/
+
+#define pr_fmt(fmt) "seemp: %s: " fmt, __func__
+
+#include "seemp_logk.h"
+#include "seemp_ringbuf.h"
+#include "seemp_event_encoder.h"
+
+/*initial function no need to hold ring_lock*/
+int ringbuf_init(struct seemp_logk_dev *sdev)
+{
+ char *buf;
+ unsigned long virt_addr;
+
+ if (kmalloc_flag) {
+ sdev->ring = kmalloc(sdev->ring_sz, GFP_KERNEL);
+ if (sdev->ring == NULL) {
+ pr_err("kmalloc failed, ring_sz= %d\n", sdev->ring_sz);
+ return -ENOMEM;
+ }
+
+ buf = (char *)sdev->ring;
+
+ /*reserve kmalloc memory as pages to make them remapable*/
+ for (virt_addr = (unsigned long)buf;
+ virt_addr < (unsigned long)buf + sdev->ring_sz;
+ virt_addr += PAGE_SIZE) {
+ SetPageReserved(virt_to_page((virt_addr)));
+ }
+ } else {
+ sdev->ring = vmalloc(sdev->ring_sz);
+ if (sdev->ring == NULL) {
+ pr_err("vmalloc failed, ring_sz = %d\n", sdev->ring_sz);
+ return -ENOMEM;
+ }
+ buf = (char *)sdev->ring;
+
+ /*reserve vmalloc memory as pages to make them remapable*/
+ for (virt_addr = (unsigned long)buf;
+ virt_addr < (unsigned long)buf + sdev->ring_sz;
+ virt_addr += PAGE_SIZE) {
+ SetPageReserved(vmalloc_to_page(
+ (unsigned long *) virt_addr));
+ }
+ }
+
+ memset(sdev->ring, 0, sdev->ring_sz);
+
+ sdev->num_tot_blks = (sdev->ring_sz / BLK_SIZE);
+ sdev->num_writers = 0;
+ sdev->write_idx = 0;
+ sdev->read_idx = 0;
+
+ sdev->num_write_avail_blks = sdev->num_tot_blks;
+ /*no. of blocks available for write*/
+ sdev->num_write_in_prog_blks = 0;
+ /*no. of blocks held by writers to perform writes*/
+
+ sdev->num_read_avail_blks = 0;
+ /*no. of blocks ready for read*/
+ sdev->num_read_in_prog_blks = 0;
+ /*no. of blocks held by the reader to perform read*/
+
+ return 0;
+}
+
+void ringbuf_cleanup(struct seemp_logk_dev *sdev)
+{
+ unsigned long virt_addr;
+
+ if (kmalloc_flag) {
+ for (virt_addr = (unsigned long)sdev->ring;
+ virt_addr < (unsigned long)sdev->ring + sdev->ring_sz;
+ virt_addr += PAGE_SIZE) {
+ /*clear all pages*/
+ ClearPageReserved(virt_to_page((unsigned long *)
+ virt_addr));
+ }
+ kfree(sdev->ring);
+ } else {
+ for (virt_addr = (unsigned long)sdev->ring;
+ virt_addr < (unsigned long)sdev->ring + sdev->ring_sz;
+ virt_addr += PAGE_SIZE) {
+ /*clear all pages*/
+ ClearPageReserved(vmalloc_to_page((unsigned long *)
+ virt_addr));
+ }
+ vfree(sdev->ring);
+ }
+}
+
+struct seemp_logk_blk *ringbuf_fetch_wr_block
+ (struct seemp_logk_dev *sdev)
+{
+ struct seemp_logk_blk *blk = NULL;
+ int idx;
+
+ mutex_lock(&sdev->lock);
+ if (sdev->num_write_avail_blks == 0) {
+ idx = -1;
+ mutex_unlock(&sdev->lock);
+ return blk;
+ }
+
+ idx = sdev->write_idx;
+ sdev->write_idx = (sdev->write_idx + 1) % sdev->num_tot_blks;
+ sdev->num_write_avail_blks--;
+ sdev->num_write_in_prog_blks++;
+ sdev->num_writers++;
+
+ blk = &sdev->ring[idx];
+ blk->status = 0x0;
+
+ mutex_unlock(&sdev->lock);
+ return blk;
+}
+
+void ringbuf_finish_writer(struct seemp_logk_dev *sdev,
+ struct seemp_logk_blk *blk)
+{
+ /* Encode seemp parameters in multi-threaded mode (before mutex lock) */
+ encode_seemp_params(blk);
+
+ /*
+ * finish writing...
+ * the calling process will no longer access this block.
+ */
+ mutex_lock(&sdev->lock);
+
+ sdev->num_writers--;
+ sdev->num_write_in_prog_blks--;
+ sdev->num_read_avail_blks++;
+
+ /*wake up any readers*/
+ if (sdev->num_writers == 0)
+ wake_up_interruptible(&sdev->readers_wq);
+
+ mutex_unlock(&sdev->lock);
+}
+
+int ringbuf_count_marked(struct seemp_logk_dev *sdev)
+{
+ int i;
+ unsigned int marked;
+
+ mutex_lock(&sdev->lock);
+ for (marked = 0, i = 0; i < sdev->num_tot_blks; i++)
+ if (sdev->ring[i].status & 0x1)
+ marked++;
+ mutex_unlock(&sdev->lock);
+
+ return marked;
+}
diff --git a/drivers/platform/msm/seemp_core/seemp_ringbuf.h b/drivers/platform/msm/seemp_core/seemp_ringbuf.h
new file mode 100644
index 000000000000..95fb9e6bcfee
--- /dev/null
+++ b/drivers/platform/msm/seemp_core/seemp_ringbuf.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+*/
+
+#ifndef __SEEMP_RINGBUF_H__
+#define __SEEMP_RINGBUF_H__
+
+/*
+ * This header exports pingpong's API
+ */
+
+int ringbuf_init(struct seemp_logk_dev *sdev);
+struct seemp_logk_blk *ringbuf_fetch_wr_block
+(struct seemp_logk_dev *sdev);
+void ringbuf_finish_writer(struct seemp_logk_dev *sdev,
+ struct seemp_logk_blk *blk);
+void ringbuf_cleanup(struct seemp_logk_dev *sdev);
+int ringbuf_count_marked(struct seemp_logk_dev *sdev);
+
+#endif
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 3b6962c52965..3bd090db1b92 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -87,6 +87,8 @@
#include <linux/slab.h>
#include <linux/flex_array.h>
#include <linux/posix-timers.h>
+#include <linux/seemp_api.h>
+#include <linux/seemp_instrumentation.h>
#ifdef CONFIG_HARDWALL
#include <asm/hardwall.h>
#endif
@@ -1074,6 +1076,9 @@ static ssize_t oom_adj_write(struct file *file, const char __user *buf,
goto out;
}
+ seemp_logk_oom_adjust_write(task->pid,
+ task->cred->uid, oom_adj);
+
task_lock(task);
if (!task->mm) {
err = -EINVAL;
@@ -1177,6 +1182,9 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
goto out;
}
+ seemp_logk_oom_adjust_write(task->pid,
+ task->cred->uid, oom_score_adj);
+
task_lock(task);
if (!task->mm) {
err = -EINVAL;
diff --git a/include/linux/seemp_instrumentation.h b/include/linux/seemp_instrumentation.h
new file mode 100644
index 000000000000..bd53d0d22ff2
--- /dev/null
+++ b/include/linux/seemp_instrumentation.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+*/
+#ifndef __SEEMP_LOGK_STUB__
+#define __SEEMP_LOGK_STUB__
+
+#ifdef CONFIG_SEEMP_CORE
+#include <linux/kernel.h>
+
+#define MAX_BUF_SIZE 188
+
+#define SEEMP_LOGK_API_SIZE sizeof(int)
+
+/* Write: api_id + skip encoding byte + params */
+#define SEEMP_LOGK_RECORD(api_id, format, ...) do { \
+ *((int *)(buf - SEEMP_LOGK_API_SIZE)) = api_id; \
+ snprintf(buf + 1, MAX_BUF_SIZE - 1, format, ##__VA_ARGS__); \
+} while (0)
+
+extern void *(*seemp_logk_kernel_begin)(char **buf);
+extern void (*seemp_logk_kernel_end)(void *blck);
+
+static inline void *seemp_setup_buf(char **buf)
+{
+ void *blck;
+
+ if (seemp_logk_kernel_begin && seemp_logk_kernel_end) {
+ blck = seemp_logk_kernel_begin(buf);
+ if (!*buf) {
+ seemp_logk_kernel_end(blck);
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+ return blck;
+}
+/*
+ * NOTE: only sendto is going to be instrumented
+ * since send sys call internally calls sendto
+ * with 2 extra parameters
+ */
+static inline void seemp_logk_sendto(int fd, void __user *buff, size_t len,
+ unsigned flags, struct sockaddr __user *addr, int addr_len)
+{
+ char *buf = NULL;
+ void *blck = NULL;
+
+ /*sets up buf and blck correctly*/
+ blck = seemp_setup_buf(&buf);
+ if (!blck)
+ return;
+
+ /*fill the buf*/
+ SEEMP_LOGK_RECORD(SEEMP_API_kernel__sendto, "len=%u,fd=%d",
+ (unsigned int)len, fd);
+
+ seemp_logk_kernel_end(blck);
+}
+
+/*
+ * NOTE: only recvfrom is going to be instrumented
+ * since recv sys call internally calls recvfrom
+ * with 2 extra parameters
+ */
+static inline void seemp_logk_recvfrom(int fd, void __user *ubuf,
+ size_t size, unsigned flags, struct sockaddr __user *addr,
+ int __user *addr_len)
+{
+ char *buf = NULL;
+ void *blck = NULL;
+
+ /*sets up buf and blck correctly*/
+ blck = seemp_setup_buf(&buf);
+ if (!blck)
+ return;
+
+ /*fill the buf*/
+ SEEMP_LOGK_RECORD(SEEMP_API_kernel__recvfrom, "size=%u,fd=%d",
+ (unsigned int)size, fd);
+
+ seemp_logk_kernel_end(blck);
+}
+
+static inline void seemp_logk_oom_adjust_write(pid_t pid,
+ kuid_t uid, int oom_adj)
+{
+ char *buf = NULL;
+ void *blck = NULL;
+
+ /*sets up buf and blck correctly*/
+ blck = seemp_setup_buf(&buf);
+ if (!blck)
+ return;
+
+ /*fill the buf*/
+ SEEMP_LOGK_RECORD(SEEMP_API_kernel__oom_adjust_write,
+ "app_uid=%d,app_pid=%d,oom_adj=%d",
+ uid.val, pid, oom_adj);
+
+ seemp_logk_kernel_end(blck);
+}
+
+static inline void seemp_logk_oom_score_adj_write(pid_t pid, kuid_t uid,
+ int oom_adj_score)
+{
+ char *buf = NULL;
+ void *blck = NULL;
+
+ /*sets up buf and blck correctly*/
+ blck = seemp_setup_buf(&buf);
+ if (!blck)
+ return;
+
+ /*fill the buf*/
+ snprintf(buf, MAX_BUF_SIZE,
+ "-1|kernel|oom_score_adj_write|app_uid=%d,app_pid=%d,oom_adj=%d|--end",
+ uid.val, pid, oom_adj_score);
+
+ seemp_logk_kernel_end(blck);
+}
+
+#else
+static inline void seemp_logk_sendto(int fd, void __user *buff,
+ size_t len, unsigned flags, struct sockaddr __user *addr,
+ int addr_len)
+{
+}
+
+static inline void seemp_logk_recvfrom
+ (int fd, void __user *ubuf, size_t size,
+ unsigned flags, struct sockaddr __user *addr,
+ int __user *addr_len)
+{
+}
+
+static inline void seemp_logk_oom_adjust_write
+ (pid_t pid, kuid_t uid, int oom_adj)
+{
+}
+
+static inline void seemp_logk_oom_score_adj_write
+ (pid_t pid, kuid_t uid, int oom_adj_score)
+{
+}
+#endif
+#endif
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 70585dfddafe..1e9d279b9536 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -379,6 +379,8 @@ header-y += sctp.h
header-y += sdla.h
header-y += seccomp.h
header-y += securebits.h
+header-y += seemp_api.h
+header-y += seemp_param_id.h
header-y += selinux_netlink.h
header-y += sem.h
header-y += serial_core.h
diff --git a/include/uapi/linux/seemp_api.h b/include/uapi/linux/seemp_api.h
new file mode 100644
index 000000000000..38ed8e3fba12
--- /dev/null
+++ b/include/uapi/linux/seemp_api.h
@@ -0,0 +1,418 @@
+#ifndef _SEEMP_API_H_
+#define _SEEMP_API_H_
+
+#define SEEMP_API_kernel__oom_adjust_write 0
+#define SEEMP_API_kernel__sendto 1
+#define SEEMP_API_kernel__recvfrom 2
+#define SEEMP_API_View__onTouchEvent 3
+#define SEEMP_API_View__onKeyDown 4
+#define SEEMP_API_View__onKeyUp 5
+#define SEEMP_API_View__onTrackBallEvent 6
+#define SEEMP_API_PhoneNumberUtils__getDeviceSoftwareVersion 7
+#define SEEMP_API_apS__get_ANDROID_ID_ 8
+#define SEEMP_API_TelephonyManager__getDeviceId 9
+#define SEEMP_API_TelephonyManager__getSimSerialNumber 10
+#define SEEMP_API_TelephonyManager__getLine1Number 11
+#define SEEMP_API_PhoneNumberUtils__getNumberFromIntent 12
+#define SEEMP_API_Telephony__query 13
+#define SEEMP_API_CallerInfo__getCallerId 14
+#define SEEMP_API_CallerInfo__getCallerInfo 15
+#define SEEMP_API_ContentResolver__query 16
+#define SEEMP_API_AccountManagerService__getPassword 17
+#define SEEMP_API_AccountManagerService__getUserData 18
+#define SEEMP_API_AccountManagerService__addAccount 19
+#define SEEMP_API_AccountManagerService__removeAccount 20
+#define SEEMP_API_AccountManagerService__setPassword 21
+#define SEEMP_API_AccountManagerService__clearPassword 22
+#define SEEMP_API_AccountManagerService__setUserData 23
+#define SEEMP_API_AccountManagerService__editProperties 24
+#define SEEMP_API_AM__getPassword 25
+#define SEEMP_API_AM__getUserData 26
+#define SEEMP_API_AM__addAccountExplicitly 27
+#define SEEMP_API_AM__removeAccount 28
+#define SEEMP_API_AM__setPassword 29
+#define SEEMP_API_AM__clearPassword 30
+#define SEEMP_API_AM__setUserData 31
+#define SEEMP_API_AM__addAccount 32
+#define SEEMP_API_AM__editProperties 33
+#define SEEMP_API_AM__doWork 34
+#define SEEMP_API_Browser__addSearchUrl 35
+#define SEEMP_API_Browser__canClearHistory 36
+#define SEEMP_API_Browser__ClearHistory 37
+#define SEEMP_API_Browser__deleteFromHistory 38
+#define SEEMP_API_Browser__deleteHistoryTimeFrame 39
+#define SEEMP_API_Browser__deleteHistoryWhere 40
+#define SEEMP_API_Browser__getAllBookmarks 41
+#define SEEMP_API_Browser__getAllVisitedUrls 42
+#define SEEMP_API_Browser__getVisitedHistory 43
+#define SEEMP_API_Browser__getVisitedLike 44
+#define SEEMP_API_Browser__requestAllIcons 45
+#define SEEMP_API_Browser__truncateHistory 46
+#define SEEMP_API_Browser__updateVisitedHistory 47
+#define SEEMP_API_Browser__clearSearches 48
+#define SEEMP_API_WebIconDatabase__bulkRequestIconForPageUrl 49
+#define SEEMP_API_ContentResolver__insert 50
+#define SEEMP_API_CalendarContract__insert 51
+#define SEEMP_API_CalendarContract__alarmExists 52
+#define SEEMP_API_CalendarContract__findNextAlarmTime 53
+#define SEEMP_API_CalendarContract__query 54
+#define SEEMP_API_LocationManager___requestLocationUpdates 55
+#define SEEMP_API_LocationManager__addGpsStatusListener 56
+#define SEEMP_API_LocationManager__addNmeaListener 57
+#define SEEMP_API_LocationManager__addProximityAlert 58
+#define SEEMP_API_LocationManager__getBestProvider 59
+#define SEEMP_API_LocationManager__getLastKnownLocation 60
+#define SEEMP_API_LocationManager__getProvider 61
+#define SEEMP_API_LocationManager__getProviders 62
+#define SEEMP_API_LocationManager__isProviderEnabled 63
+#define SEEMP_API_LocationManager__requestLocationUpdates 64
+#define SEEMP_API_LocationManager__sendExtraCommand 65
+#define SEEMP_API_TelephonyManager__getCellLocation 66
+#define SEEMP_API_TelephonyManager__getNeighboringCellInfo 67
+#define SEEMP_API_GeolocationService__registerForLocationUpdates 68
+#define SEEMP_API_GeolocationService__setEnableGps 69
+#define SEEMP_API_GeolocationService__start 70
+#define SEEMP_API_WebChromeClient__onGeolocationPermissionsShowPrompt 71
+#define SEEMP_API_WifiManager__getScanResults 72
+#define SEEMP_API_abB__enable 73
+#define SEEMP_API_abB__disable 74
+#define SEEMP_API_abB__startDiscovery 75
+#define SEEMP_API_abB__listenUsingInsecureRfcommWithServiceRecord 76
+#define SEEMP_API_abB__listenUsingSecureRfcommWithServiceRecord 77
+#define SEEMP_API_abB__getBondedDevices 78
+#define SEEMP_API_abB__getRemoteDevice 79
+#define SEEMP_API_abB__getState 80
+#define SEEMP_API_abB__getProfileConnectionState 81
+#define SEEMP_API_Camera__takePicture 82
+#define SEEMP_API_Camera__setPreviewCallback 83
+#define SEEMP_API_Camera__setPreviewCallbackWithBuffer 84
+#define SEEMP_API_Camera__setOneShotPreviewCallback 85
+#define SEEMP_API_MediaRecorder__start 86
+#define SEEMP_API_MediaRecorder__stop 87
+#define SEEMP_API_AudioRecord__startRecording 88
+#define SEEMP_API_AudioRecord__start 89
+#define SEEMP_API_AudioRecord__stop 90
+#define SEEMP_API_SpeechRecognizer__startListening 91
+#define SEEMP_API_at_SmsManager__sendDataMessage 92
+#define SEEMP_API_at_SmsManager__sendMultipartTextMessage 93
+#define SEEMP_API_at_SmsManager__sendTextMessage 94
+#define SEEMP_API_at_gsm_SmsManager__sendDataMessage 95
+#define SEEMP_API_at_gsm_SmsManager__sendMultipartTextMessage 96
+#define SEEMP_API_at_gsm_SmsManager__sendTextMessage 97
+#define SEEMP_API_at_SmsManager__copyMessageToIcc 98
+#define SEEMP_API_at_SmsManager__deleteMessageFromIcc 99
+#define SEEMP_API_at_SmsManager__updateMessageOnIcc 100
+#define SEEMP_API_at_gsm_SmsManager__copyMessageToSim 101
+#define SEEMP_API_at_gsm_SmsManager__deleteMessageFromSim 102
+#define SEEMP_API_at_gsm_SmsManager__updateMessageOnSim 103
+#define SEEMP_API_at_gsm_SmsManager__getAllMessagesFromSim 104
+#define SEEMP_API_ah_SEL__onAccuracyChanged_ACCELEROMETER_ 105
+#define SEEMP_API_ah_SEL__onSensorChanged_ACCELEROMETER_ 106
+#define SEEMP_API_ah_SensorManager__registerListener 107
+#define SEEMP_API_ASensorEventQueue__enableSensor 108
+#define SEEMP_API_ContactsContract__getLookupUri 109
+#define SEEMP_API_ContactsContract__lookupContact 110
+#define SEEMP_API_ContactsContract__openContactPhotoInputStream 111
+#define SEEMP_API_ContactsContract__getContactLookupUri 112
+#define SEEMP_API_PackageManagerService__installPackage 113
+#define SEEMP_API_TelephonyManager__getSubscriberId 114
+#define SEEMP_API_URL__openConnection 115
+#define SEEMP_API_AM__confirmCredentials 116
+#define SEEMP_API_AM__invalidateAuthToken 117
+#define SEEMP_API_AM__updateCredentials 118
+#define SEEMP_API_AM__checkManageAccountsOrUseCredentialsPermissions 119
+#define SEEMP_API_AM__checkManageAccountsPermission 120
+#define SEEMP_API_AM__peekAuthToken 121
+#define SEEMP_API_AM__setAuthToken 122
+#define SEEMP_API_AM__checkAuthenticateAccountsPermission 123
+#define SEEMP_API_ah_SEL__onAccuracyChanged_ORIENTATION_ 124
+#define SEEMP_API_ah_SEL__onSensorChanged_ORIENTATION_ 125
+#define SEEMP_API_apS__get_ACCELEROMETER_ROTATION_ 126
+#define SEEMP_API_apS__get_USER_ROTATION_ 127
+#define SEEMP_API_apS__get_ADB_ENABLED_ 128
+#define SEEMP_API_apS__get_DEBUG_APP_ 129
+#define SEEMP_API_apS__get_WAIT_FOR_DEBUGGER_ 130
+#define SEEMP_API_apS__get_AIRPLANE_MODE_ON_ 131
+#define SEEMP_API_apS__get_AIRPLANE_MODE_RADIOS_ 132
+#define SEEMP_API_apS__get_ALARM_ALERT_ 133
+#define SEEMP_API_apS__get_NEXT_ALARM_FORMATTED_ 134
+#define SEEMP_API_apS__get_ALWAYS_FINISH_ACTIVITIES_ 135
+#define SEEMP_API_apS__get_LOGGING_ID_ 136
+#define SEEMP_API_apS__get_ANIMATOR_DURATION_SCALE_ 137
+#define SEEMP_API_apS__get_WINDOW_ANIMATION_SCALE_ 138
+#define SEEMP_API_apS__get_FONT_SCALE_ 139
+#define SEEMP_API_apS__get_SCREEN_BRIGHTNESS_ 140
+#define SEEMP_API_apS__get_SCREEN_BRIGHTNESS_MODE_ 141
+#define SEEMP_API_apS__get_SCREEN_BRIGHTNESS_MODE_AUTOMATIC_ 142
+#define SEEMP_API_apS__get_SCREEN_BRIGHTNESS_MODE_MANUAL_ 143
+#define SEEMP_API_apS__get_SCREEN_OFF_TIMEOUT_ 144
+#define SEEMP_API_apS__get_DIM_SCREEN_ 145
+#define SEEMP_API_apS__get_TS_ANIMATION_SCALE_ 146
+#define SEEMP_API_apS__get_STAY_ON_WHILE_PLUGGED_IN_ 147
+#define SEEMP_API_apS__get_WALLPAPER_ACTIVITY_ 148
+#define SEEMP_API_apS__get_SHOW_PROCESSES_ 149
+#define SEEMP_API_apS__get_SHOW_WEB_SUGGESTIONS_ 150
+#define SEEMP_API_apS__get_SHOW_GTALK_SERVICE_STATUS_ 151
+#define SEEMP_API_apS__get_USE_GOOGLE_MAIL_ 152
+#define SEEMP_API_apS__get_AUTO_TIME_ 153
+#define SEEMP_API_apS__get_AUTO_TIME_ZONE_ 154
+#define SEEMP_API_apS__get_DATE_FORMAT_ 155
+#define SEEMP_API_apS__get_TIME_12_24_ 156
+#define SEEMP_API_apS__get_BLUETOOTH_DISCOVERABILITY_ 157
+#define SEEMP_API_apS__get_BLUETOOTH_DISCOVERABILITY_TIMEOUT_ 158
+#define SEEMP_API_apS__get_BLUETOOTH_ON_ 159
+#define SEEMP_API_apS__get_DEVICE_PROVISIONED_ 160
+#define SEEMP_API_apS__get_SETUP_WIZARD_HAS_RUN_ 161
+#define SEEMP_API_apS__get_DTMF_TONE_WHEN_DIALING_ 162
+#define SEEMP_API_apS__get_END_BUTTON_BEHAVIOR_ 163
+#define SEEMP_API_apS__get_RINGTONE_ 164
+#define SEEMP_API_apS__get_MODE_RINGER_ 165
+#define SEEMP_API_apS__get_INSTALL_NON_MARKET_APPS_ 166
+#define SEEMP_API_apS__get_LOCATION_PROVIDERS_ALLOWED_ 167
+#define SEEMP_API_apS__get_LOCK_PATTERN_ENABLED_ 168
+#define SEEMP_API_apS__get_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_ 169
+#define SEEMP_API_apS__get_LOCK_PATTERN_VISIBLE_ 170
+#define SEEMP_API_apS__get_NETWORK_PREFERENCE_ 171
+#define SEEMP_API_apS__get_DATA_ROAMING_ 172
+#define SEEMP_API_apS__get_HTTP_PROXY_ 173
+#define SEEMP_API_apS__get_PARENTAL_CONTROL_ENABLED_ 174
+#define SEEMP_API_apS__get_PARENTAL_CONTROL_LAST_UPDATE_ 175
+#define SEEMP_API_apS__get_PARENTAL_CONTROL_REDIRECT_URL_ 176
+#define SEEMP_API_apS__get_RADIO_BLUETOOTH_ 177
+#define SEEMP_API_apS__get_RADIO_CELL_ 178
+#define SEEMP_API_apS__get_RADIO_NFC_ 179
+#define SEEMP_API_apS__get_RADIO_WIFI_ 180
+#define SEEMP_API_apS__get_SYS_PROP_SETTING_VERSION_ 181
+#define SEEMP_API_apS__get_SETTINGS_CLASSNAME_ 182
+#define SEEMP_API_apS__get_TEXT_AUTO_CAPS_ 183
+#define SEEMP_API_apS__get_TEXT_AUTO_PUNCTUATE_ 184
+#define SEEMP_API_apS__get_TEXT_AUTO_REPLACE_ 185
+#define SEEMP_API_apS__get_TEXT_SHOW_PASSWORD_ 186
+#define SEEMP_API_apS__get_USB_MASS_STORAGE_ENABLED_ 187
+#define SEEMP_API_apS__get_VIBRATE_ON_ 188
+#define SEEMP_API_apS__get_HAPTIC_FEEDBACK_ENABLED_ 189
+#define SEEMP_API_apS__get_VOLUME_ALARM_ 190
+#define SEEMP_API_apS__get_VOLUME_BLUETOOTH_SCO_ 191
+#define SEEMP_API_apS__get_VOLUME_MUSIC_ 192
+#define SEEMP_API_apS__get_VOLUME_NOTIFICATION_ 193
+#define SEEMP_API_apS__get_VOLUME_RING_ 194
+#define SEEMP_API_apS__get_VOLUME_SYSTEM_ 195
+#define SEEMP_API_apS__get_VOLUME_VOICE_ 196
+#define SEEMP_API_apS__get_SOUND_EFFECTS_ENABLED_ 197
+#define SEEMP_API_apS__get_MODE_RINGER_STREAMS_AFFECTED_ 198
+#define SEEMP_API_apS__get_MUTE_STREAMS_AFFECTED_ 199
+#define SEEMP_API_apS__get_NOTIFICATION_SOUND_ 200
+#define SEEMP_API_apS__get_APPEND_FOR_LAST_AUDIBLE_ 201
+#define SEEMP_API_apS__get_WIFI_MAX_DHCP_RETRY_COUNT_ 202
+#define SEEMP_API_apS__get_WIFI_MOBILE_DATA_TS_WAKELOCK_TIMEOUT_MS_ 203
+#define SEEMP_API_apS__get_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_ 204
+#define SEEMP_API_apS__get_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_ 205
+#define SEEMP_API_apS__get_WIFI_NUM_OPEN_NETWORKS_KEPT_ 206
+#define SEEMP_API_apS__get_WIFI_ON_ 207
+#define SEEMP_API_apS__get_WIFI_SLEEP_POLICY_ 208
+#define SEEMP_API_apS__get_WIFI_SLEEP_POLICY_DEFAULT_ 209
+#define SEEMP_API_apS__get_WIFI_SLEEP_POLICY_NEVER_ 210
+#define SEEMP_API_apS__get_WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED_ 211
+#define SEEMP_API_apS__get_WIFI_STATIC_DNS1_ 212
+#define SEEMP_API_apS__get_WIFI_STATIC_DNS2_ 213
+#define SEEMP_API_apS__get_WIFI_STATIC_GATEWAY_ 214
+#define SEEMP_API_apS__get_WIFI_STATIC_IP_ 215
+#define SEEMP_API_apS__get_WIFI_STATIC_NETMASK_ 216
+#define SEEMP_API_apS__get_WIFI_USE_STATIC_IP_ 217
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PR_ 218
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_AP_COUNT_ 219
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_ 220
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_ 221
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_ 222
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_ 223
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_MAX_AP_CHECKS_ 224
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_ON_ 225
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_PING_COUNT_ 226
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_PING_DELAY_MS_ 227
+#define SEEMP_API_apS__get_WIFI_WATCHDOG_PING_TIMEOUT_MS_ 228
+#define SEEMP_API_apS__put_ACCELEROMETER_ROTATION_ 229
+#define SEEMP_API_apS__put_USER_ROTATION_ 230
+#define SEEMP_API_apS__put_ADB_ENABLED_ 231
+#define SEEMP_API_apS__put_DEBUG_APP_ 232
+#define SEEMP_API_apS__put_WAIT_FOR_DEBUGGER_ 233
+#define SEEMP_API_apS__put_AIRPLANE_MODE_ON_ 234
+#define SEEMP_API_apS__put_AIRPLANE_MODE_RADIOS_ 235
+#define SEEMP_API_apS__put_ALARM_ALERT_ 236
+#define SEEMP_API_apS__put_NEXT_ALARM_FORMATTED_ 237
+#define SEEMP_API_apS__put_ALWAYS_FINISH_ACTIVITIES_ 238
+#define SEEMP_API_apS__put_ANDROID_ID_ 239
+#define SEEMP_API_apS__put_LOGGING_ID_ 240
+#define SEEMP_API_apS__put_ANIMATOR_DURATION_SCALE_ 241
+#define SEEMP_API_apS__put_WINDOW_ANIMATION_SCALE_ 242
+#define SEEMP_API_apS__put_FONT_SCALE_ 243
+#define SEEMP_API_apS__put_SCREEN_BRIGHTNESS_ 244
+#define SEEMP_API_apS__put_SCREEN_BRIGHTNESS_MODE_ 245
+#define SEEMP_API_apS__put_SCREEN_BRIGHTNESS_MODE_AUTOMATIC_ 246
+#define SEEMP_API_apS__put_SCREEN_BRIGHTNESS_MODE_MANUAL_ 247
+#define SEEMP_API_apS__put_SCREEN_OFF_TIMEOUT_ 248
+#define SEEMP_API_apS__put_DIM_SCREEN_ 249
+#define SEEMP_API_apS__put_TS_ANIMATION_SCALE_ 250
+#define SEEMP_API_apS__put_STAY_ON_WHILE_PLUGGED_IN_ 251
+#define SEEMP_API_apS__put_WALLPAPER_ACTIVITY_ 252
+#define SEEMP_API_apS__put_SHOW_PROCESSES_ 253
+#define SEEMP_API_apS__put_SHOW_WEB_SUGGESTIONS_ 254
+#define SEEMP_API_apS__put_SHOW_GTALK_SERVICE_STATUS_ 255
+#define SEEMP_API_apS__put_USE_GOOGLE_MAIL_ 256
+#define SEEMP_API_apS__put_AUTO_TIME_ 257
+#define SEEMP_API_apS__put_AUTO_TIME_ZONE_ 258
+#define SEEMP_API_apS__put_DATE_FORMAT_ 259
+#define SEEMP_API_apS__put_TIME_12_24_ 260
+#define SEEMP_API_apS__put_BLUETOOTH_DISCOVERABILITY_ 261
+#define SEEMP_API_apS__put_BLUETOOTH_DISCOVERABILITY_TIMEOUT_ 262
+#define SEEMP_API_apS__put_BLUETOOTH_ON_ 263
+#define SEEMP_API_apS__put_DEVICE_PROVISIONED_ 264
+#define SEEMP_API_apS__put_SETUP_WIZARD_HAS_RUN_ 265
+#define SEEMP_API_apS__put_DTMF_TONE_WHEN_DIALING_ 266
+#define SEEMP_API_apS__put_END_BUTTON_BEHAVIOR_ 267
+#define SEEMP_API_apS__put_RINGTONE_ 268
+#define SEEMP_API_apS__put_MODE_RINGER_ 269
+#define SEEMP_API_apS__put_INSTALL_NON_MARKET_APPS_ 270
+#define SEEMP_API_apS__put_LOCATION_PROVIDERS_ALLOWED_ 271
+#define SEEMP_API_apS__put_LOCK_PATTERN_ENABLED_ 272
+#define SEEMP_API_apS__put_LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED_ 273
+#define SEEMP_API_apS__put_LOCK_PATTERN_VISIBLE_ 274
+#define SEEMP_API_apS__put_NETWORK_PREFERENCE_ 275
+#define SEEMP_API_apS__put_DATA_ROAMING_ 276
+#define SEEMP_API_apS__put_HTTP_PROXY_ 277
+#define SEEMP_API_apS__put_PARENTAL_CONTROL_ENABLED_ 278
+#define SEEMP_API_apS__put_PARENTAL_CONTROL_LAST_UPDATE_ 279
+#define SEEMP_API_apS__put_PARENTAL_CONTROL_REDIRECT_URL_ 280
+#define SEEMP_API_apS__put_RADIO_BLUETOOTH_ 281
+#define SEEMP_API_apS__put_RADIO_CELL_ 282
+#define SEEMP_API_apS__put_RADIO_NFC_ 283
+#define SEEMP_API_apS__put_RADIO_WIFI_ 284
+#define SEEMP_API_apS__put_SYS_PROP_SETTING_VERSION_ 285
+#define SEEMP_API_apS__put_SETTINGS_CLASSNAME_ 286
+#define SEEMP_API_apS__put_TEXT_AUTO_CAPS_ 287
+#define SEEMP_API_apS__put_TEXT_AUTO_PUNCTUATE_ 288
+#define SEEMP_API_apS__put_TEXT_AUTO_REPLACE_ 289
+#define SEEMP_API_apS__put_TEXT_SHOW_PASSWORD_ 290
+#define SEEMP_API_apS__put_USB_MASS_STORAGE_ENABLED_ 291
+#define SEEMP_API_apS__put_VIBRATE_ON_ 292
+#define SEEMP_API_apS__put_HAPTIC_FEEDBACK_ENABLED_ 293
+#define SEEMP_API_apS__put_VOLUME_ALARM_ 294
+#define SEEMP_API_apS__put_VOLUME_BLUETOOTH_SCO_ 295
+#define SEEMP_API_apS__put_VOLUME_MUSIC_ 296
+#define SEEMP_API_apS__put_VOLUME_NOTIFICATION_ 297
+#define SEEMP_API_apS__put_VOLUME_RING_ 298
+#define SEEMP_API_apS__put_VOLUME_SYSTEM_ 299
+#define SEEMP_API_apS__put_VOLUME_VOICE_ 300
+#define SEEMP_API_apS__put_SOUND_EFFECTS_ENABLED_ 301
+#define SEEMP_API_apS__put_MODE_RINGER_STREAMS_AFFECTED_ 302
+#define SEEMP_API_apS__put_MUTE_STREAMS_AFFECTED_ 303
+#define SEEMP_API_apS__put_NOTIFICATION_SOUND_ 304
+#define SEEMP_API_apS__put_APPEND_FOR_LAST_AUDIBLE_ 305
+#define SEEMP_API_apS__put_WIFI_MAX_DHCP_RETRY_COUNT_ 306
+#define SEEMP_API_apS__put_WIFI_MOBILE_DATA_TS_WAKELOCK_TIMEOUT_MS_ 307
+#define SEEMP_API_apS__put_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_ 308
+#define SEEMP_API_apS__put_WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_ 309
+#define SEEMP_API_apS__put_WIFI_NUM_OPEN_NETWORKS_KEPT_ 310
+#define SEEMP_API_apS__put_WIFI_ON_ 311
+#define SEEMP_API_apS__put_WIFI_SLEEP_POLICY_ 312
+#define SEEMP_API_apS__put_WIFI_SLEEP_POLICY_DEFAULT_ 313
+#define SEEMP_API_apS__put_WIFI_SLEEP_POLICY_NEVER_ 314
+#define SEEMP_API_apS__put_WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED_ 315
+#define SEEMP_API_apS__put_WIFI_STATIC_DNS1_ 316
+#define SEEMP_API_apS__put_WIFI_STATIC_DNS2_ 317
+#define SEEMP_API_apS__put_WIFI_STATIC_GATEWAY_ 318
+#define SEEMP_API_apS__put_WIFI_STATIC_IP_ 319
+#define SEEMP_API_apS__put_WIFI_STATIC_NETMASK_ 320
+#define SEEMP_API_apS__put_WIFI_USE_STATIC_IP_ 321
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PR_ 322
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_AP_COUNT_ 323
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS_ 324
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED_ 325
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS_ 326
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT_ 327
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_MAX_AP_CHECKS_ 328
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_ON_ 329
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_PING_COUNT_ 330
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_PING_DELAY_MS_ 331
+#define SEEMP_API_apS__put_WIFI_WATCHDOG_PING_TIMEOUT_MS_ 332
+#define SEEMP_API_Poll__setCumulativeWifiRxMBytes 333
+#define SEEMP_API_Poll__setInstantaneousWifiRxMBytes 334
+#define SEEMP_API_Poll__setCumulativeWifiRxPackets 335
+#define SEEMP_API_Poll__setInstantaneousWifiRxPackets 336
+#define SEEMP_API_Poll__setCumulativeWifiTxMBytes 337
+#define SEEMP_API_Poll__setInstantaneousWifiTxMBytes 338
+#define SEEMP_API_Poll__setCumulativeWifiTxPackets 339
+#define SEEMP_API_Poll__setInstantaneousWifiTxPackets 340
+#define SEEMP_API_Poll__setCumulativeWifiRxTcpMBytes 341
+#define SEEMP_API_Poll__setInstantaneousWifiRxTcpMBytes 342
+#define SEEMP_API_Poll__setCumulativeWifiRxTcpPackets 343
+#define SEEMP_API_Poll__setInstantaneousWifiRxTcpPackets 344
+#define SEEMP_API_Poll__setCumulativeWifiRxUdpMBytes 345
+#define SEEMP_API_Poll__setInstantaneousWifiRxUdpMBytes 346
+#define SEEMP_API_Poll__setCumulativeWifiRxUdpPackets 347
+#define SEEMP_API_Poll__setInstantaneousWifiRxUdpPackets 348
+#define SEEMP_API_Poll__setCumulativeWifiRxOtherMBytes 349
+#define SEEMP_API_Poll__setInstantaneousWifiRxOtherMBytes 350
+#define SEEMP_API_Poll__setCumulativeWifiRxOtherPackets 351
+#define SEEMP_API_Poll__setInstantaneousWifiRxOtherPackets 352
+#define SEEMP_API_Poll__setCumulativeWifiTxTcpMBytes 353
+#define SEEMP_API_Poll__setInstantaneousWifiTxTcpMBytes 354
+#define SEEMP_API_Poll__setCumulativeWifiTxTcpPackets 355
+#define SEEMP_API_Poll__setInstantaneousWifiTxTcpPackets 356
+#define SEEMP_API_Poll__setCumulativeWifiTxUdpMBytes 357
+#define SEEMP_API_Poll__setInstantaneousWifiTxUdpMBytes 358
+#define SEEMP_API_Poll__setCumulativeWifiTxUdpPackets 359
+#define SEEMP_API_Poll__setInstantaneousWifiTxUdpPackets 360
+#define SEEMP_API_Poll__setCumulativeWifiTxOtherMBytes 361
+#define SEEMP_API_Poll__setInstantaneousWifiTxOtherMBytes 362
+#define SEEMP_API_Poll__setCumulativeWifiTxOtherPackets 363
+#define SEEMP_API_Poll__setInstantaneousWifiTxOtherPackets 364
+#define SEEMP_API_Poll__setCumulativeMobileRxMBytes 365
+#define SEEMP_API_Poll__setInstantaneousMobileRxMBytes 366
+#define SEEMP_API_Poll__setCumulativeMobileRxPackets 367
+#define SEEMP_API_Poll__setInstantaneousMobileRxPackets 368
+#define SEEMP_API_Poll__setCumulativeMobileTxMBytes 369
+#define SEEMP_API_Poll__setInstantaneousMobileTxMBytes 370
+#define SEEMP_API_Poll__setCumulativeMobileTxPackets 371
+#define SEEMP_API_Poll__setInstantaneousMobileTxPackets 372
+#define SEEMP_API_Poll__setCumulativeMobileRxTcpMBytes 373
+#define SEEMP_API_Poll__setInstantaneousMobileRxTcpMBytes 374
+#define SEEMP_API_Poll__setCumulativeMobileRxTcpPackets 375
+#define SEEMP_API_Poll__setInstantaneousMobileRxTcpPackets 376
+#define SEEMP_API_Poll__setCumulativeMobileRxUdpMBytes 377
+#define SEEMP_API_Poll__setInstantaneousMobileRxUdpMBytes 378
+#define SEEMP_API_Poll__setCumulativeMobileRxUdpPackets 379
+#define SEEMP_API_Poll__setInstantaneousMobileRxUdpPackets 380
+#define SEEMP_API_Poll__setCumulativeMobileRxOtherMBytes 381
+#define SEEMP_API_Poll__setInstantaneousMobileRxOtherMBytes 382
+#define SEEMP_API_Poll__setCumulativeMobileRxOtherPackets 383
+#define SEEMP_API_Poll__setInstantaneousMobileRxOtherPackets 384
+#define SEEMP_API_Poll__setCumulativeMobileTxTcpMBytes 385
+#define SEEMP_API_Poll__setInstantaneousMobileTxTcpMBytes 386
+#define SEEMP_API_Poll__setCumulativeMobileTxTcpPackets 387
+#define SEEMP_API_Poll__setInstantaneousMobileTxTcpPackets 388
+#define SEEMP_API_Poll__setCumulativeMobileTxUdpMBytes 389
+#define SEEMP_API_Poll__setInstantaneousMobileTxUdpMBytes 390
+#define SEEMP_API_Poll__setCumulativeMobileTxUdpPackets 391
+#define SEEMP_API_Poll__setInstantaneousMobileTxUdpPackets 392
+#define SEEMP_API_Poll__setCumulativeMobileTxOtherMBytes 393
+#define SEEMP_API_Poll__setInstantaneousMobileTxOtherMBytes 394
+#define SEEMP_API_Poll__setCumulativeMobileTxOtherPackets 395
+#define SEEMP_API_Poll__setInstantaneousMobileTxOtherPackets 396
+#define SEEMP_API_Poll__setNumSockets 397
+#define SEEMP_API_Poll__setNumTcpStateListen 398
+#define SEEMP_API_Poll__setNumTcpStateEstablished 399
+#define SEEMP_API_Poll__setNumLocalIp 400
+#define SEEMP_API_Poll__setNumLocalPort 401
+#define SEEMP_API_Poll__setNumRemoteIp 402
+#define SEEMP_API_Poll__setNumRemotePort 403
+#define SEEMP_API_Poll__setNumRemoteTuple 404
+#define SEEMP_API_Poll__setNumInode 405
+#define SEEMP_API_Instrumentation__startActivitySync 406
+#define SEEMP_API_Instrumentation__execStartActivity 407
+#define SEEMP_API_Instrumentation__execStartActivitiesAsUser 408
+#define SEEMP_API_Instrumentation__execStartActivityAsCaller 409
+#define SEEMP_API_Instrumentation__execStartActivityFromAppTask 410
+#define SEEMP_API_ah_SystemSensorManager__registerListenerImpl 411
+#define SEEMP_API_ah_SystemSensorManager__unregisterListenerImpl 412
+
+#endif /* _SEEMP_API_H_ */
diff --git a/include/uapi/linux/seemp_param_id.h b/include/uapi/linux/seemp_param_id.h
new file mode 100644
index 000000000000..d4f1894dadd1
--- /dev/null
+++ b/include/uapi/linux/seemp_param_id.h
@@ -0,0 +1,70 @@
+#ifndef _PARAM_ID_H_
+#define _PARAM_ID_H_
+
+#define PARAM_ID_LEN 0
+#define PARAM_ID_OOM_ADJ 1
+#define PARAM_ID_APP_PID 2
+#define PARAM_ID_VALUE 3
+#define PARAM_ID_RATE 4
+#define PARAM_ID_SENSOR 5
+#define PARAM_ID_SIZE 6
+#define PARAM_ID_FD 7
+#define NUM_PARAM_IDS 8
+
+#ifndef PROVIDE_PARAM_ID
+int param_id_index(const char *param, const char *end);
+const char *get_param_id_name(int id);
+#else
+int param_id_index(const char *param, const char *end)
+{
+ int id = -1;
+ int len = ((end != NULL) ? (end - param) : (int)strlen(param));
+
+ /**/ if ((len == 3) && !memcmp(param, "len", 3))
+ id = 0;
+ else if ((len == 7) && !memcmp(param, "oom_adj", 7))
+ id = 1;
+ else if ((len == 7) && !memcmp(param, "app_pid", 7))
+ id = 2;
+ else if ((len == 5) && !memcmp(param, "value", 5))
+ id = 3;
+ else if ((len == 4) && !memcmp(param, "rate", 4))
+ id = 4;
+ else if ((len == 6) && !memcmp(param, "sensor", 6))
+ id = 5;
+ else if ((len == 4) && !memcmp(param, "size", 4))
+ id = 6;
+ else if ((len == 2) && !memcmp(param, "fd", 2))
+ id = 7;
+
+ return id;
+}
+
+const char *get_param_id_name(int id)
+{
+ const char *name = "?";
+
+ switch (id) {
+ case 0:
+ name = "len"; break;
+ case 1:
+ name = "oom_adj"; break;
+ case 2:
+ name = "app_pid"; break;
+ case 3:
+ name = "value"; break;
+ case 4:
+ name = "rate"; break;
+ case 5:
+ name = "sensor"; break;
+ case 6:
+ name = "size"; break;
+ case 7:
+ name = "fd"; break;
+ }
+
+ return name;
+}
+#endif /* PROVIDE_PARAM_ID */
+
+#endif /* _PARAM_ID_H_ */
diff --git a/net/socket.c b/net/socket.c
index cdf6b9621f25..01866f7acad2 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -89,6 +89,8 @@
#include <linux/magic.h>
#include <linux/slab.h>
#include <linux/xattr.h>
+#include <linux/seemp_api.h>
+#include <linux/seemp_instrumentation.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -1658,6 +1660,8 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
struct iovec iov;
int fput_needed;
+ seemp_logk_sendto(fd, buff, len, flags, addr, addr_len);
+
err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
if (unlikely(err))
return err;
@@ -1714,6 +1718,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
int err, err2;
int fput_needed;
+ seemp_logk_recvfrom(fd, ubuf, size, flags, addr, addr_len);
+
err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter);
if (unlikely(err))
return err;