Snap for 7478067 from 3457fff1f4f759f73f431137b8cf8eed1772da1f to mainline-cellbroadcast-release

Change-Id: Id1c411c41169115db9839feb83631d9943d39ed4
diff --git a/Android.bp b/Android.bp
index 22e6568..22fe8d9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,3 +1,40 @@
+package {
+    default_applicable_licenses: ["external_selinux_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'filegroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// http://go/android-license-faq
+license {
+    name: "external_selinux_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-BSD",
+        "SPDX-license-identifier-GPL",
+        "SPDX-license-identifier-GPL-2.0",
+        "SPDX-license-identifier-LGPL",
+        "SPDX-license-identifier-LGPL-2.1",
+        "SPDX-license-identifier-LGPL-3.0",
+        "SPDX-license-identifier-Zlib",
+        "legacy_unencumbered",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 subdirs = [
     "checkpolicy",
     "libselinux",
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..6d8601b
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+  license_type: RESTRICTED
+}
diff --git a/OWNERS b/OWNERS
index 215ed6a..cfada96 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,3 @@
+alanstokes@google.com
 jeffv@google.com
 jgalenson@google.com
-nnk@google.com
diff --git a/checkpolicy/Android.bp b/checkpolicy/Android.bp
index bfd91b7..0dad602 100644
--- a/checkpolicy/Android.bp
+++ b/checkpolicy/Android.bp
@@ -1,3 +1,34 @@
+package {
+    default_applicable_licenses: ["external_selinux_checkpolicy_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'filegroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// http://go/android-license-faq
+license {
+    name: "external_selinux_checkpolicy_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-GPL",
+        "SPDX-license-identifier-GPL-2.0",
+        "SPDX-license-identifier-LGPL",
+    ],
+    license_text: [
+        "COPYING",
+    ],
+}
+
 common_CFLAGS = [
     "-Wall",
     "-Werror",
diff --git a/libselinux/Android.bp b/libselinux/Android.bp
index 664e928..272a3a6 100644
--- a/libselinux/Android.bp
+++ b/libselinux/Android.bp
@@ -1,3 +1,34 @@
+package {
+    default_applicable_licenses: ["external_selinux_libselinux_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'filegroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// http://go/android-license-faq
+license {
+    name: "external_selinux_libselinux_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-GPL-2.0",
+        "legacy_unencumbered",
+    ],
+    license_text: [
+        "LICENSE",
+    ],
+}
+
 common_CFLAGS = [
     // Persistently stored patterns (pcre2) are architecture dependent.
     // In particular paterns built on amd64 can not run on devices with armv7
@@ -80,6 +111,8 @@
                 "liblog",
             ],
 
+            header_libs: ["libcutils_headers"],
+
             local_include_dirs: [ "src" ],
 
             // 1003 corresponds to auditd, from system/core/logd/event.logtags
@@ -100,6 +133,12 @@
     name: "libselinux",
     defaults: ["libselinux_defaults"],
 
+    llndk: {
+        symbol_file: "exported.map.txt",
+    },
+
+    ramdisk_available: true,
+    vendor_ramdisk_available: true,
     recovery_available: true,
 
     host_supported: true,
@@ -179,7 +218,7 @@
                 shared_libs: ["libpackagelistparser"],
             },
 
-            version_script: "exported.map",
+            version_script: "exported.map.txt",
         },
 
         vendor: {
@@ -204,17 +243,11 @@
     },
 
     stubs: {
-        symbol_file: "exported.map",
+        symbol_file: "exported.map.txt",
         versions: ["30"],
     },
 }
 
-llndk_library {
-    name: "libselinux",
-    export_include_dirs: ["include"],
-    symbol_file: "exported.map",
-}
-
 cc_binary_host {
     name: "sefcontext_compile",
     defaults: ["libselinux_defaults"],
@@ -227,3 +260,73 @@
     ],
     whole_static_libs: ["libpcre2"],
 }
+
+rust_bindgen {
+    name: "libselinux_bindgen",
+    wrapper_src: "rust/selinux.h",
+    crate_name: "selinux_bindgen",
+    source_stem: "bindings",
+    local_include_dirs: ["include"],
+
+    // Generate bindings only for the symbols that are actually exported (see exported.map.txt).
+    // This makes the generated bindings much more concise and improves compilation
+    // time.
+    bindgen_flags: [
+        "--allowlist-function=fgetfilecon",
+        "--allowlist-function=fgetfilecon_raw",
+        "--allowlist-function=freecon",
+        "--allowlist-function=fsetfilecon",
+        "--allowlist-function=getcon",
+        "--allowlist-function=getfilecon",
+        "--allowlist-function=getpeercon",
+        "--allowlist-function=getpidcon",
+        "--allowlist-function=is_selinux_enabled",
+        "--allowlist-function=lgetfilecon",
+        "--allowlist-function=lsetfilecon",
+        "--allowlist-function=security_compute_create",
+        "--allowlist-function=security_get_initial_context",
+        "--allowlist-function=security_getenforce",
+        "--allowlist-function=security_load_policy",
+        "--allowlist-function=security_policyvers",
+        "--allowlist-function=security_setenforce",
+        "--allowlist-function=selabel_close",
+        "--allowlist-function=selabel_lookup",
+        "--allowlist-function=selabel_lookup_best_match",
+        "--allowlist-function=selabel_open",
+        "--allowlist-function=selinux_android_file_context_handle",
+        "--allowlist-function=selinux_android_hw_service_context_handle",
+        "--allowlist-function=selinux_android_load_policy",
+        "--allowlist-function=selinux_android_load_policy_from_fd",
+        "--allowlist-function=selinux_android_restorecon",
+        "--allowlist-function=selinux_android_restorecon_pkgdir",
+        "--allowlist-function=selinux_android_seapp_context_init",
+        "--allowlist-function=selinux_android_service_context_handle",
+        "--allowlist-function=selinux_android_set_sehandle",
+        "--allowlist-function=selinux_android_setcon",
+        "--allowlist-function=selinux_android_setcontext",
+        "--allowlist-function=selinux_android_vendor_service_context_handle",
+        "--allowlist-function=selinux_check_access",
+        "--allowlist-function=selinux_log_callback",
+        "--allowlist-function=selinux_set_callback",
+        "--allowlist-function=selinux_status_open",
+        "--allowlist-function=selinux_status_updated",
+        "--allowlist-function=selinux_vendor_log_callback",
+        "--allowlist-function=set_selinuxmnt",
+        "--allowlist-function=setcon",
+        "--allowlist-function=setexeccon",
+        "--allowlist-function=setfilecon",
+        "--allowlist-function=setfscreatecon",
+        "--allowlist-function=setsockcreatecon",
+        "--allowlist-function=setsockcreatecon_raw",
+        "--allowlist-function=string_to_security_class",
+        "--allowlist-function=selinux_android_context_with_level",
+        "--allowlist-function=selinux_android_keystore2_key_context_handle",
+
+        // We also need some constants in addition to the functions.
+        "--allowlist-var=SELABEL_.*",
+        "--allowlist-var=SELINUX_.*",
+    ],
+
+    // This is mainly to run layout tests for generated bindings on the host.
+    host_supported: true,
+}
diff --git a/libselinux/exported.map b/libselinux/exported.map.txt
similarity index 90%
rename from libselinux/exported.map
rename to libselinux/exported.map.txt
index 89a3117..ac701ab 100644
--- a/libselinux/exported.map
+++ b/libselinux/exported.map.txt
@@ -49,3 +49,8 @@
     string_to_security_class;
   local: *;
 };
+
+LIBSELINUX_S { # introduced=S
+    selinux_android_context_with_level;
+    selinux_android_keystore2_key_context_handle;
+};
diff --git a/libselinux/exported_vendor.map b/libselinux/exported_vendor.map
index ccd5fef..3b30373 100644
--- a/libselinux/exported_vendor.map
+++ b/libselinux/exported_vendor.map
@@ -17,6 +17,7 @@
     selinux_android_service_context_handle;
     selinux_android_hw_service_context_handle;
     selinux_android_vendor_service_context_handle;
+    selinux_android_keystore2_key_context_handle;
     selinux_check_access;
     security_getenforce;
     security_setenforce;
diff --git a/libselinux/fuzzers/Android.bp b/libselinux/fuzzers/Android.bp
new file mode 100644
index 0000000..ea3f9b2
--- /dev/null
+++ b/libselinux/fuzzers/Android.bp
@@ -0,0 +1,96 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "external_selinux_libselinux_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["external_selinux_libselinux_license"],
+}
+
+cc_defaults {
+    name: "libselinux_fuzzer_defaults",
+    cflags: [
+        "-Wall",
+    ],
+    static_libs: [
+        "liblog",
+        "libselinux",
+    ],
+}
+
+cc_fuzz {
+    name: "libselinux_android_setcontext_fuzzer",
+    defaults: ["libselinux_fuzzer_defaults"],
+    srcs: ["AndroidSetcontextFuzzer.cpp"],
+}
+
+cc_fuzz {
+    name: "libselinux_context_fuzzer",
+    defaults: ["libselinux_fuzzer_defaults"],
+    srcs: ["ContextFuzzer.cpp"],
+    host_supported: true,
+}
+
+cc_fuzz {
+    name: "libselinux_selabel_lookup_fuzzer",
+    defaults: ["libselinux_fuzzer_defaults"],
+    srcs: ["selabel_lookup_fuzzer.cpp"],
+    dictionary: "selabel_lookup_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "libselinux_selinux_check_access_fuzzer",
+    defaults: ["libselinux_fuzzer_defaults"],
+    srcs: ["selinux_check_access_fuzzer.cpp"],
+    dictionary: "selinux_check_access_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "libselinux_selinux_android_restorecon_fuzzer",
+    defaults: ["libselinux_fuzzer_defaults"],
+    srcs: ["selinux_android_restorecon_fuzzer.cpp"],
+    dictionary: "selinux_android_restorecon_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "libselinux_selinux_android_setcon_fuzzer",
+    defaults: ["libselinux_fuzzer_defaults"],
+    srcs: ["selinux_android_setcon_fuzzer.cpp"],
+    dictionary: "selinux_android_setcon_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "libselinux_setfilecon_fuzzer",
+    defaults: ["libselinux_fuzzer_defaults"],
+    srcs: ["setfilecon_fuzzer.cpp"],
+    dictionary: "setfilecon_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "libselinux_lsetfilecon_fuzzer",
+    defaults: ["libselinux_fuzzer_defaults"],
+    srcs: ["lsetfilecon_fuzzer.cpp"],
+    dictionary: "lsetfilecon_fuzzer.dict",
+}
+
+cc_fuzz {
+    name: "libselinux_string_to_security_class_fuzzer",
+    defaults: ["libselinux_fuzzer_defaults"],
+    srcs: ["string_to_security_class_fuzzer.cpp"],
+    dictionary: "string_to_security_class_fuzzer.dict",
+}
diff --git a/libselinux/fuzzers/AndroidSetcontextFuzzer.cpp b/libselinux/fuzzers/AndroidSetcontextFuzzer.cpp
new file mode 100644
index 0000000..995b0d9
--- /dev/null
+++ b/libselinux/fuzzers/AndroidSetcontextFuzzer.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string>
+
+#include <selinux/android.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  FuzzedDataProvider fdp(data, size);
+  uid_t uid = fdp.ConsumeIntegral<int>();
+  bool isSystemServer = fdp.ConsumeBool();
+  std::string pkgname = fdp.ConsumeRandomLengthString();
+  std::string seinfo = fdp.ConsumeRemainingBytesAsString();
+
+  selinux_android_setcontext(uid, isSystemServer, seinfo.c_str(), pkgname.c_str());
+
+  return 0;
+}
diff --git a/libselinux/fuzzers/ContextFuzzer.cpp b/libselinux/fuzzers/ContextFuzzer.cpp
new file mode 100644
index 0000000..f7aed65
--- /dev/null
+++ b/libselinux/fuzzers/ContextFuzzer.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string>
+
+#include <selinux/context.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, [[maybe_unused]] size_t size) {
+  FuzzedDataProvider fdp(data, size);
+  std::string contextName = fdp.ConsumeRemainingBytesAsString();
+
+  context_t context = context_new(contextName.c_str());
+  // According to docs, this should be safe to call with null pointer
+  // (meaning even if previous call fails).
+  context_free(context);
+
+  return 0;
+}
diff --git a/libselinux/fuzzers/lsetfilecon_fuzzer.cpp b/libselinux/fuzzers/lsetfilecon_fuzzer.cpp
new file mode 100644
index 0000000..b5303e5
--- /dev/null
+++ b/libselinux/fuzzers/lsetfilecon_fuzzer.cpp
@@ -0,0 +1,33 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <selinux/selinux.h>
+#include <string>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  FuzzedDataProvider fdp(data, size);
+
+  std::string path = fdp.ConsumeRandomLengthString();
+  std::string con = fdp.ConsumeRemainingBytesAsString();
+
+  lsetfilecon(path.c_str(), con.c_str());
+
+  return 0;
+}
diff --git a/libselinux/fuzzers/lsetfilecon_fuzzer.dict b/libselinux/fuzzers/lsetfilecon_fuzzer.dict
new file mode 100644
index 0000000..778b557
--- /dev/null
+++ b/libselinux/fuzzers/lsetfilecon_fuzzer.dict
@@ -0,0 +1,15 @@
+# A few paths from frameworks/native.
+
+path="/data/app/com.example/dir/dir/file"
+path="/data/user/0/com.example/secondary.dex"
+path="/dev/socket/pdx"
+path="/proc/net/xt_qtaguid/iface_stat_all"
+path="/sys/devices/system/cpu/cpufreq"
+path="/vendor/bin/hw/android.hardware.media.omx@1.0-service"
+
+# Random contexts from AOSP.
+
+con="u:r:system_server:s0"
+con="u:r:adbd:s0"
+con="u:r:shell:s0"
+con="u:r:adbd:s0"
diff --git a/libselinux/fuzzers/selabel_lookup_fuzzer.cpp b/libselinux/fuzzers/selabel_lookup_fuzzer.cpp
new file mode 100644
index 0000000..38e44f5
--- /dev/null
+++ b/libselinux/fuzzers/selabel_lookup_fuzzer.cpp
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <stdint.h>
+#include <selinux/android.h>
+#include <string>
+
+selabel_handle *GetHandle(FuzzedDataProvider &fdp) {
+  switch (fdp.ConsumeIntegralInRange(0, 4)) {
+  case 0: return selinux_android_file_context_handle();
+  case 1: return selinux_android_service_context_handle();
+  case 2: return selinux_android_hw_service_context_handle();
+  case 3: return selinux_android_vendor_service_context_handle();
+  case 4: return selinux_android_keystore2_key_context_handle();
+  default: return selinux_android_file_context_handle();
+  }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  FuzzedDataProvider fdp(data, size);
+
+  std::string str = fdp.ConsumeRandomLengthString();
+  static auto handle = GetHandle(fdp);
+  char *conn = NULL;
+  int type = fdp.ConsumeIntegral<int>();
+
+  selabel_lookup(handle, &conn, str.data(), type);
+
+  return 0;
+}
diff --git a/libselinux/fuzzers/selabel_lookup_fuzzer.dict b/libselinux/fuzzers/selabel_lookup_fuzzer.dict
new file mode 100644
index 0000000..60b34ad
--- /dev/null
+++ b/libselinux/fuzzers/selabel_lookup_fuzzer.dict
@@ -0,0 +1,8 @@
+# A few paths from frameworks/native.
+
+"/data/app/com.example/dir/dir/file"
+"/data/user/0/com.example/secondary.dex"
+"/dev/socket/pdx"
+"/proc/net/xt_qtaguid/iface_stat_all"
+"/sys/devices/system/cpu/cpufreq"
+"/vendor/bin/hw/android.hardware.media.omx@1.0-service"
diff --git a/libselinux/fuzzers/selinux_android_restorecon_fuzzer.cpp b/libselinux/fuzzers/selinux_android_restorecon_fuzzer.cpp
new file mode 100644
index 0000000..962abf1
--- /dev/null
+++ b/libselinux/fuzzers/selinux_android_restorecon_fuzzer.cpp
@@ -0,0 +1,66 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <selinux/android.h>
+#include <string>
+
+unsigned int GetFlags(FuzzedDataProvider &fdp) {
+  unsigned int flags = 0;
+  if (fdp.ConsumeBool()) {
+    flags |= SELINUX_ANDROID_RESTORECON_NOCHANGE;
+  }
+  if (fdp.ConsumeBool()) {
+    flags |= SELINUX_ANDROID_RESTORECON_VERBOSE;
+  }
+  if (fdp.ConsumeBool()) {
+    flags |= SELINUX_ANDROID_RESTORECON_RECURSE;
+  }
+  if (fdp.ConsumeBool()) {
+    flags |= SELINUX_ANDROID_RESTORECON_FORCE;
+  }
+  if (fdp.ConsumeBool()) {
+    flags |= SELINUX_ANDROID_RESTORECON_DATADATA;
+  }
+  if (fdp.ConsumeBool()) {
+    flags |= SELINUX_ANDROID_RESTORECON_SKIPCE;
+  }
+  if (fdp.ConsumeBool()) {
+    flags |= SELINUX_ANDROID_RESTORECON_CROSS_FILESYSTEMS;
+  }
+  if (fdp.ConsumeBool()) {
+    flags |= SELINUX_ANDROID_RESTORECON_SKIP_SEHASH;
+  }
+  // Try adding random noise (which likely isn't a real flag).
+  if (fdp.ConsumeBool()) {
+    flags |= fdp.ConsumeIntegral<unsigned int>();
+  }
+  return flags;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  FuzzedDataProvider fdp(data, size);
+
+  std::string file = fdp.ConsumeRandomLengthString();
+  unsigned int flags = GetFlags(fdp);
+
+  selinux_android_restorecon(file.c_str(), flags);
+
+  return 0;
+}
diff --git a/libselinux/fuzzers/selinux_android_restorecon_fuzzer.dict b/libselinux/fuzzers/selinux_android_restorecon_fuzzer.dict
new file mode 100644
index 0000000..6428993
--- /dev/null
+++ b/libselinux/fuzzers/selinux_android_restorecon_fuzzer.dict
@@ -0,0 +1,16 @@
+# A few paths from frameworks/native.
+
+"/data/app/com.example/dir/dir/file"
+"/data/user/0/com.example/secondary.dex"
+"/dev/socket/pdx"
+"/proc/net/xt_qtaguid/iface_stat_all"
+"/sys/devices/system/cpu/cpufreq"
+"/vendor/bin/hw/android.hardware.media.omx@1.0-service"
+
+# A few paths from system/core/init/selinux.cpp.
+
+"/dev"
+"/dev/kmsg"
+"/apex"
+"/linkerconfig"
+"/metadata/gsi"
diff --git a/libselinux/fuzzers/selinux_android_setcon_fuzzer.cpp b/libselinux/fuzzers/selinux_android_setcon_fuzzer.cpp
new file mode 100644
index 0000000..28d637f
--- /dev/null
+++ b/libselinux/fuzzers/selinux_android_setcon_fuzzer.cpp
@@ -0,0 +1,32 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <selinux/android.h>
+#include <string>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  FuzzedDataProvider fdp(data, size);
+
+  std::string con = fdp.ConsumeRemainingBytesAsString();
+
+  selinux_android_setcon(con.c_str());
+
+  return 0;
+}
diff --git a/libselinux/fuzzers/selinux_android_setcon_fuzzer.dict b/libselinux/fuzzers/selinux_android_setcon_fuzzer.dict
new file mode 100644
index 0000000..1e286d6
--- /dev/null
+++ b/libselinux/fuzzers/selinux_android_setcon_fuzzer.dict
@@ -0,0 +1,5 @@
+# Random contexts from AOSP.
+"u:r:system_server:s0"
+"u:r:adbd:s0"
+"u:r:shell:s0"
+"u:r:adbd:s0"
diff --git a/libselinux/fuzzers/selinux_check_access_fuzzer.cpp b/libselinux/fuzzers/selinux_check_access_fuzzer.cpp
new file mode 100644
index 0000000..60595d8
--- /dev/null
+++ b/libselinux/fuzzers/selinux_check_access_fuzzer.cpp
@@ -0,0 +1,64 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <selinux/selinux.h>
+#include <string>
+
+std::string GetClass(FuzzedDataProvider &fdp) {
+  switch (fdp.ConsumeIntegralInRange(0, 9)) {
+  case 0: return "filesystem";
+  case 1: return "dir";
+  case 2: return "file";
+  case 3: return "lnk_file";
+  case 4: return "chr_file";
+  case 5: return "blk_file";
+  case 6: return "sock_file";
+  case 7: return "fifo_file";
+  case 8: return "fd";
+  default: return fdp.ConsumeRandomLengthString();
+  }
+}
+
+// This is not an exhaustive list.
+std::string GetPermission(FuzzedDataProvider &fdp) {
+  switch (fdp.ConsumeIntegralInRange(0, 7)) {
+  case 0: return "create";
+  case 1: return "execute";
+  case 2: return "getattr";
+  case 3: return "ioctl";
+  case 4: return "read";
+  case 5: return "setattr";
+  case 6: return "write";
+  default: return fdp.ConsumeRandomLengthString();
+  }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  FuzzedDataProvider fdp(data, size);
+
+  std::string tclass = GetClass(fdp);
+  std::string perm = GetPermission(fdp);
+  std::string scon = fdp.ConsumeRandomLengthString();
+  std::string tcon = fdp.ConsumeRandomLengthString();
+
+  selinux_check_access(scon.data(), tcon.data(), tclass.data(), perm.data(), NULL);
+
+  return 0;
+}
diff --git a/libselinux/fuzzers/selinux_check_access_fuzzer.dict b/libselinux/fuzzers/selinux_check_access_fuzzer.dict
new file mode 100644
index 0000000..f0b01ed
--- /dev/null
+++ b/libselinux/fuzzers/selinux_check_access_fuzzer.dict
@@ -0,0 +1,2 @@
+scon="u:r:shell:s0"
+tcon="u:object_r:metadata_file:s0"
diff --git a/libselinux/fuzzers/setfilecon_fuzzer.cpp b/libselinux/fuzzers/setfilecon_fuzzer.cpp
new file mode 100644
index 0000000..790bcf6
--- /dev/null
+++ b/libselinux/fuzzers/setfilecon_fuzzer.cpp
@@ -0,0 +1,33 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <selinux/selinux.h>
+#include <string>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  FuzzedDataProvider fdp(data, size);
+
+  std::string path = fdp.ConsumeRandomLengthString();
+  std::string con = fdp.ConsumeRemainingBytesAsString();
+
+  setfilecon(path.c_str(), con.c_str());
+
+  return 0;
+}
diff --git a/libselinux/fuzzers/setfilecon_fuzzer.dict b/libselinux/fuzzers/setfilecon_fuzzer.dict
new file mode 100644
index 0000000..778b557
--- /dev/null
+++ b/libselinux/fuzzers/setfilecon_fuzzer.dict
@@ -0,0 +1,15 @@
+# A few paths from frameworks/native.
+
+path="/data/app/com.example/dir/dir/file"
+path="/data/user/0/com.example/secondary.dex"
+path="/dev/socket/pdx"
+path="/proc/net/xt_qtaguid/iface_stat_all"
+path="/sys/devices/system/cpu/cpufreq"
+path="/vendor/bin/hw/android.hardware.media.omx@1.0-service"
+
+# Random contexts from AOSP.
+
+con="u:r:system_server:s0"
+con="u:r:adbd:s0"
+con="u:r:shell:s0"
+con="u:r:adbd:s0"
diff --git a/libselinux/fuzzers/string_to_security_class_fuzzer.cpp b/libselinux/fuzzers/string_to_security_class_fuzzer.cpp
new file mode 100644
index 0000000..d264bf8
--- /dev/null
+++ b/libselinux/fuzzers/string_to_security_class_fuzzer.cpp
@@ -0,0 +1,32 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <selinux/selinux.h>
+#include <string>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  FuzzedDataProvider fdp(data, size);
+
+  std::string name = fdp.ConsumeRemainingBytesAsString();
+
+  string_to_security_class(name.c_str());
+
+  return 0;
+}
diff --git a/libselinux/fuzzers/string_to_security_class_fuzzer.dict b/libselinux/fuzzers/string_to_security_class_fuzzer.dict
new file mode 100644
index 0000000..86aeb76
--- /dev/null
+++ b/libselinux/fuzzers/string_to_security_class_fuzzer.dict
@@ -0,0 +1,7 @@
+"file"
+"dir"
+"chr_file"
+"blk_file"
+"fifo_file"
+"lnk_file"
+"sock_file"
diff --git a/libselinux/include/selinux/android.h b/libselinux/include/selinux/android.h
index 3d1816d..6081324 100644
--- a/libselinux/include/selinux/android.h
+++ b/libselinux/include/selinux/android.h
@@ -19,6 +19,8 @@
 
 extern struct selabel_handle* selinux_android_vendor_service_context_handle(void);
 
