• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "key_utils.h"
17 
18 #include <cstdlib>
19 #include <dlfcn.h>
20 #include <fcntl.h>
21 #include <string>
22 #include <unistd.h>
23 #include <securec.h>
24 
25 #include "log_rust.h"
26 
27 using namespace OHOS::Security::CodeSign;
28 
29 enum DeviceMode {
30     NOT_INITIALIZE = 0,
31     DEVICE_MODE_RD,
32     DEVICE_MODE_NOT_RD
33 };
34 
35 constexpr int32_t CMDLINE_MAX_BUF_LEN = 4096;
36 #ifndef KEY_ENABLE_UTILS_TEST
37 static const std::string PROC_CMDLINE_FILE_PATH = "/proc/cmdline";
38 static int32_t g_isRdDevice = NOT_INITIALIZE;
39 #else
40 const std::string PROC_CMDLINE_FILE_PATH = "/data/test/tmp/cmdline";
41 int32_t g_isRdDevice = NOT_INITIALIZE;
42 #endif
43 
CheckDeviceMode(char * buf,ssize_t bufLen)44 static bool CheckDeviceMode(char *buf, ssize_t bufLen)
45 {
46     bool status = false;
47     char *onStr = strstr(buf, "oemmode=rd");
48     char *offStr = strstr(buf, "oemmode=user");
49     char *statusStr = strstr(buf, "oemmode=");
50     if (onStr == nullptr && offStr == nullptr) {
51         LOG_INFO(LABEL, "Not rd mode, cmdline = %{private}s", buf);
52     } else if (offStr != nullptr && statusStr != nullptr && offStr != statusStr) {
53         LOG_ERROR(LABEL, "cmdline attacked, cmdline = %{private}s", buf);
54     } else if (onStr != nullptr && offStr == nullptr) {
55         status = true;
56         LOG_DEBUG(LABEL, "Oemode is rd");
57     }
58     return status;
59 }
60 
CheckEfuseStatus(char * buf,ssize_t bufLen)61 static bool CheckEfuseStatus(char *buf, ssize_t bufLen)
62 {
63     bool status = false;
64     char *onStr = strstr(buf, "efuse_status=1");
65     char *offStr = strstr(buf, "efuse_status=0");
66     char *statusStr = strstr(buf, "efuse_status=");
67     if (onStr == nullptr && offStr == nullptr) {
68         LOG_INFO(LABEL, "device is efused, cmdline = %{private}s", buf);
69     } else if (offStr != nullptr && statusStr != nullptr && offStr != statusStr) {
70         LOG_ERROR(LABEL, "cmdline attacked, cmdline = %{private}s", buf);
71     } else if (onStr != nullptr && offStr == nullptr) {
72         status = true;
73         LOG_DEBUG(LABEL, "device is not efused");
74     }
75     return status;
76 }
77 
ParseCMDLine()78 static void ParseCMDLine()
79 {
80     int32_t fd = open(PROC_CMDLINE_FILE_PATH.c_str(), O_RDONLY);
81     if (fd < 0) {
82         g_isRdDevice = DEVICE_MODE_NOT_RD;
83         LOG_ERROR(LABEL, "open %{public}s failed, %{public}s",
84             PROC_CMDLINE_FILE_PATH.c_str(), strerror(errno));
85         return;
86     }
87     char *buf = nullptr;
88     int32_t status = DEVICE_MODE_NOT_RD;
89     do {
90         buf = static_cast<char *>(malloc(CMDLINE_MAX_BUF_LEN));
91         if (buf == nullptr) {
92             LOG_ERROR(LABEL, "Alloc buffer for reading cmdline failed.");
93             break;
94         }
95         (void) memset_s(buf, CMDLINE_MAX_BUF_LEN, 0, CMDLINE_MAX_BUF_LEN);
96         ssize_t bufLen = read(fd, buf, CMDLINE_MAX_BUF_LEN - 1);
97         if (bufLen < 0) {
98             LOG_ERROR(LABEL, "Read %{public}s failed, %{public}s.",
99                 PROC_CMDLINE_FILE_PATH.c_str(), strerror(errno));
100             break;
101         }
102         if (CheckDeviceMode(buf, bufLen) || CheckEfuseStatus(buf, bufLen)) {
103             status = DEVICE_MODE_RD;
104         }
105     } while (0);
106     g_isRdDevice = status;
107     (void) close(fd);
108     free(buf);
109 }
110 
IsRdDevice()111 bool IsRdDevice()
112 {
113     if (g_isRdDevice == NOT_INITIALIZE) {
114         ParseCMDLine();
115     }
116     return g_isRdDevice == DEVICE_MODE_RD;
117 }