1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #define _GNU_SOURCE
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdint.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <sys/mman.h>
24 #include <sys/ioctl.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <sys/wait.h>
28
29 #define DEVICE "/dev/seemplog"
30 #define SZ_1M 0x100000
31 #define FOUR_MB (4 * SZ_1M)
32
33 #define BLK_SIZE 256
34 #define BLK_HDR_SIZE 64
35 #define TS_SIZE 20
36 #define BLK_MAX_MSG_SZ (BLK_SIZE - BLK_HDR_SIZE)
37
38 #define TASK_COMM_LEN 16
39
40 #define MAGIC 'z'
41
42 #define SEEMP_CMD_RESERVE_RDBLKS _IOR(MAGIC, 1, int)
43 #define SEEMP_CMD_RELEASE_RDBLKS _IO(MAGIC, 2)
44 #define SEEMP_CMD_GET_RINGSZ _IOR(MAGIC, 3, int)
45 #define SEEMP_CMD_GET_BLKSZ _IOR(MAGIC, 4, int)
46 #define SEEMP_CMD_SET_MASK _IO(MAGIC, 5)
47 #define SEEMP_CMD_SET_MAPPING _IO(MAGIC, 6)
48 #define SEEMP_CMD_CHECK_FILTER _IOR(MAGIC, 7, int)
49 #define SEEMP_CMD_DEBUG_START _IOR(MAGIC, 8, int)
50 #define SEEMP_CMD_DEBUG_STOP _IOR(MAGIC, 9, int)
51
52 struct read_range {
53 int start_idx;
54 int num;
55 };
56
57 struct blk_payload {
58 uint32_t api_id;
59 char msg[BLK_MAX_MSG_SZ];
60 } __attribute__((packed));
61
62 struct seemp_logk_blk {
63 uint8_t status;
64 uint16_t len;
65 uint8_t version;
66 int32_t pid;
67 int32_t uid;
68 int32_t tid;
69 int32_t sec;
70 int32_t nsec;
71 char ts[TS_SIZE];
72 char appname[TASK_COMM_LEN];
73 struct blk_payload payload;
74 } __attribute__((packed));
75
dump_blk_headers(char * ptr)76 void dump_blk_headers(char *ptr) {
77 int i;
78 struct seemp_logk_blk *temp;
79
80 for (i = 0; i < (FOUR_MB / 256); i++) {
81 temp = (struct seemp_logk_blk *)ptr;
82
83 ptr += 256;
84 }
85 }
86
print_maps(int time)87 void print_maps(int time) {
88 char cmd[] = "/proc/%d/maps";
89 char cmd2[sizeof("/proc/-2147483648/maps")];
90 FILE *fp;
91 size_t nread;
92 char buf[1024];
93
94 snprintf(cmd2, sizeof(cmd2)-1, cmd, getpid());
95
96 fp = fopen(cmd2, "r");
97 if (fp == NULL) {
98 exit(-1);
99 }
100
101 while ((nread = fread(buf, 1, sizeof(buf), fp)) > 0)
102 fwrite(buf, 1, nread, stdout);
103
104 fclose(fp);
105 sleep(time);
106 }
107
reserve_rdblks(int fd)108 void reserve_rdblks(int fd) {
109 struct read_range rrange;
110 ioctl(fd, SEEMP_CMD_RESERVE_RDBLKS, &rrange);
111 }
112
get_ringsz(int fd)113 unsigned int get_ringsz(int fd) {
114 unsigned int ringsz;
115 ioctl(fd, SEEMP_CMD_GET_RINGSZ, &ringsz);
116 return ringsz;
117 }
118
get_blksz(int fd)119 unsigned int get_blksz(int fd) {
120 unsigned int blksz;
121 ioctl(fd, SEEMP_CMD_GET_BLKSZ, &blksz);
122 return blksz;
123 }
124
write_to_file(char * ptr)125 void write_to_file(char *ptr) {
126 FILE *dumpfp = fopen("/data/local/tmp/dump", "wb");
127 int i;
128
129 if (dumpfp == NULL) {
130 exit(-1);
131 }
132
133 fwrite(ptr, 1, FOUR_MB, dumpfp);
134 fclose(dumpfp);
135 }
136
write_to_dev(int fd)137 void write_to_dev(int fd) {
138 char ts[] = "IIIIIIIIIIIIIIIIIIII";
139 char appname[] = "JJJJJJJJJJJJJJJJ";
140 char msg[] = "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL";
141
142 struct seemp_logk_blk block;
143
144 block.status = 0xff;
145 block.len = 0x4242;
146 block.version = 'C';
147 block.pid = 0x44444444;
148 block.uid = 0x45454545;
149 block.tid = 0x46464646;
150 block.sec = 0x47474747;
151 block.nsec = 0x48484848;
152 strcpy(block.ts, ts);
153 strcpy(block.appname, appname);
154 block.payload.api_id = 0x51515151;
155 strcpy(block.payload.msg, msg);
156 }
157
do_mapping(void ** ptr,int fd)158 void do_mapping(void **ptr, int fd) {
159 *ptr = mmap(NULL,
160 FOUR_MB,
161 0x7,
162 MAP_SHARED,
163 fd,
164 0);
165 if (*ptr == MAP_FAILED) {
166 close(fd);
167 exit(-1);
168 }
169 }
170
spam_mapped_region(char * ptr,int offset,int size)171 void spam_mapped_region(char *ptr, int offset, int size) {
172 int i;
173 for (i = offset; i < size; i++)
174 *(ptr + i) = 'A';
175 }
176
start_printk(int fd)177 void start_printk(int fd) {
178 ioctl(fd, SEEMP_CMD_DEBUG_START, NULL);
179 }
180
stop_printk(int fd)181 void stop_printk(int fd) {
182 ioctl(fd, SEEMP_CMD_DEBUG_STOP, NULL);
183 }
184
main()185 int main() {
186 int fd;
187 void *ptr;
188 int i;
189
190 fd = open(DEVICE, O_RDWR);
191 if (fd == -1) {
192 exit(-1);
193 }
194
195 start_printk(fd);
196
197 do_mapping(&ptr, fd);
198
199 for (i = 0; i < (FOUR_MB / 256); i++)
200 write_to_dev(fd);
201
202 dump_blk_headers(ptr);
203 print_maps(5);
204
205 write_to_file(ptr);
206
207 stop_printk(fd);
208
209 close(fd);
210 munmap(ptr, FOUR_MB);
211
212 return 0;
213 }
214
215