+extern struct selabel_handle* selinux_android_keystore2_key_context_handle(void);
+
 extern void selinux_android_set_sehandle(const struct selabel_handle *hndl);
 
 extern int selinux_android_load_policy(void);
@@ -32,6 +34,11 @@
 				      const char *seinfo,
 				      const char *name);
 
+extern int selinux_android_context_with_level(const char * context,
+					      char ** newContext,
+					      uid_t userid,
+					      uid_t appid);
+
 extern int selinux_log_callback(int type, const char *fmt, ...)
     __attribute__ ((format(printf, 2, 3)));
 
diff --git a/libselinux/include/selinux/label.h b/libselinux/include/selinux/label.h
index e898360..95e9a9b 100644
--- a/libselinux/include/selinux/label.h
+++ b/libselinux/include/selinux/label.h
@@ -37,6 +37,8 @@
 #define SELABEL_CTX_ANDROID_PROP 4
 /* Android service contexts */
 #define SELABEL_CTX_ANDROID_SERVICE 5
+/* Android keystore key contexts */
+#define SELABEL_CTX_ANDROID_KEYSTORE2_KEY 6
 
 /*
  * Available options
diff --git a/libselinux/rust/selinux.h b/libselinux/rust/selinux.h
new file mode 100644
index 0000000..706f12f
--- /dev/null
+++ b/libselinux/rust/selinux.h
@@ -0,0 +1,4 @@
+#pragma once
+
+#include <selinux/android.h>
+#include <selinux/avc.h>
diff --git a/libselinux/src/android/android.c b/libselinux/src/android/android.c
index 2e70ceb..8787708 100644
--- a/libselinux/src/android/android.c
+++ b/libselinux/src/android/android.c
@@ -60,6 +60,23 @@
 static const struct selinux_opt seopts_vndservice_rootfs =
     { SELABEL_OPT_PATH, "/vndservice_contexts" };
 
+static const struct selinux_opt seopts_keystore2_key_plat[] = {
+    { SELABEL_OPT_PATH, "/system/etc/selinux/plat_keystore2_key_contexts" },
+    { SELABEL_OPT_PATH, "/plat_keystore2_key_contexts" }
+};
+static const struct selinux_opt seopts_keystore2_key_system_ext[] = {
+    { SELABEL_OPT_PATH, "/system_ext/etc/selinux/system_ext_keystore2_key_contexts" },
+    { SELABEL_OPT_PATH, "/system_ext_keystore2_key_contexts" }
+};
+static const struct selinux_opt seopts_keystore2_key_product[] = {
+    { SELABEL_OPT_PATH, "/product/etc/selinux/product_keystore2_key_contexts" },
+    { SELABEL_OPT_PATH, "/product_keystore2_key_contexts" }
+};
+static const struct selinux_opt seopts_keystore2_key_vendor[] = {
+    { SELABEL_OPT_PATH, "/vendor/etc/selinux/vendor_keystore2_key_contexts" },
+    { SELABEL_OPT_PATH, "/vendor_keystore2_key_contexts" },
+};
+
 struct selabel_handle* selinux_android_service_open_context_handle(const struct selinux_opt* seopts_service,
                                                                    unsigned nopts)
 {
@@ -80,6 +97,26 @@
     return sehandle;
 }
 
+struct selabel_handle* selinux_android_keystore2_key_open_context_handle(const struct selinux_opt* seopts_service,
+                                                                   unsigned nopts)
+{
+    struct selabel_handle* sehandle;
+
+    sehandle = selabel_open(SELABEL_CTX_ANDROID_KEYSTORE2_KEY,
+            seopts_service, nopts);
+
+    if (!sehandle) {
+        selinux_log(SELINUX_ERROR, "%s: Error getting keystore key context handle (%s)\n",
+                __FUNCTION__, strerror(errno));
+        return NULL;
+    }
+    selinux_log(SELINUX_INFO, "SELinux: Loaded keystore2_key_contexts from:\n");
+    for (unsigned i = 0; i < nopts; i++) {
+        selinux_log(SELINUX_INFO, "    %s\n", seopts_service[i].value);
+    }
+    return sehandle;
+}
+
 struct selabel_handle* selinux_android_service_context_handle(void)
 {
     struct selinux_opt seopts_service[MAX_FILE_CONTEXT_SIZE];
@@ -163,6 +200,39 @@
     return selinux_android_service_open_context_handle(seopts_service, 1);
 }
 
+struct selabel_handle* selinux_android_keystore2_key_context_handle(void)
+{
+    struct selinux_opt seopts_keystore2_key[MAX_FILE_CONTEXT_SIZE];
+    int size = 0;
+    unsigned int i;
+    for (i = 0; i < ARRAY_SIZE(seopts_keystore2_key_plat); i++) {
+        if (access(seopts_keystore2_key_plat[i].value, R_OK) != -1) {
+            seopts_keystore2_key[size++] = seopts_keystore2_key_plat[i];
+            break;
+        }
+    }
+    for (i = 0; i < ARRAY_SIZE(seopts_keystore2_key_system_ext); i++) {
+        if (access(seopts_keystore2_key_system_ext[i].value, R_OK) != -1) {
+            seopts_keystore2_key[size++] = seopts_keystore2_key_system_ext[i];
+            break;
+        }
+    }
+    for (i = 0; i < ARRAY_SIZE(seopts_keystore2_key_product); i++) {
+        if (access(seopts_keystore2_key_product[i].value, R_OK) != -1) {
+            seopts_keystore2_key[size++] = seopts_keystore2_key_product[i];
+            break;
+        }
+    }
+    for (i = 0; i < ARRAY_SIZE(seopts_keystore2_key_vendor); i++) {
+        if (access(seopts_keystore2_key_vendor[i].value, R_OK) != -1) {
+            seopts_keystore2_key[size++] = seopts_keystore2_key_vendor[i];
+            break;
+        }
+    }
+
+    return selinux_android_keystore2_key_open_context_handle(seopts_keystore2_key, size);
+}
+
 int selinux_log_callback(int type, const char *fmt, ...)
 {
     va_list ap;
diff --git a/libselinux/src/android/android_platform.c b/libselinux/src/android/android_platform.c
index 20bb4a9..2e52c15 100644
--- a/libselinux/src/android/android_platform.c
+++ b/libselinux/src/android/android_platform.c
@@ -760,6 +760,39 @@
 	return 0;
 }
 
+static int set_range_from_level(context_t ctx, enum levelFrom levelFrom, uid_t userid, uid_t appid)
+{
+	char level[255];
+	switch (levelFrom) {
+	case LEVELFROM_NONE:
+        	strlcpy(level, "s0", sizeof level);
+		break;
+	case LEVELFROM_APP:
+		snprintf(level, sizeof level, "s0:c%u,c%u",
+			 appid & 0xff,
+			 256 + (appid>>8 & 0xff));
+		break;
+	case LEVELFROM_USER:
+		snprintf(level, sizeof level, "s0:c%u,c%u",
+			 512 + (userid & 0xff),
+			 768 + (userid>>8 & 0xff));
+		break;
+	case LEVELFROM_ALL:
+		snprintf(level, sizeof level, "s0:c%u,c%u,c%u,c%u",
+			 appid & 0xff,
+			 256 + (appid>>8 & 0xff),
+			 512 + (userid & 0xff),
+			 768 + (userid>>8 & 0xff));
+		break;
+	default:
+		return -1;
+	}
+	if (context_range_set(ctx, level)) {
+		return -2;
+	}
+	return 0;
+}
+
 static int seapp_context_lookup(enum seapp_kind kind,
 				uid_t uid,
 				bool isSystemServer,
@@ -903,30 +936,10 @@
 		}
 
 		if (cur->levelFrom != LEVELFROM_NONE) {
-			char level[255];
-			switch (cur->levelFrom) {
-			case LEVELFROM_APP:
-				snprintf(level, sizeof level, "s0:c%u,c%u",
-					 appid & 0xff,
-					 256 + (appid>>8 & 0xff));
-				break;
-			case LEVELFROM_USER:
-				snprintf(level, sizeof level, "s0:c%u,c%u",
-					 512 + (userid & 0xff),
-					 768 + (userid>>8 & 0xff));
-				break;
-			case LEVELFROM_ALL:
-				snprintf(level, sizeof level, "s0:c%u,c%u,c%u,c%u",
-					 appid & 0xff,
-					 256 + (appid>>8 & 0xff),
-					 512 + (userid & 0xff),
-					 768 + (userid>>8 & 0xff));
-				break;
-			default:
-				goto err;
+			int res = set_range_from_level(ctx, cur->levelFrom, userid, appid);
+			if (res != 0) {
+				return res;
 			}
-			if (context_range_set(ctx, level))
-				goto oom;
 		} else if (cur->level) {
 			if (context_range_set(ctx, cur->level))
 				goto oom;
@@ -955,6 +968,49 @@
 	return -2;
 }
 
+int selinux_android_context_with_level(const char * context,
+				       char ** newContext,
+				       uid_t userid,
+				       uid_t appid)
+{
+	int rc = -2;
+
+	enum levelFrom levelFrom;
+	if (userid == (uid_t) -1) {
+		levelFrom = (appid == (uid_t) -1) ? LEVELFROM_NONE : LEVELFROM_APP;
+	} else {
+		levelFrom = (appid == (uid_t) -1) ? LEVELFROM_USER : LEVELFROM_ALL;
+	}
+
+	context_t ctx = context_new(context);
+	if (!ctx) {
+		goto out;
+	}
+
+	int res = set_range_from_level(ctx, levelFrom, userid, appid);
+	if (res != 0) {
+		rc = res;
+		goto out;
+	}
+
+	char * newString = context_str(ctx);
+	if (!newString) {
+		goto out;
+	}
+
+	char * newCopied = strdup(newString);
+	if (!newCopied) {
+		goto out;
+	}
+
+	*newContext = newCopied;
+	rc = 0;
+
+out:
+	context_free(ctx);
+	return rc;
+}
+
 int selinux_android_setcon(const char *con)
 {
 	int ret = setcon(con);
@@ -1123,9 +1179,9 @@
  * credentials are presented (filenames inside are mangled), so we need
  * to delay restorecon of those until vold explicitly requests it. */
 // NOTE: these paths need to be kept in sync with vold
