1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.util.Slog;
21 
22 import java.io.File;
23 import java.io.FileDescriptor;
24 import java.io.IOException;
25 
26 /**
27  * This class provides access to the centralized jni bindings for
28  * SELinux interaction.
29  * {@hide}
30  */
31 public class SELinux {
32     private static final String TAG = "SELinux";
33 
34     /** Keep in sync with ./external/selinux/libselinux/include/selinux/android.h */
35     private static final int SELINUX_ANDROID_RESTORECON_NOCHANGE = 1;
36     private static final int SELINUX_ANDROID_RESTORECON_VERBOSE = 2;
37     private static final int SELINUX_ANDROID_RESTORECON_RECURSE = 4;
38     private static final int SELINUX_ANDROID_RESTORECON_FORCE = 8;
39     private static final int SELINUX_ANDROID_RESTORECON_DATADATA = 16;
40     private static final int SELINUX_ANDROID_RESTORECON_SKIPCE = 32;
41     private static final int SELINUX_ANDROID_RESTORECON_CROSS_FILESYSTEMS = 64;
42     private static final int SELINUX_ANDROID_RESTORECON_SKIP_SEHASH = 128;
43 
44     /**
45      * Get context associated with path by file_contexts.
46      * @param path path to the regular file to get the security context for.
47      * @return a String representing the security context or null on failure.
48      */
fileSelabelLookup(String path)49     public static final native String fileSelabelLookup(String path);
50 
51     /**
52      * Determine whether SELinux is disabled or enabled.
53      * @return a boolean indicating whether SELinux is enabled.
54      */
55     @UnsupportedAppUsage
isSELinuxEnabled()56     public static final native boolean isSELinuxEnabled();
57 
58     /**
59      * Determine whether SELinux is permissive or enforcing.
60      * @return a boolean indicating whether SELinux is enforcing.
61      */
62     @UnsupportedAppUsage
isSELinuxEnforced()63     public static final native boolean isSELinuxEnforced();
64 
65     /**
66      * Sets the security context for newly created file objects.
67      * @param context a security context given as a String.
68      * @return a boolean indicating whether the operation succeeded.
69      */
setFSCreateContext(String context)70     public static final native boolean setFSCreateContext(String context);
71 
72     /**
73      * Change the security context of an existing file object.
74      * @param path representing the path of file object to relabel.
75      * @param context new security context given as a String.
76      * @return a boolean indicating whether the operation succeeded.
77      */
setFileContext(String path, String context)78     public static final native boolean setFileContext(String path, String context);
79 
80     /**
81      * Get the security context of a file object.
82      * @param path the pathname of the file object.
83      * @return a security context given as a String.
84      */
85     @UnsupportedAppUsage
getFileContext(String path)86     public static final native String getFileContext(String path);
87 
88     /**
89      * Get the security context of a peer socket.
90      * @param fd FileDescriptor class of the peer socket.
91      * @return a String representing the peer socket security context.
92      */
getPeerContext(FileDescriptor fd)93     public static final native String getPeerContext(FileDescriptor fd);
94 
95     /**
96      * Get the security context of a file descriptor of a file.
97      * @param fd FileDescriptor of a file.
98      * @return a String representing the file descriptor security context.
99      */
getFileContext(FileDescriptor fd)100     public static final native String getFileContext(FileDescriptor fd);
101 
102     /**
103      * Gets the security context of the current process.
104      * @return a String representing the security context of the current process.
105      */
106     @UnsupportedAppUsage
getContext()107     public static final native String getContext();
108 
109     /**
110      * Gets the security context of a given process id.
111      * @param pid an int representing the process id to check.
112      * @return a String representing the security context of the given pid.
113      */
114     @UnsupportedAppUsage
getPidContext(int pid)115     public static final native String getPidContext(int pid);
116 
117     /**
118      * Check permissions between two security contexts.
119      * @param scon The source or subject security context.
120      * @param tcon The target or object security context.
121      * @param tclass The object security class name.
122      * @param perm The permission name.
123      * @return a boolean indicating whether permission was granted.
124      */
125     @UnsupportedAppUsage
checkSELinuxAccess(String scon, String tcon, String tclass, String perm)126     public static final native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm);
127 
128     /**
129      * Restores a file to its default SELinux security context.
130      * If the system is not compiled with SELinux, then {@code true}
131      * is automatically returned.
132      * If SELinux is compiled in, but disabled, then {@code true} is
133      * returned.
134      *
135      * @param pathname The pathname of the file to be relabeled.
136      * @return a boolean indicating whether the relabeling succeeded.
137      * @exception NullPointerException if the pathname is a null object.
138      */
restorecon(String pathname)139     public static boolean restorecon(String pathname) throws NullPointerException {
140         if (pathname == null) { throw new NullPointerException(); }
141         return native_restorecon(pathname, 0);
142     }
143 
144     /**
145      * Restores a file to its default SELinux security context.
146      * If the system is not compiled with SELinux, then {@code true}
147      * is automatically returned.
148      * If SELinux is compiled in, but disabled, then {@code true} is
149      * returned.
150      *
151      * @param pathname The pathname of the file to be relabeled.
152      * @return a boolean indicating whether the relabeling succeeded.
153      */
native_restorecon(String pathname, int flags)154     private static native boolean native_restorecon(String pathname, int flags);
155 
156     /**
157      * Restores a file to its default SELinux security context.
158      * If the system is not compiled with SELinux, then {@code true}
159      * is automatically returned.
160      * If SELinux is compiled in, but disabled, then {@code true} is
161      * returned.
162      *
163      * @param file The File object representing the path to be relabeled.
164      * @return a boolean indicating whether the relabeling succeeded.
165      * @exception NullPointerException if the file is a null object.
166      */
restorecon(File file)167     public static boolean restorecon(File file) throws NullPointerException {
168         try {
169             return native_restorecon(file.getCanonicalPath(), 0);
170         } catch (IOException e) {
171             Slog.e(TAG, "Error getting canonical path. Restorecon failed for " +
172                     file.getPath(), e);
173             return false;
174         }
175     }
176 
177     /**
178      * Recursively restores all files under the given path to their default
179      * SELinux security context. If the system is not compiled with SELinux,
180      * then {@code true} is automatically returned. If SELinux is compiled in,
181      * but disabled, then {@code true} is returned.
182      *
183      * @return a boolean indicating whether the relabeling succeeded.
184      */
185     @UnsupportedAppUsage
restoreconRecursive(File file)186     public static boolean restoreconRecursive(File file) {
187         try {
188             return native_restorecon(file.getCanonicalPath(),
189                 SELINUX_ANDROID_RESTORECON_RECURSE | SELINUX_ANDROID_RESTORECON_SKIP_SEHASH);
190         } catch (IOException e) {
191             Slog.e(TAG, "Error getting canonical path. Restorecon failed for " +
192                     file.getPath(), e);
193             return false;
194         }
195     }
196 }
197