1 /* 2 * Copyright (c) 2025 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 #ifndef FD_UTILS_H 17 #define FD_UTILS_H 18 19 #include <sstream> 20 #include <sys/ioctl.h> 21 #include "common/fdsan_fd.h" 22 #ifdef __linux__ 23 #include <sys/xattr.h> 24 #endif 25 26 namespace OHOS { 27 namespace Media { 28 29 #ifdef __linux__ 30 namespace { 31 constexpr size_t MAX_ATTR_NAME = 64; 32 const std::string CLOUD_LOCATION_ATTR = "user.cloud.location"; 33 static const std::string LOCAL = "1"; 34 } 35 #endif 36 37 class FdUtils { 38 public: 39 // This method is prohibited from being used on the server side. ReOpenFd(int32_t fd)40 static FdsanFd ReOpenFd(int32_t fd) 41 { 42 #ifdef __linux__ 43 if (fd > 0 && LocalFd(fd)) { 44 MEDIA_LOGI("ReOpenFd In"); 45 std::stringstream ss; 46 ss << "/proc/self/fd/" << fd; 47 std::string fdPathStr = ss.str(); 48 char realPath[PATH_MAX_REAL]; 49 ssize_t result = readlink(fdPathStr.c_str(), realPath, sizeof(realPath)); 50 if (result == RESULT_ERROR) { 51 MEDIA_LOGW("invailed fd: %{public}d, error: %{public}s", fd, std::strerror(errno)); 52 return FdsanFd(); 53 } 54 auto newFd = open(fdPathStr.c_str(), O_RDONLY); 55 if (newFd < 0) { 56 MEDIA_LOGW("invailed fd: %{public}d, error: %{public}s", fd, std::strerror(errno)); 57 return FdsanFd(); 58 } 59 return FdsanFd(newFd); 60 } 61 #endif 62 MEDIA_LOGW("=== fd is cloud"); 63 return FdsanFd(); 64 } 65 66 private: 67 #if __linux__ LocalFd(int32_t fd)68 static bool LocalFd(int32_t fd) 69 { 70 char value[MAX_ATTR_NAME + 1] = {0}; 71 ssize_t size = fgetxattr(fd, CLOUD_LOCATION_ATTR.c_str(), value, MAX_ATTR_NAME); 72 if (size <= 0 || static_cast<size_t>(size) > MAX_ATTR_NAME) { 73 MEDIA_LOGW("Getxattr value failed, errno is %{public}s", std::strerror(errno)); 74 return false; 75 } 76 std::string local(value, static_cast<size_t>(size)); 77 MEDIA_LOGD("Getxattr value, local is %{public}s", local.c_str()); 78 79 return local == LOCAL; 80 } 81 #endif 82 83 // The HMDFS I/O control code 84 static constexpr unsigned int HMDFS_IOC = 0xf2; 85 // The I/O control code for retrieving the HMDFS location 86 static constexpr unsigned int HMDFS_IOC_GET_LOCATION = _IOR(HMDFS_IOC, 7, __u32); 87 // The I/O control code for cloud operations 88 static constexpr int IOCTL_CLOUD = 2; 89 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "FdUtils"}; 90 static constexpr ssize_t RESULT_ERROR = -1; 91 static constexpr int PATH_MAX_REAL = PATH_MAX + 1; 92 }; 93 } // namespace Media 94 } // namespace OHOS 95 #endif // FD_UTILS_H