Yida Wang | 0bf43bd | 2017-03-22 18:16:31 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved. |
| 3 | * |
| 4 | * This program is free software; you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License version 2 and |
| 6 | * only version 2 as published by the Free Software Foundation. |
| 7 | * |
| 8 | * This program is distributed in the hope that it will be useful, |
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | * GNU General Public License for more details. |
| 12 | */ |
| 13 | |
| 14 | #ifndef __SEEMP_LOGK_H__ |
| 15 | #define __SEEMP_LOGK_H__ |
| 16 | |
| 17 | #define OBSERVER_VERSION 0x01 |
| 18 | |
| 19 | #include <linux/module.h> |
| 20 | #include <linux/kernel.h> |
| 21 | #include <linux/ioctl.h> |
| 22 | #include <linux/cdev.h> |
| 23 | #include <linux/device.h> |
| 24 | #include <linux/poll.h> |
| 25 | #include <linux/wait.h> |
| 26 | #include <linux/fs.h> |
| 27 | #include <linux/slab.h> |
| 28 | #include <linux/errno.h> |
| 29 | #include <linux/err.h> |
| 30 | #include <linux/mm.h> |
| 31 | #include <linux/sched.h> |
| 32 | #include <linux/mutex.h> |
| 33 | #include <linux/vmalloc.h> |
| 34 | #include <asm/ioctls.h> |
| 35 | |
| 36 | #define seemp_LOGK_NUM_DEVS 1 |
| 37 | #define seemp_LOGK_DEV_NAME "seemplog" |
| 38 | |
| 39 | /* |
| 40 | * The logcat driver on Android uses four 256k ring buffers |
| 41 | * here, we use two ring buffers of the same size. |
| 42 | * we think this is reasonable |
| 43 | */ |
| 44 | #define FULL_BUF_SIZE (64 * 1024 * 1024) |
| 45 | #define HALF_BUF_SIZE (32 * 1024 * 1024) |
| 46 | #define FULL_BLOCKS (8 * 1024) |
| 47 | #define HALF_BLOCKS (4 * 1024) |
| 48 | |
| 49 | #define READER_NOT_READY 0 |
| 50 | #define READER_READY 1 |
| 51 | |
| 52 | #define MAGIC 'z' |
| 53 | |
| 54 | #define SEEMP_CMD_RESERVE_RDBLKS _IOR(MAGIC, 1, int) |
| 55 | #define SEEMP_CMD_RELEASE_RDBLKS _IO(MAGIC, 2) |
| 56 | #define SEEMP_CMD_GET_RINGSZ _IOR(MAGIC, 3, int) |
| 57 | #define SEEMP_CMD_GET_BLKSZ _IOR(MAGIC, 4, int) |
| 58 | #define SEEMP_CMD_SET_MASK _IO(MAGIC, 5) |
| 59 | #define SEEMP_CMD_SET_MAPPING _IO(MAGIC, 6) |
| 60 | #define SEEMP_CMD_CHECK_FILTER _IOR(MAGIC, 7, int) |
| 61 | |
| 62 | struct read_range { |
| 63 | int start_idx; |
| 64 | int num; |
| 65 | }; |
| 66 | |
| 67 | struct seemp_logk_dev { |
| 68 | unsigned int major; |
| 69 | unsigned int minor; |
| 70 | |
| 71 | struct cdev cdev; |
| 72 | struct class *cls; |
| 73 | /*the full buffer*/ |
| 74 | struct seemp_logk_blk *ring; |
| 75 | /*an array of blks*/ |
| 76 | unsigned int ring_sz; |
| 77 | unsigned int blk_sz; |
| 78 | |
| 79 | int num_tot_blks; |
| 80 | |
| 81 | int num_write_avail_blks; |
| 82 | int num_write_in_prog_blks; |
| 83 | |
| 84 | int num_read_avail_blks; |
| 85 | int num_read_in_prog_blks; |
| 86 | |
| 87 | int num_writers; |
| 88 | |
| 89 | /* |
| 90 | * there is always one reader |
| 91 | * which is the observer daemon |
| 92 | * therefore there is no necessity |
| 93 | * for num_readers variable |
| 94 | */ |
| 95 | |
| 96 | /* |
| 97 | * read_idx and write_idx loop through from zero to ring_sz, |
| 98 | * and then back to zero in a circle, as they advance |
| 99 | * based on the reader's and writers' accesses |
| 100 | */ |
| 101 | int read_idx; |
| 102 | |
| 103 | int write_idx; |
| 104 | |
| 105 | /* |
| 106 | * wait queues |
| 107 | * readers_wq: implement wait for readers |
| 108 | * writers_wq: implement wait for writers |
| 109 | * |
| 110 | * whether writers are blocked or not is driven by the policy: |
| 111 | * case 1: (best_effort_logging == 1) |
| 112 | * writers are not blocked, and |
| 113 | * when there is no mem in the ring to store logs, |
| 114 | * the logs are simply dropped. |
| 115 | * case 2: (best_effort_logging == 0) |
| 116 | * when there is no mem in the ring to store logs, |
| 117 | * the process gets blocked until there is space. |
| 118 | */ |
| 119 | wait_queue_head_t readers_wq; |
| 120 | wait_queue_head_t writers_wq; |
| 121 | |
| 122 | /* |
| 123 | * protects everything in the device |
| 124 | * including ring buffer and all the num_ variables |
| 125 | * spinlock_t lock; |
| 126 | */ |
| 127 | struct mutex lock; |
| 128 | }; |
| 129 | |
| 130 | #define BLK_SIZE 256 |
| 131 | #define BLK_HDR_SIZE 64 |
| 132 | #define TS_SIZE 20 |
| 133 | #define BLK_MAX_MSG_SZ (BLK_SIZE - BLK_HDR_SIZE) |
| 134 | |
| 135 | struct blk_payload { |
| 136 | __u32 api_id; /* event API id */ |
| 137 | char msg[BLK_MAX_MSG_SZ]; /* event parameters */ |
| 138 | } __packed; |
| 139 | |
| 140 | struct seemp_logk_blk { |
| 141 | __u8 status; /* bits: 0->valid/invalid; 1-7: unused as of now! */ |
| 142 | __u16 len; /* length of the payload */ |
| 143 | __u8 version; /* version number */ |
| 144 | __s32 pid; /* generating process's pid */ |
| 145 | __s32 uid; /* generating process's uid - app specific */ |
| 146 | __s32 tid; /* generating process's tid */ |
| 147 | __s32 sec; /* seconds since Epoch */ |
| 148 | __s32 nsec; /* nanoseconds */ |
| 149 | char ts[TS_SIZE]; /* Time Stamp */ |
| 150 | char appname[TASK_COMM_LEN]; |
| 151 | struct blk_payload payload; |
| 152 | } __packed; |
| 153 | |
| 154 | |
| 155 | extern unsigned int kmalloc_flag; |
| 156 | |
| 157 | struct seemp_source_mask { |
| 158 | __u32 hash; |
| 159 | bool isOn; |
| 160 | }; |
Yida Wang | 943c3b4 | 2017-06-23 17:10:13 -0400 | [diff] [blame] | 161 | |
| 162 | /* report region header */ |
| 163 | struct el2_report_header_t { |
| 164 | __u64 report_version; /* Version of the EL2 report */ |
| 165 | __u64 mp_catalog_version; |
| 166 | /* Version of MP catalogue used for kernel protection */ |
Yida Wang | 414df74 | 2017-07-19 16:58:23 -0400 | [diff] [blame] | 167 | __u64 num_incidents; /* Number of Incidents Observed by EL2 */ |
Yida Wang | 943c3b4 | 2017-06-23 17:10:13 -0400 | [diff] [blame] | 168 | __u8 protection_enabled; /* Kernel Assets protected by EL2 */ |
| 169 | __u8 pad1; |
| 170 | __u8 pad2; |
| 171 | __u8 pad3; |
| 172 | __u32 pad4; |
Yida Wang | 943c3b4 | 2017-06-23 17:10:13 -0400 | [diff] [blame] | 173 | }; |
| 174 | |
| 175 | /* individual report */ |
| 176 | struct el2_report_data_t { |
Yida Wang | 414df74 | 2017-07-19 16:58:23 -0400 | [diff] [blame] | 177 | __u64 sequence_number; /* Sequence number of the report */ |
| 178 | __u64 actor; /* Actor that caused the Incident. */ |
Yida Wang | 943c3b4 | 2017-06-23 17:10:13 -0400 | [diff] [blame] | 179 | __u8 report_valid; |
| 180 | /* Flag to indicate whether report instance is valid */ |
| 181 | __u8 report_type; /* Report Type */ |
Yida Wang | 414df74 | 2017-07-19 16:58:23 -0400 | [diff] [blame] | 182 | __u8 asset_category; /* Asset Category */ |
| 183 | __u8 response; /* Response From EL2 */ |
Yida Wang | 943c3b4 | 2017-06-23 17:10:13 -0400 | [diff] [blame] | 184 | }; |
| 185 | |
Yida Wang | 0bf43bd | 2017-03-22 18:16:31 -0400 | [diff] [blame] | 186 | #endif |