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