18e920a95Sopenharmony_ci/*
28e920a95Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
38e920a95Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48e920a95Sopenharmony_ci * you may not use this file except in compliance with the License.
58e920a95Sopenharmony_ci * You may obtain a copy of the License at
68e920a95Sopenharmony_ci *
78e920a95Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
88e920a95Sopenharmony_ci *
98e920a95Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108e920a95Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118e920a95Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128e920a95Sopenharmony_ci * See the License for the specific language governing permissions and
138e920a95Sopenharmony_ci * limitations under the License.
148e920a95Sopenharmony_ci */
158e920a95Sopenharmony_ci
168e920a95Sopenharmony_ci#include "xpm_common.h"
178e920a95Sopenharmony_ci
188e920a95Sopenharmony_ci#include <cerrno>
198e920a95Sopenharmony_ci#include <cstdio>
208e920a95Sopenharmony_ci#include <cstdlib>
218e920a95Sopenharmony_ci#include <cstring>
228e920a95Sopenharmony_ci#include <fcntl.h>
238e920a95Sopenharmony_ci#include <unistd.h>
248e920a95Sopenharmony_ci#include <securec.h>
258e920a95Sopenharmony_ci#include <sys/mman.h>
268e920a95Sopenharmony_ci#include <sys/stat.h>
278e920a95Sopenharmony_ci
288e920a95Sopenharmony_ci#include "code_sign_attr_utils.h"
298e920a95Sopenharmony_ci#include "log.h"
308e920a95Sopenharmony_ci
318e920a95Sopenharmony_cinamespace OHOS {
328e920a95Sopenharmony_cinamespace Security {
338e920a95Sopenharmony_cinamespace CodeSign {
348e920a95Sopenharmony_cistruct XpmRegionArea {
358e920a95Sopenharmony_ci    uint64_t start;
368e920a95Sopenharmony_ci    uint64_t end;
378e920a95Sopenharmony_ci};
388e920a95Sopenharmony_ci
398e920a95Sopenharmony_ciconst std::string XPM_PROC_PREFIX_PATH = "/proc/";
408e920a95Sopenharmony_ciconst std::string XPM_PROC_SUFFIX_PATH = "/xpm_region";
418e920a95Sopenharmony_ci
428e920a95Sopenharmony_ciconstexpr unsigned long XPM_PROC_LENGTH = 50;
438e920a95Sopenharmony_ci
448e920a95Sopenharmony_cistatic int GetXpmRegion(struct XpmRegionArea &area)
458e920a95Sopenharmony_ci{
468e920a95Sopenharmony_ci    if (InitXpm(0, PROCESS_OWNERID_UNINIT, NULL) != 0) {
478e920a95Sopenharmony_ci        LOG_ERROR("init xpm region failed");
488e920a95Sopenharmony_ci        return -1;
498e920a95Sopenharmony_ci    }
508e920a95Sopenharmony_ci
518e920a95Sopenharmony_ci    pid_t pid = getpid();
528e920a95Sopenharmony_ci    std::string path = XPM_PROC_PREFIX_PATH + std::to_string(pid) + XPM_PROC_SUFFIX_PATH;
538e920a95Sopenharmony_ci    int fd = open(path.c_str(), O_RDWR);
548e920a95Sopenharmony_ci    if (fd < 0) {
558e920a95Sopenharmony_ci        LOG_ERROR("open xpm proc file failed(%{public}s)", strerror(errno));
568e920a95Sopenharmony_ci        return -1;
578e920a95Sopenharmony_ci    }
588e920a95Sopenharmony_ci
598e920a95Sopenharmony_ci    char xpmRegion[XPM_PROC_LENGTH] = {0};
608e920a95Sopenharmony_ci    int ret = read(fd, xpmRegion, sizeof(xpmRegion));
618e920a95Sopenharmony_ci    if (ret < 0) {
628e920a95Sopenharmony_ci        LOG_ERROR("read xpm proc file failed(%{public}s)", strerror(errno));
638e920a95Sopenharmony_ci        return -1;
648e920a95Sopenharmony_ci    }
658e920a95Sopenharmony_ci
668e920a95Sopenharmony_ci    ret = sscanf_s(xpmRegion, "%llx-%llx", &area.start, &area.end);
678e920a95Sopenharmony_ci    if (ret < 0) {
688e920a95Sopenharmony_ci        LOG_ERROR("sscanf xpm region string failed(%{public}s)", strerror(errno));
698e920a95Sopenharmony_ci        return -1;
708e920a95Sopenharmony_ci    }
718e920a95Sopenharmony_ci
728e920a95Sopenharmony_ci    close(fd);
738e920a95Sopenharmony_ci    return 0;
748e920a95Sopenharmony_ci}
758e920a95Sopenharmony_ci
768e920a95Sopenharmony_cibool AllocXpmRegion()
778e920a95Sopenharmony_ci{
788e920a95Sopenharmony_ci    struct XpmRegionArea area = {0};
798e920a95Sopenharmony_ci
808e920a95Sopenharmony_ci    if (GetXpmRegion(area)) {
818e920a95Sopenharmony_ci        return false;
828e920a95Sopenharmony_ci    }
838e920a95Sopenharmony_ci    if (!area.start) {
848e920a95Sopenharmony_ci        return false;
858e920a95Sopenharmony_ci    }
868e920a95Sopenharmony_ci    if (!area.end) {
878e920a95Sopenharmony_ci        return false;
888e920a95Sopenharmony_ci    }
898e920a95Sopenharmony_ci
908e920a95Sopenharmony_ci    return true;
918e920a95Sopenharmony_ci}
928e920a95Sopenharmony_ci} // namespace CodeSign
938e920a95Sopenharmony_ci} // namespace Security
948e920a95Sopenharmony_ci} // namespace OHOS