-#define DATA_SYSTEM_CE_PREFIX "/data/system_ce/"
-#define DATA_VENDOR_CE_PREFIX "/data/vendor_ce/"
-#define DATA_MISC_CE_PREFIX "/data/misc_ce/"
+#define DATA_SYSTEM_CE_PREFIX "/data/system_ce"
+#define DATA_VENDOR_CE_PREFIX "/data/vendor_ce"
+#define DATA_MISC_CE_PREFIX "/data/misc_ce"
 
 /* The path prefixes of package data directories. */
 #define DATA_DATA_PATH "/data/data"
@@ -1133,6 +1189,7 @@
 #define DATA_USER_DE_PATH "/data/user_de"
 #define EXPAND_USER_PATH "/mnt/expand/\?\?\?\?\?\?\?\?-\?\?\?\?-\?\?\?\?-\?\?\?\?-\?\?\?\?\?\?\?\?\?\?\?\?/user"
 #define EXPAND_USER_DE_PATH "/mnt/expand/\?\?\?\?\?\?\?\?-\?\?\?\?-\?\?\?\?-\?\?\?\?-\?\?\?\?\?\?\?\?\?\?\?\?/user_de"
+#define USER_PROFILE_PATH "/data/misc/profiles/cur/*"
 #define DATA_DATA_PREFIX DATA_DATA_PATH "/"
 #define DATA_USER_PREFIX DATA_USER_PATH "/"
 #define DATA_USER_DE_PREFIX DATA_USER_DE_PATH "/"
