1 /*
2  * Copyright 2021, 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 
17 #pragma once
18 
19 #include <stdbool.h>
20 #include <stdint.h>
21 #include <trusty/uuid.h>
22 
23 /**
24  * DOC: Metrics
25  *
26  * Metrics interface provides a way for Android to get Trusty metrics data.
27  *
28  * Currently, only "push" model is supported. Clients are expected to connect to
29  * metrics service, listen for events, e.g. app crash events, and respond to
30  * every event with a &struct metrics_req.
31  *
32  * Communication is driven by metrics service, i.e. requests/responses are all
33  * sent from/to metrics service.
34  *
35  * Note that the type of the event is not known to the client ahead of time.
36  *
37  * This interface used to be exposed on the METRICS_PORT for Android to listen
38  * to the Trusty metrics event.
39  * However the METRICS_PORT is deprecated and replaced by ISTATS_SETTER_PORT
40  * from `trusty/user/base/interface/stats_setter` allowing asynchronous callback
41  * to a Normal-World IStats.aidl service (also see IStatsSetter.aidl under
42  * `system/core/trusty/stats/aidl/android/trusty/stats/setter`).
43  *
44  * This Metrics interface still is used on the METRICS_CONSUMER_PORT, allowing
45  * the Trusty kernel errors to be reported to the metrics user-space service,
46  * then relayed via the IStats callback.
47  */
48 
49 #define METRICS_PORT "com.android.trusty.metrics"
50 
51 #define HASH_SIZE_BYTES 64
52 
53 /**
54  * enum metrics_cmd - command identifiers for metrics interface
55  * @METRICS_CMD_RESP_BIT:             message is a response
56  * @METRICS_CMD_REQ_SHIFT:            number of bits used by @METRICS_CMD_RESP_BIT
57  * @METRICS_CMD_REPORT_EVENT_DROP:    report gaps in the event stream
58  * @METRICS_CMD_REPORT_CRASH:         report an app crash event
59  * @METRICS_CMD_REPORT_EXIT:          report an app exit
60  * @METRICS_CMD_REPORT_STORAGE_ERROR: report trusty storage error
61  */
62 enum metrics_cmd {
63     METRICS_CMD_RESP_BIT = 1,
64     METRICS_CMD_REQ_SHIFT = 1,
65 
66     METRICS_CMD_REPORT_EVENT_DROP = (1 << METRICS_CMD_REQ_SHIFT),
67     METRICS_CMD_REPORT_CRASH = (2 << METRICS_CMD_REQ_SHIFT),
68     METRICS_CMD_REPORT_EXIT = (3 << METRICS_CMD_REQ_SHIFT),
69     METRICS_CMD_REPORT_STORAGE_ERROR = (4 << METRICS_CMD_REQ_SHIFT),
70 };
71 
72 /**
73  * enum metrics_error - metrics error codes
74  * @METRICS_NO_ERROR:        no error
75  * @METRICS_ERR_UNKNOWN_CMD: unknown or not implemented command
76  */
77 enum metrics_error {
78     METRICS_NO_ERROR = 0,
79     METRICS_ERR_UNKNOWN_CMD = 1,
80 };
81 
82 /**
83  * struct metrics_req - common structure for metrics requests
84  * @cmd:      command identifier - one of &enum metrics_cmd
85  * @reserved: must be 0
86  */
87 struct metrics_req {
88     uint32_t cmd;
89     uint32_t reserved;
90 } __attribute__((__packed__));
91 
92 /**
93  * struct metrics_resp - common structure for metrics responses
94  * @cmd: command identifier - %METRICS_CMD_RESP_BIT or'ed with a cmd in
95  *                            one of &enum metrics_cmd
96  * @status: response status, one of &enum metrics_error
97  */
98 struct metrics_resp {
99     uint32_t cmd;
100     uint32_t status;
101 } __attribute__((__packed__));
102 
103 /**
104  * struct metrics_report_exit_req - arguments of %METRICS_CMD_REPORT_EXIT
105  *                                   requests
106  * @app_id: app_id in the form UUID in ascii format
107  *          "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
108  * @exit_code: architecture-specific exit code
109  */
110 struct metrics_report_exit_req {
111     char app_id[UUID_STR_SIZE];
112     uint32_t exit_code;
113 } __attribute__((__packed__));
114 
115 /**
116  * struct metrics_report_crash_req - arguments of %METRICS_CMD_REPORT_CRASH
117  *                                   requests
118  * @app_id: app_id in the form UUID in ascii format
119  *          "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
120  * @crash_reason: architecture-specific code representing the reason for the
121  *                crash
122  * @far: Fault Address Register corresponding to the crash. It is set to 0 and
123  *       not always revealed
124  * @far_hash: Fault Address Register obfuscated, always revealed
125  * @elr: Exception Link Register corresponding to the crash. It is set to 0 and
126  *       not always revealed
127  * @elr_hash: Exception Link Register obfuscated, always revealed
128  * @is_hash: Boolean value indicating whether far and elr have been ob
129  */
130 struct metrics_report_crash_req {
131     char app_id[UUID_STR_SIZE];
132     uint32_t crash_reason;
133     uint64_t far;
134     uint8_t far_hash[HASH_SIZE_BYTES];
135     uint64_t elr;
136     uint8_t elr_hash[HASH_SIZE_BYTES];
137     bool is_hash;
138 } __attribute__((__packed__));
139 
140 #define METRICS_MAX_APP_ID_LEN 256
141 
142 #define METRICS_MAX_MSG_SIZE 1024
143