• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "perm_setproc.h"
17 
18 #include <cerrno>
19 #include <cstdint>
20 #include <fcntl.h>
21 #include <sys/ioctl.h>
22 #include <unistd.h>
23 namespace OHOS {
24 namespace Security {
25 namespace AccessToken {
26 const uint32_t UINT32_T_BITS = 32;
27 const uint32_t MAX_PERM_SIZE = 64;
28 struct IoctlAddPermData {
29     uint32_t token;
30     uint32_t perm[MAX_PERM_SIZE] = { 0 };
31 };
32 
33 struct IoctlSetGetPermData {
34     uint32_t token;
35     uint32_t opCode;
36     bool isGranted;
37 };
38 
39 #define    ACCESS_TOKENID_ADD_PERMISSIONS \
40     _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, ADD_PERMISSIONS, struct IoctlAddPermData)
41 #define    ACCESS_TOKENID_REMOVE_PERMISSIONS \
42     _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, REMOVE_PERMISSIONS, uint32_t)
43 #define    ACCESS_TOKENID_GET_PERMISSION \
44     _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, GET_PERMISSION, struct IoctlSetGetPermData)
45 #define    ACCESS_TOKENID_SET_PERMISSION \
46     _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_PERMISSION, struct IoctlSetGetPermData)
47 
AddPermissionToKernel(uint32_t tokenID,const std::vector<uint32_t> & opCodeList,const std::vector<bool> & statusList)48 int32_t AddPermissionToKernel(
49     uint32_t tokenID, const std::vector<uint32_t>& opCodeList, const std::vector<bool>& statusList)
50 {
51     if (opCodeList.size() != statusList.size()) {
52         return ACCESS_TOKEN_PARAM_INVALID;
53     }
54     size_t size = opCodeList.size();
55     if (size == 0) {
56         RemovePermissionFromKernel(tokenID);
57         return ACCESS_TOKEN_OK;
58     }
59     struct IoctlAddPermData data;
60     data.token = tokenID;
61 
62     for (uint32_t i = 0; i < size; ++i) {
63         uint32_t opCode = opCodeList[i];
64         uint32_t idx = opCode / UINT32_T_BITS;
65         uint32_t bitIdx = opCode % UINT32_T_BITS;
66         if (statusList[i]) { // granted
67             data.perm[idx] |= static_cast<uint32_t>(0x01) << bitIdx;
68         } else {
69             data.perm[idx] &= ~(static_cast<uint32_t>(0x01) << bitIdx);
70         }
71     }
72 
73     int32_t fd = open(TOKENID_DEVNODE, O_RDWR);
74     if (fd < 0) {
75         return ACCESS_TOKEN_OPEN_ERROR;
76     }
77     int32_t ret = ioctl(fd, ACCESS_TOKENID_ADD_PERMISSIONS, &data);
78     close(fd);
79     if (ret != ACCESS_TOKEN_OK) {
80         return errno;
81     }
82 
83     return ACCESS_TOKEN_OK;
84 }
85 
RemovePermissionFromKernel(uint32_t tokenID)86 int32_t RemovePermissionFromKernel(uint32_t tokenID)
87 {
88     int32_t fd = open(TOKENID_DEVNODE, O_RDWR);
89     if (fd < 0) {
90         return ACCESS_TOKEN_OPEN_ERROR;
91     }
92     int32_t ret = ioctl(fd, ACCESS_TOKENID_REMOVE_PERMISSIONS, &tokenID);
93     close(fd);
94     if (ret) {
95         return errno;
96     }
97 
98     return ACCESS_TOKEN_OK;
99 }
100 
SetPermissionToKernel(uint32_t tokenID,int32_t opCode,bool status)101 int32_t SetPermissionToKernel(uint32_t tokenID, int32_t opCode, bool status)
102 {
103     struct IoctlSetGetPermData data = {
104         .token = tokenID,
105         .opCode = opCode,
106         .isGranted = status,
107     };
108 
109     int32_t fd = open(TOKENID_DEVNODE, O_RDWR);
110     if (fd < 0) {
111         return ACCESS_TOKEN_OPEN_ERROR;
112     }
113     int32_t ret = ioctl(fd, ACCESS_TOKENID_SET_PERMISSION, &data);
114     close(fd);
115     if (ret != ACCESS_TOKEN_OK) {
116         return errno;
117     }
118 
119     return ACCESS_TOKEN_OK;
120 }
121 
GetPermissionFromKernel(uint32_t tokenID,int32_t opCode,bool & isGranted)122 int32_t GetPermissionFromKernel(uint32_t tokenID, int32_t opCode, bool& isGranted)
123 {
124     struct IoctlSetGetPermData data = {
125         .token = tokenID,
126         .opCode = opCode,
127         .isGranted = false,
128     };
129     isGranted =  false;
130 
131     int32_t fd = open(TOKENID_DEVNODE, O_RDWR);
132     if (fd < 0) {
133         return ACCESS_TOKEN_OPEN_ERROR;
134     }
135     int32_t ret = ioctl(fd, ACCESS_TOKENID_GET_PERMISSION, &data);
136     close(fd);
137     if (ret < 0) {
138         return errno;
139     }
140     isGranted = (ret == 1);
141     return ACCESS_TOKEN_OK;
142 }
143 } // namespace AccessToken
144 } // namespace Security
145 } // namespace OHOS
146