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#include "cmd.h" 16#include "log.h" 17#include "base.h" 18#include "usb_util.h" 19#if defined(SURPPORT_SELINUX) 20#include "selinux/selinux.h" 21#endif 22#include "parameter.h" 23#include <string> 24#include <cstdio> 25#include <cerrno> 26#include <grp.h> 27#include <pwd.h> 28#include <unistd.h> 29#include <sys/types.h> 30#include "sys_para.h" 31 32namespace Hdc { 33using namespace std; 34 35static bool DropRootPrivileges() 36{ 37 int ret; 38 const char *userName = "shell"; 39 vector<const char *> groupsNames = { "shell", "log", "readproc", "file_manager" }; 40 struct passwd *user; 41 gid_t *gids = nullptr; 42 43 user = getpwnam(userName); 44 if (user == nullptr) { 45 WRITE_LOG(LOG_INFO, "getpwuid %s fail, %s", userName, strerror(errno)); 46 return false; 47 } 48 gids = static_cast<gid_t *>(calloc(groupsNames.size(), sizeof(gid_t))); 49 if (gids == nullptr) { 50 return false; 51 } 52 for (size_t i = 0; i < groupsNames.size(); i++) { 53 struct group *group = getgrnam(groupsNames[i]); 54 if (group == nullptr) { 55 continue; 56 } 57 gids[i] = group->gr_gid; 58 } 59 ret = setuid(user->pw_uid); 60 if (ret) { 61 WRITE_LOG(LOG_WARN, "setuid %s fail, %s", userName, strerror(errno)); 62 free(gids); 63 return false; 64 } 65 ret = setgid(user->pw_gid); 66 if (ret) { 67 WRITE_LOG(LOG_WARN, "setgid %s fail, %s", userName, strerror(errno)); 68 free(gids); 69 return false; 70 } 71 ret = setgroups(groupsNames.size(), gids); 72 if (ret) { 73 WRITE_LOG(LOG_WARN, "setgroups %s fail, %s", userName, strerror(errno)); 74 free(gids); 75 return false; 76 } 77 free(gids); 78#if defined(SURPPORT_SELINUX) 79 if (setcon("u:r:hdcd:s0") != 0) { 80 WRITE_LOG(LOG_WARN, "setcon fail, errno %s", strerror(errno)); 81 return false; 82 } 83#endif 84 return true; 85} 86 87extern "C" bool NeedDropRootPrivileges() 88{ 89 string rootMode; 90 string debugMode; 91 GetDevItem("const.debuggable", debugMode); 92 GetDevItem("persist.hdc.root", rootMode); 93 WRITE_LOG(LOG_WARN, "debuggable:[%s]", debugMode.c_str()); 94 WRITE_LOG(LOG_WARN, "param root:[%s]", rootMode.c_str()); 95 if (debugMode != "1") { 96 return DropRootPrivileges(); 97 } 98 if (rootMode == "0") { 99 return DropRootPrivileges(); 100 } 101 WRITE_LOG(LOG_WARN, "will keep current privilege", rootMode.c_str()); 102 return true; 103} 104extern "C" void Restart() 105{ 106 execl("/system/bin/hdcd", "hdcd", nullptr, nullptr); 107} 108} 109