Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 : #include "package_verify.h"
11 :
12 : #include <unistd.h>
13 : #include <fstream>
14 : #include "mmpa/mmpa_api.h"
15 : #include "tsd_log.h"
16 : #include "tsd_scope_guard.h"
17 : #include "weak_ascend_hal.h"
18 : #include "tsd_util_func.h"
19 : #include "package_process_config.h"
20 :
21 : namespace tsd {
22 : namespace {
23 : using VerifyImgFunc = int32_t (*)(HAL_VERIFY_TYPE, HAL_IMG_ID, const char_t*, int32_t);
24 : constexpr uint32_t CMS_HEAD_FIX_PACKET_LEN = (4U + 4U) * 1024U;
25 : constexpr uint32_t CMS_IMG_DESC_LEN = 256U;
26 : } // namespace
27 :
28 3 : TSD_StatusT PackageVerify::VerifyPackage() const
29 : {
30 3 : TSD_INFO("Start verify package, path=%s", pkgPath_.c_str());
31 :
32 3 : TSD_StatusT ret = IsPackageValid();
33 3 : if (ret != TSD_OK) {
34 1 : TSD_ERROR("Verify package failed by path is invalid, ret=%u, path=%s", ret, pkgPath_.c_str());
35 1 : return TSD_VERIFY_OPP_FAIL;
36 : }
37 :
38 2 : ret = ChangePackageMode();
39 2 : if (ret != TSD_OK) {
40 0 : TSD_ERROR("Verify package failed by change mode failed, ret=%u, path=%s", ret, pkgPath_.c_str());
41 0 : return TSD_VERIFY_OPP_FAIL;
42 : }
43 :
44 2 : ret = IsPackageNeedCmsVerify() ? VerifyPackageByCms() : VerifyPackageByDrv();
45 2 : if (ret != TSD_OK) {
46 0 : TSD_ERROR("Verify package failed, ret=%u, path=%s", ret, pkgPath_.c_str());
47 0 : return TSD_VERIFY_OPP_FAIL;
48 : }
49 :
50 2 : TSD_INFO("End verify package, ret=%u, path=%s", ret, pkgPath_.c_str());
51 :
52 2 : return TSD_OK;
53 : }
54 :
55 4 : TSD_StatusT PackageVerify::IsPackageValid() const
56 : {
57 4 : if (pkgPath_.empty()) {
58 1 : TSD_ERROR("Package path is empty");
59 1 : return TSD_INTERNAL_ERROR;
60 : }
61 :
62 3 : const int32_t ret = access(pkgPath_.c_str(), F_OK);
63 3 : if (ret != EOK) {
64 2 : TSD_ERROR("File cannot access, ret=%d, path=%s, reason=%s", ret, pkgPath_.c_str(), SafeStrerror().c_str());
65 2 : return TSD_INTERNAL_ERROR;
66 : }
67 :
68 1 : return TSD_OK;
69 : }
70 :
71 2 : TSD_StatusT PackageVerify::ChangePackageMode() const
72 : {
73 : // package must have write auth, because need rewrite to remove signature
74 2 : const int32_t ret = chmod(pkgPath_.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP));
75 2 : if (ret != EOK) {
76 1 : TSD_ERROR(
77 : "Change package mode failed, ret=%d, path=%s, reason=%s", ret, pkgPath_.c_str(), SafeStrerror().c_str());
78 1 : return TSD_INTERNAL_ERROR;
79 : }
80 :
81 1 : return TSD_OK;
82 : }
83 :
84 2 : bool PackageVerify::IsPackageNeedCmsVerify() const
85 : {
86 2 : if ((IsSupportCmsVerify()) && (IsCmsVerifyPackage())) {
87 1 : return true;
88 : }
89 :
90 1 : return false;
91 : }
92 :
93 2 : bool PackageVerify::IsSupportCmsVerify() const
94 : {
95 : #if (defined CMS_CBB_VERIFY_PKT) || (defined TSD_HOST_LIB)
96 2 : return true;
97 : #else
98 : return false;
99 : #endif
100 : }
101 :
102 7 : bool PackageVerify::IsCmsVerifyPackage() const
103 : {
104 14 : if ((pkgPath_.find("Ascend-aicpu_syskernels.tar.gz") != std::string::npos) ||
105 13 : (pkgPath_.find("_Ascend-runtime_device-minios.tar.gz") != std::string::npos) ||
106 11 : (pkgPath_.find("_Ascend-opp_rt-minios.aarch64.tar.gz") != std::string::npos) ||
107 9 : (pkgPath_.find("Ascend-aicpu_extend_syskernels.tar.gz") != std::string::npos) ||
108 18 : (pkgPath_.find("Ascend-device-sw-plugin.tar.gz") != std::string::npos) ||
109 3 : (pkgPath_.find("transformer_tile_fwk_aicpu_kernel.tar.gz") != std::string::npos)) {
110 5 : return true;
111 : }
112 :
113 2 : PackageProcessConfig* pkgConf = PackageProcessConfig::GetInstance();
114 2 : if (pkgConf->IsConfigPackageInfo(pkgPath_)) {
115 0 : return true;
116 : }
117 :
118 2 : return false;
119 : }
120 :
121 2 : TSD_StatusT PackageVerify::VerifyPackageByDrv() const
122 : {
123 2 : const std::string soName = "libascend_drvupgrade.so";
124 2 : const std::string soPath = "/usr/lib64/" + soName;
125 2 : void* handle = mmDlopen(soPath.c_str(), MMPA_RTLD_LAZY);
126 2 : if (handle == nullptr) {
127 0 : handle = mmDlopen(soName.c_str(), MMPA_RTLD_LAZY);
128 0 : if (handle == nullptr) {
129 0 : TSD_ERROR("Open %s failed, reason=%s, dlerror=%s", soName.c_str(), SafeStrerror().c_str(), dlerror());
130 0 : return TSD_INTERNAL_ERROR;
131 : }
132 : }
133 4 : const ScopeGuard closeGuard([handle]() { (void)mmDlclose(handle); });
134 :
135 2 : const std::string apiName = "halVerifyImg";
136 2 : void* const tempFunc = mmDlsym(handle, apiName.c_str());
137 2 : if (tempFunc == nullptr) {
138 0 : TSD_ERROR("Get api %s in %s failed", apiName.c_str(), soName.c_str());
139 0 : return TSD_INTERNAL_ERROR;
140 : }
141 :
142 2 : const VerifyImgFunc verifyImg = reinterpret_cast<VerifyImgFunc>(tempFunc);
143 2 : const int32_t ret = verifyImg(
144 : VERIFY_TYPE_SOC, ITEE_IMG_ID, pkgPath_.c_str(), static_cast<int32_t>(HAL_VERIFY_MODE_COVER_WITH_HEAD_OFF));
145 2 : if (ret != 0) {
146 1 : TSD_ERROR("Check head tag failed, ret=%d, path=%s", ret, pkgPath_.c_str());
147 1 : return TSD_VERIFY_OPP_FAIL;
148 : }
149 :
150 1 : return TSD_OK;
151 2 : }
152 :
153 1 : uint32_t PackageVerify::GetVerifyDeviceId() const
154 : {
155 1 : TSD_INFO("use tsdclient to verify package");
156 1 : return 0U;
157 : }
158 :
159 1 : TSD_StatusT PackageVerify::VerifyPackageByCms() const
160 : {
161 1 : TSD_INFO("[CMSCBB_VERIFY] verify pkg[%s] by cms start", pkgPath_.c_str());
162 1 : uint32_t codeLen = 0U;
163 1 : TSD_StatusT ret = GetPkgCodeLen(pkgPath_, codeLen);
164 1 : if (ret != TSD_OK) {
165 0 : TSD_ERROR("[CMSCBB_VERIFY] get cmsInfo offset failed");
166 0 : return static_cast<uint32_t>(TSD_START_FAIL);
167 : }
168 1 : ret = ProcessSendStepVerify(pkgPath_, codeLen);
169 1 : if (ret != TSD_OK) {
170 0 : TSD_ERROR("[CMSCBB_VERIFY] ProcessSendStepVerify failed");
171 0 : return static_cast<uint32_t>(TSD_START_FAIL);
172 : }
173 1 : TSD_INFO("[CMSCBB_VERIFY] verify pkg[%s] by cms end", pkgPath_.c_str());
174 1 : return TSD_OK;
175 : }
176 :
177 4 : TSD_StatusT PackageVerify::GetPkgCodeLen(const std::string& srcPath, uint32_t& mixCodeLen) const
178 : {
179 4 : TSD_INFO("[CMSCBB_VERIFY] GetPkgCodeLen start");
180 4 : FILE* fp = fopen(srcPath.c_str(), "r");
181 4 : if (fp == nullptr) {
182 1 : TSD_ERROR("[CMSCBB_VERIFY] fopen failed. path[%s]", srcPath.c_str());
183 1 : return static_cast<uint32_t>(TSD_START_FAIL);
184 : }
185 6 : const ScopeGuard closeFileGuard([&fp]() { (void)fclose(fp); });
186 3 : const int32_t ret = fseek(fp, 0, SEEK_END);
187 3 : if (ret != 0) {
188 0 : TSD_ERROR("[CMSCBB_VERIFY] fseek failed. path[%s]", srcPath.c_str());
189 0 : return static_cast<uint32_t>(TSD_START_FAIL);
190 : }
191 3 : const int64_t fileLen = ftell(fp);
192 3 : if (fileLen <= static_cast<int64_t>(CMS_IMG_DESC_LEN + CMS_HEAD_FIX_PACKET_LEN)) {
193 3 : TSD_ERROR("[CMSCBB_VERIFY] file length invalid. path[%s], len[%lld]", srcPath.c_str(), fileLen);
194 3 : return static_cast<uint32_t>(TSD_START_FAIL);
195 : }
196 0 : rewind(fp);
197 0 : std::unique_ptr<SeImageHead> pktHeaderPtr(new (std::nothrow) SeImageHead());
198 0 : if (pktHeaderPtr == nullptr) {
199 0 : TSD_ERROR("[CMSCBB_VERIFY] new SeImageHead failed");
200 0 : return static_cast<uint32_t>(TSD_START_FAIL);
201 : }
202 0 : SeImageHead* const pktHeader = pktHeaderPtr.get();
203 0 : if (pktHeader == nullptr) {
204 0 : TSD_ERROR("[CMSCBB_VERIFY] malloc failed");
205 0 : return static_cast<uint32_t>(TSD_START_FAIL);
206 : }
207 :
208 0 : const uint32_t freadBytes = fread(pktHeader, sizeof(uint8_t), sizeof(SeImageHead), fp);
209 0 : if (freadBytes != sizeof(SeImageHead)) {
210 0 : TSD_ERROR("[CMSCBB_VERIFY] fread fileHead failed. readn[%d]", freadBytes);
211 0 : return static_cast<uint32_t>(TSD_START_FAIL);
212 : }
213 0 : mixCodeLen = pktHeader->uwLCodeLen;
214 0 : if (mixCodeLen <= CMS_IMG_DESC_LEN) {
215 0 : TSD_ERROR("[CMSCBB_VERIFY] invalid code length:%u", mixCodeLen);
216 0 : return static_cast<uint32_t>(TSD_START_FAIL);
217 : }
218 0 : mixCodeLen = mixCodeLen - CMS_IMG_DESC_LEN;
219 0 : TSD_RUN_INFO("[CMSCBB_VERIFY] GetPkgCodeLen end, mixCodeLen[%u]", mixCodeLen);
220 0 : return TSD_OK;
221 3 : }
222 :
223 3 : TSD_StatusT PackageVerify::ProcessSendStepVerify(const std::string& srcPath, const uint32_t codeLen) const
224 : {
225 3 : TSD_INFO("[CMSCBB_VERIFY] verify code len[%u] start", codeLen);
226 3 : FILE* fp = fopen(srcPath.c_str(), "r");
227 3 : if (fp == nullptr) {
228 1 : TSD_ERROR("[CMSCBB_VERIFY] fopen failed. path[%s]", srcPath.c_str());
229 1 : return static_cast<uint32_t>(TSD_START_FAIL);
230 : }
231 4 : const ScopeGuard closeFileGuard([&fp]() { (void)fclose(fp); });
232 2 : const int32_t ret = fseek(fp, CMS_HEAD_FIX_PACKET_LEN, SEEK_SET);
233 2 : if (ret != 0) {
234 0 : TSD_ERROR("[CMSCBB_VERIFY] fseek failed. path[%s]", srcPath.c_str());
235 0 : return static_cast<uint32_t>(TSD_START_FAIL);
236 : }
237 2 : const uint32_t fileTotalLen = codeLen + CMS_IMG_DESC_LEN;
238 2 : std::unique_ptr<uint8_t[]> srcFilePtr(new (std::nothrow) uint8_t[fileTotalLen]);
239 2 : if (srcFilePtr == nullptr) {
240 0 : TSD_ERROR("[CMSCBB_VERIFY] new srcFilePtr failed");
241 0 : return static_cast<uint32_t>(TSD_START_FAIL);
242 : }
243 2 : uint8_t* srcFile = srcFilePtr.get();
244 2 : if (srcFile == nullptr) {
245 0 : TSD_ERROR("[CMSCBB_VERIFY] new srcFilePtr failed");
246 0 : return static_cast<uint32_t>(TSD_START_FAIL);
247 : }
248 2 : const uint32_t freadBytes = fread(srcFile, sizeof(uint8_t), fileTotalLen, fp);
249 2 : if (freadBytes != fileTotalLen) {
250 2 : TSD_ERROR("[CMSCBB_VERIFY] fread failed. readn[%d], totalLen:%u", freadBytes, fileTotalLen);
251 2 : return static_cast<uint32_t>(TSD_START_FAIL);
252 : }
253 :
254 0 : const TSD_StatusT res = ReWriteAicpuPackage(srcFile + CMS_IMG_DESC_LEN, codeLen, srcPath);
255 0 : if (res != TSD_OK) {
256 0 : TSD_ERROR("[CMSCBB_VERIFY] ReWriteAicpuPackage failed");
257 0 : return static_cast<uint32_t>(TSD_START_FAIL);
258 : }
259 0 : TSD_INFO("[CMSCBB_VERIFY] verify ProcessSendStepVerify end");
260 0 : return TSD_OK;
261 2 : }
262 :
263 3 : TSD_StatusT PackageVerify::ReWriteAicpuPackage(
264 : const uint8_t* const buf, const uint32_t len, const std::string& srcPath) const
265 : {
266 3 : TSD_INFO("[CMSCBB_VERIFY] start write new file");
267 3 : FILE* fp = fopen(srcPath.c_str(), "w");
268 3 : if (fp == nullptr) {
269 1 : TSD_ERROR("[CMSCBB_VERIFY] fopen failed. path[%s]", srcPath.c_str());
270 1 : return static_cast<uint32_t>(TSD_START_FAIL);
271 : }
272 4 : const ScopeGuard closeFileGuard([&fp]() { (void)fclose(fp); });
273 2 : const size_t writeRet = fwrite(buf, len, 1, fp);
274 2 : if (writeRet != 1) {
275 1 : TSD_ERROR("[CMSCBB_VERIFY] fwrite failed writeRet[%zu]", writeRet);
276 1 : return static_cast<uint32_t>(TSD_START_FAIL);
277 : }
278 1 : TSD_INFO("[CMSCBB_VERIFY] end write new file:%s, len:%u", srcPath.c_str(), len);
279 1 : return TSD_OK;
280 2 : }
281 :
282 : } // namespace tsd
|