@@ -1492,6 +1549,11 @@
                 continue;
             }
 
+            if (!datadata && !fnmatch(USER_PROFILE_PATH, ftsent->fts_path, FNM_PATHNAME)) {
+                // Don't label this directory, vold takes care of that, but continue below it.
+                continue;
+            }
+
             if (setrestoreconlast) {
                 struct dir_hash_node* new_node = NULL;
                 if (check_context_match_for_dir(ftsent->fts_path, &new_node, force, error)) {
diff --git a/libselinux/src/label.c b/libselinux/src/label.c
index eac6e36..e0ed68d 100644
--- a/libselinux/src/label.c
+++ b/libselinux/src/label.c
@@ -57,7 +57,8 @@
 	CONFIG_X_BACKEND(selabel_x_init),
 	CONFIG_DB_BACKEND(selabel_db_init),
 	CONFIG_ANDROID_BACKEND(selabel_property_init),
-	CONFIG_ANDROID_BACKEND(selabel_service_init),
+	CONFIG_ANDROID_BACKEND(selabel_exact_match_init),//service init
+	CONFIG_ANDROID_BACKEND(selabel_exact_match_init),//keyStore key init
 };
 
 static inline struct selabel_digest *selabel_is_digest_set
diff --git a/libselinux/src/label_backends_android.c b/libselinux/src/label_backends_android.c
index eaca594..d81faab 100644
--- a/libselinux/src/label_backends_android.c
+++ b/libselinux/src/label_backends_android.c
@@ -327,7 +327,7 @@
 	return ret;
 }
 
