• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #include <stdio.h>
26 #include <string.h>
27 #include <sysexits.h>
28 
29 #include <android-base/properties.h>
30 
31 #include <libavb_user/libavb_user.h>
32 
33 namespace {
34 
35 /* Prints program usage to |where|. */
usage(FILE * where,int,char * argv[])36 void usage(FILE* where, int /* argc */, char* argv[]) {
37   fprintf(where,
38           "%s - command-line tool for AVB.\n"
39           "\n"
40           "Usage:\n"
41           "  %s COMMAND\n"
42           "\n"
43           "Commands:\n"
44           "  %s get-verity           - Prints whether verity is enabled in "
45           "current slot.\n"
46           "  %s disable-verity       - Disable verity in current slot.\n"
47           "  %s enable-verity        - Enable verity in current slot.\n"
48           "  %s get-verification     - Prints whether verification is enabled "
49           "in current slot.\n"
50           "  %s disable-verification - Disable verification in current slot.\n"
51           "  %s enable-verification  - Enable verification in current slot.\n",
52           argv[0],
53           argv[0],
54           argv[0],
55           argv[0],
56           argv[0],
57           argv[0],
58           argv[0],
59           argv[0]);
60 }
61 
62 /* Function to enable and disable verification. The |ops| parameter
63  * should be an |AvbOps| from libavb_user.
64  */
do_set_verification(AvbOps * ops,const std::string & ab_suffix,bool enable_verification)65 int do_set_verification(AvbOps* ops,
66                         const std::string& ab_suffix,
67                         bool enable_verification) {
68   bool verification_enabled;
69 
70   if (!avb_user_verification_get(
71           ops, ab_suffix.c_str(), &verification_enabled)) {
72     fprintf(stderr, "Error getting whether verification is enabled.\n");
73     return EX_SOFTWARE;
74   }
75 
76   if ((verification_enabled && enable_verification) ||
77       (!verification_enabled && !enable_verification)) {
78     fprintf(stdout,
79             "verification is already %s",
80             verification_enabled ? "enabled" : "disabled");
81     if (ab_suffix != "") {
82       fprintf(stdout, " on slot with suffix %s", ab_suffix.c_str());
83     }
84     fprintf(stdout, ".\n");
85     return EX_OK;
86   }
87 
88   if (!avb_user_verification_set(ops, ab_suffix.c_str(), enable_verification)) {
89     fprintf(stderr, "Error setting verification.\n");
90     return EX_SOFTWARE;
91   }
92 
93   fprintf(stdout,
94           "Successfully %s verification",
95           enable_verification ? "enabled" : "disabled");
96   if (ab_suffix != "") {
97     fprintf(stdout, " on slot with suffix %s", ab_suffix.c_str());
98   }
99   fprintf(stdout, ". Reboot the device for changes to take effect.\n");
100 
101   return EX_OK;
102 }
103 
104 /* Function to query if verification. The |ops| parameter should be an
105  * |AvbOps| from libavb_user.
106  */
do_get_verification(AvbOps * ops,const std::string & ab_suffix)107 int do_get_verification(AvbOps* ops, const std::string& ab_suffix) {
108   bool verification_enabled;
109 
110   if (!avb_user_verification_get(
111           ops, ab_suffix.c_str(), &verification_enabled)) {
112     fprintf(stderr, "Error getting whether verification is enabled.\n");
113     return EX_SOFTWARE;
114   }
115 
116   fprintf(stdout,
117           "verification is %s",
118           verification_enabled ? "enabled" : "disabled");
119   if (ab_suffix != "") {
120     fprintf(stdout, " on slot with suffix %s", ab_suffix.c_str());
121   }
122   fprintf(stdout, ".\n");
123 
124   return EX_OK;
125 }
126 
127 /* Function to enable and disable dm-verity. The |ops| parameter
128  * should be an |AvbOps| from libavb_user.
129  */
do_set_verity(AvbOps * ops,const std::string & ab_suffix,bool enable_verity)130 int do_set_verity(AvbOps* ops,
131                   const std::string& ab_suffix,
132                   bool enable_verity) {
133   bool verity_enabled;
134 
135   if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) {
136     fprintf(stderr, "Error getting whether verity is enabled.\n");
137     return EX_SOFTWARE;
138   }
139 
140   if ((verity_enabled && enable_verity) ||
141       (!verity_enabled && !enable_verity)) {
142     fprintf(stdout,
143             "verity is already %s",
144             verity_enabled ? "enabled" : "disabled");
145     if (ab_suffix != "") {
146       fprintf(stdout, " on slot with suffix %s", ab_suffix.c_str());
147     }
148     fprintf(stdout, ".\n");
149     return EX_OK;
150   }
151 
152   if (!avb_user_verity_set(ops, ab_suffix.c_str(), enable_verity)) {
153     fprintf(stderr, "Error setting verity.\n");
154     return EX_SOFTWARE;
155   }
156 
157   fprintf(
158       stdout, "Successfully %s verity", enable_verity ? "enabled" : "disabled");
159   if (ab_suffix != "") {
160     fprintf(stdout, " on slot with suffix %s", ab_suffix.c_str());
161   }
162   fprintf(stdout, ". Reboot the device for changes to take effect.\n");
163 
164   return EX_OK;
165 }
166 
167 /* Function to query if dm-verity is enabled. The |ops| parameter
168  * should be an |AvbOps| from libavb_user.
169  */
do_get_verity(AvbOps * ops,const std::string & ab_suffix)170 int do_get_verity(AvbOps* ops, const std::string& ab_suffix) {
171   bool verity_enabled;
172 
173   if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) {
174     fprintf(stderr, "Error getting whether verity is enabled.\n");
175     return EX_SOFTWARE;
176   }
177 
178   fprintf(stdout, "verity is %s", verity_enabled ? "enabled" : "disabled");
179   if (ab_suffix != "") {
180     fprintf(stdout, " on slot with suffix %s", ab_suffix.c_str());
181   }
182   fprintf(stdout, ".\n");
183 
184   return EX_OK;
185 }
186 
187 /* Helper function to get A/B suffix, if any. If the device isn't
188  * using A/B the empty string is returned. Otherwise either "_a",
189  * "_b", ... is returned.
190  *
191  * Note that since sometime in O androidboot.slot_suffix is deprecated
192  * and androidboot.slot should be used instead. Since bootloaders may
193  * be out of sync with the OS, we check both and for extra safety
194  * prepend a leading underscore if there isn't one already.
195  */
get_ab_suffix()196 std::string get_ab_suffix() {
197   std::string ab_suffix = android::base::GetProperty("ro.boot.slot_suffix", "");
198   if (ab_suffix == "") {
199     ab_suffix = android::base::GetProperty("ro.boot.slot", "");
200   }
201   if (ab_suffix.size() > 0 && ab_suffix[0] != '_') {
202     ab_suffix = std::string("_") + ab_suffix;
203   }
204   return ab_suffix;
205 }
206 
207 }  // namespace
208 
main(int argc,char * argv[])209 int main(int argc, char* argv[]) {
210   int ret;
211   AvbOps* ops = nullptr;
212   std::string ab_suffix = get_ab_suffix();
213 
214   if (argc < 2) {
215     usage(stderr, argc, argv);
216     ret = EX_USAGE;
217     goto out;
218   }
219 
220   ops = avb_ops_user_new();
221   if (ops == nullptr) {
222     fprintf(stderr, "Error getting AVB ops.\n");
223     ret = EX_SOFTWARE;
224     goto out;
225   }
226 
227   if (strcmp(argv[1], "disable-verity") == 0) {
228     ret = do_set_verity(ops, ab_suffix, false);
229   } else if (strcmp(argv[1], "enable-verity") == 0) {
230     ret = do_set_verity(ops, ab_suffix, true);
231   } else if (strcmp(argv[1], "get-verity") == 0) {
232     ret = do_get_verity(ops, ab_suffix);
233   } else if (strcmp(argv[1], "disable-verification") == 0) {
234     ret = do_set_verification(ops, ab_suffix, false);
235   } else if (strcmp(argv[1], "enable-verification") == 0) {
236     ret = do_set_verification(ops, ab_suffix, true);
237   } else if (strcmp(argv[1], "get-verification") == 0) {
238     ret = do_get_verification(ops, ab_suffix);
239   } else {
240     usage(stderr, argc, argv);
241     ret = EX_USAGE;
242   }
243 
244   ret = EX_OK;
245 out:
246   if (ops != nullptr) {
247     avb_ops_user_free(ops);
248   }
249   return ret;
250 }
251