• 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 <unistd.h>
17 #include "src/callbacks.h"
18 #include "src/label_internal.h"
19 #include "policycoreutils.h"
20 #include "selinux/restorecon.h"
21 
22 static pthread_once_t g_fcOnce = PTHREAD_ONCE_INIT;
23 static struct selabel_handle *g_fcHandle = NULL;
24 static const char SYSTEM_FILE_CONTEXTS[] = "/system/etc/selinux/targeted/contexts/file_contexts";
25 static const char VENDOR_FILE_CONTEXTS[] = "/vendor/etc/selinux/targeted/contexts/file_contexts";
26 #define MAX_OPT_NUM 3 // system + vendor + digest
27 
28 typedef struct selinux_opt SelinuxOptions;
29 
SetFileContextsHandle(void)30 static void SetFileContextsHandle(void)
31 {
32     if (g_fcHandle != NULL) {
33         selinux_log(SELINUX_ERROR, "File_contexts handle already set\n");
34         return;
35     }
36 
37     SelinuxOptions options[MAX_OPT_NUM] = {0};
38 
39     unsigned int index = 0;
40     if (access(SYSTEM_FILE_CONTEXTS, R_OK) == 0) {
41         SelinuxOptions systemOption = {SELABEL_OPT_PATH, SYSTEM_FILE_CONTEXTS};
42         options[index++] = systemOption;
43     }
44     if (access(VENDOR_FILE_CONTEXTS, R_OK) == 0) {
45         SelinuxOptions vendorOption = {SELABEL_OPT_PATH, VENDOR_FILE_CONTEXTS};
46         options[index++] = vendorOption;
47     }
48 
49     // default option of selabel_open
50     SelinuxOptions digestOption = {SELABEL_OPT_DIGEST, (char *)1};
51     options[index++] = digestOption;
52 
53     g_fcHandle = selabel_open(SELABEL_CTX_FILE, options, index);
54     if (g_fcHandle == NULL) {
55         selinux_log(SELINUX_ERROR, "File_contexts handle open fail\n");
56         return;
57     }
58 
59     selinux_restorecon_set_sehandle(g_fcHandle);
60 }
61 
RestoreconCommon(const char * path,unsigned int flag)62 static int RestoreconCommon(const char *path, unsigned int flag)
63 {
64     __selinux_once(g_fcOnce, SetFileContextsHandle);
65     if (g_fcHandle == NULL) {
66         selinux_log(SELINUX_ERROR, "File_contexts handle is null\n");
67         return -1;
68     }
69     return selinux_restorecon(path, flag);
70 }
71 
Restorecon(const char * path)72 int Restorecon(const char *path)
73 {
74     return RestoreconCommon(path, SELINUX_RESTORECON_REALPATH);
75 }
76 
RestoreconRecurse(const char * path)77 int RestoreconRecurse(const char *path)
78 {
79     return RestoreconCommon(path, SELINUX_RESTORECON_REALPATH | SELINUX_RESTORECON_RECURSE);
80 }
81