-static struct selabel_lookup_rec *service_lookup(struct selabel_handle *rec,
+static struct selabel_lookup_rec *lookup_exact_match(struct selabel_handle *rec,
 		const char *key, int __attribute__((unused)) type)
 {
 	struct saved_data *data = (struct saved_data *)rec->data;
@@ -382,7 +382,7 @@
 	return init(rec, opts, nopts);
 }
 
-int selabel_service_init(struct selabel_handle *rec,
+int selabel_exact_match_init(struct selabel_handle *rec,
 		const struct selinux_opt *opts, unsigned nopts)
 {
 	struct saved_data *data;
@@ -394,7 +394,7 @@
 	rec->data = data;
 	rec->func_close = &closef;
 	rec->func_stats = &stats;
-	rec->func_lookup = &service_lookup;
+	rec->func_lookup = &lookup_exact_match;
 
 	return init(rec, opts, nopts);
 }
diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_internal.h
index 74bf9e0..95f9a14 100644
--- a/libselinux/src/label_internal.h
+++ b/libselinux/src/label_internal.h
@@ -39,7 +39,7 @@
 int selabel_property_init(struct selabel_handle *rec,
 			    const struct selinux_opt *opts,
 			    unsigned nopts) hidden;
-int selabel_service_init(struct selabel_handle *rec,
+int selabel_exact_match_init(struct selabel_handle *rec,
 			    const struct selinux_opt *opts,
 			    unsigned nopts) hidden;
 
diff --git a/libselinux/utils/selabel_lookup.c b/libselinux/utils/selabel_lookup.c
index 1aef64d..b18e5fc 100644
--- a/libselinux/utils/selabel_lookup.c
+++ b/libselinux/utils/selabel_lookup.c
@@ -59,6 +59,8 @@
 				backend = SELABEL_CTX_ANDROID_PROP;
 			} else if (!strcmp(optarg, "service")) {
 				backend = SELABEL_CTX_ANDROID_SERVICE;
+			} else if (!strcmp(optarg, "keystore2_key")) {
+				backend = SELABEL_CTX_ANDROID_KEYSTORE2_KEY;
 			} else {
 				fprintf(stderr, "Unknown backend: %s\n",
 								    optarg);
diff --git a/libsepol/Android.bp b/libsepol/Android.bp
index 0f63ee3..9c56fc4 100644
--- a/libsepol/Android.bp
+++ b/libsepol/Android.bp
@@ -1,3 +1,38 @@
+package {
+    default_applicable_licenses: ["external_selinux_libsepol_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'filegroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// http://go/android-license-faq
+license {
+    name: "external_selinux_libsepol_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-BSD",
+        "SPDX-license-identifier-GPL",
+        "SPDX-license-identifier-LGPL",
+        "SPDX-license-identifier-LGPL-2.1",
+        "SPDX-license-identifier-LGPL-3.0",
+        "SPDX-license-identifier-Zlib",
+        "legacy_unencumbered",
+    ],
+    license_text: [
+        "COPYING",
+    ],
+}
+
 common_CFLAGS = [
     "-D_GNU_SOURCE",
     "-Wall",
diff --git a/secilc/Android.bp b/secilc/Android.bp
index 597058b..f7a11b4 100644
--- a/secilc/Android.bp
+++ b/secilc/Android.bp
@@ -1,3 +1,20 @@
+package {
+    default_applicable_licenses: ["external_selinux_secilc_license"],
+}
+
+// Added automatically by a large-scale-change
+// http://go/android-license-faq
+license {
+    name: "external_selinux_secilc_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-BSD",
+    ],
+    license_text: [
+        "COPYING",
+    ],
+}
+
 common_CFLAGS = [
     "-Wall",
     "-Werror",
diff --git a/secilc/secilc.c b/secilc/secilc.c
index 186c5a7..9c78e42 100644
--- a/secilc/secilc.c
+++ b/secilc/secilc.c
@@ -268,6 +268,12 @@
 		}
 		file_size = filedata.st_size;
 
+		if (!file_size) {
+			fclose(file);
+			file = NULL;
+			continue;
+		}
+
 		buffer = malloc(file_size);
 		rc = fread(buffer, file_size, 1, file);
 		if (rc != 1) {