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