Revert "ANDROID: GKI: Add script to generate symbol protection headers"
Bug: 393366754 Change-Id: Ie426f398ff76c1221afc87de68f9ecdb71f15eb7 Signed-off-by: Sid Nayyar <sidnayyar@google.com>
This commit is contained in:
2
kernel/.gitignore
vendored
2
kernel/.gitignore
vendored
@@ -1,5 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
/config_data
|
||||
/kheaders.md5
|
||||
/gki_module_exported.h
|
||||
/gki_module_protected.h
|
||||
|
||||
@@ -286,19 +286,6 @@ config MODULE_SIG_FORCE
|
||||
Reject unsigned modules or signed modules for which we don't have a
|
||||
key. Without this, such modules will simply taint the kernel.
|
||||
|
||||
config MODULE_SIG_PROTECT
|
||||
bool "Android GKI module protection"
|
||||
depends on MODULE_SIG && !MODULE_SIG_FORCE
|
||||
help
|
||||
Enables Android GKI symbol and export protection support.
|
||||
|
||||
This modifies the behavior of the MODULE_SIG_FORCE as follows:
|
||||
- Allows Android GKI Modules signed using MODULE_SIG_ALL during build.
|
||||
- Allows other modules to load if they don't violate the access to
|
||||
Android GKI protected symbols and do not export the symbols already
|
||||
exported by the Android GKI modules. Loading will fail and return
|
||||
-EACCES (Permission denied) if symbol access conditions are not met.
|
||||
|
||||
config MODULE_SIG_ALL
|
||||
bool "Automatically sign all modules"
|
||||
default y
|
||||
|
||||
@@ -13,7 +13,6 @@ obj-y += kmod.o
|
||||
obj-$(CONFIG_MODULE_DEBUG_AUTOLOAD_DUPS) += dups.o
|
||||
obj-$(CONFIG_MODULE_DECOMPRESS) += decompress.o
|
||||
obj-$(CONFIG_MODULE_SIG) += signing.o
|
||||
obj-$(CONFIG_MODULE_SIG_PROTECT) += gki_module.o
|
||||
obj-$(CONFIG_LIVEPATCH) += livepatch.o
|
||||
obj-$(CONFIG_MODULES_TREE_LOOKUP) += tree_lookup.o
|
||||
obj-$(CONFIG_DEBUG_KMEMLEAK) += debug_kmemleak.o
|
||||
@@ -24,36 +23,3 @@ obj-$(CONFIG_KGDB_KDB) += kdb.o
|
||||
obj-$(CONFIG_MODVERSIONS) += version.o
|
||||
obj-$(CONFIG_MODULE_UNLOAD_TAINT_TRACKING) += tracking.o
|
||||
obj-$(CONFIG_MODULE_STATS) += stats.o
|
||||
|
||||
#
|
||||
# ANDROID: GKI: Generate headerfiles required for gki_module.o
|
||||
#
|
||||
# Dependencies on generated files need to be listed explicitly
|
||||
$(obj)/gki_module.o: include/generated/gki_module_protected_exports.h \
|
||||
include/generated/gki_module_unprotected.h
|
||||
|
||||
ifneq ($(CONFIG_UNUSED_KSYMS_WHITELIST),)
|
||||
ALL_KMI_SYMBOLS := $(CONFIG_UNUSED_KSYMS_WHITELIST)
|
||||
else
|
||||
ALL_KMI_SYMBOLS := include/config/abi_gki_kmi_symbols
|
||||
$(ALL_KMI_SYMBOLS):
|
||||
: > $@
|
||||
endif
|
||||
|
||||
include/generated/gki_module_unprotected.h: $(ALL_KMI_SYMBOLS) \
|
||||
$(srctree)/scripts/gen_gki_modules_headers.sh
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/gen_gki_modules_headers.sh $@ \
|
||||
"$(srctree)" \
|
||||
$(ALL_KMI_SYMBOLS)
|
||||
|
||||
# AARCH is the same as ARCH, except that arm64 becomes aarch64
|
||||
AARCH := $(if $(filter arm64,$(ARCH)),aarch64,$(ARCH))
|
||||
|
||||
# ABI protected exports list file specific to ARCH if exists else empty
|
||||
ABI_PROTECTED_EXPORTS_FILE := $(wildcard $(srctree)/gki/$(AARCH)/protected_exports)
|
||||
|
||||
include/generated/gki_module_protected_exports.h: $(ABI_PROTECTED_EXPORTS_FILE) \
|
||||
$(srctree)/scripts/gen_gki_modules_headers.sh
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/gen_gki_modules_headers.sh $@ \
|
||||
"$(srctree)" \
|
||||
$(ABI_PROTECTED_EXPORTS_FILE)
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
* Author: ramjiyani@google.com (Ramji Jiyani)
|
||||
*/
|
||||
|
||||
#include <linux/bsearch.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/*
|
||||
* Build time generated header files
|
||||
*
|
||||
* gki_module_protected_exports.h -- Symbols protected from _export_ by unsigned modules
|
||||
* gki_module_unprotected.h -- Symbols allowed to _access_ by unsigned modules
|
||||
*/
|
||||
#include <generated/gki_module_protected_exports.h>
|
||||
#include <generated/gki_module_unprotected.h>
|
||||
|
||||
#define MAX_STRCMP_LEN (max(MAX_UNPROTECTED_NAME_LEN, MAX_PROTECTED_EXPORTS_NAME_LEN))
|
||||
|
||||
/* bsearch() comparision callback */
|
||||
static int gki_cmp_name(const void *sym, const void *protected_sym)
|
||||
{
|
||||
return strncmp(sym, protected_sym, MAX_STRCMP_LEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* gki_is_module_protected_export - Is a symbol exported from a protected GKI module?
|
||||
*
|
||||
* @name: Symbol being checked against exported symbols from protected GKI modules
|
||||
*/
|
||||
bool gki_is_module_protected_export(const char *name)
|
||||
{
|
||||
if (NR_UNPROTECTED_SYMBOLS) {
|
||||
return bsearch(name, gki_protected_exports_symbols, NR_PROTECTED_EXPORTS_SYMBOLS,
|
||||
MAX_PROTECTED_EXPORTS_NAME_LEN, gki_cmp_name) != NULL;
|
||||
} else {
|
||||
/*
|
||||
* If there are no symbols in unprotected list; We don't need to
|
||||
* protect exports as there is no KMI enforcement.
|
||||
* Treat everything exportable in this case.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gki_is_module_unprotected_symbol - Is a symbol unprotected for unsigned module?
|
||||
*
|
||||
* @name: Symbol being checked in list of unprotected symbols
|
||||
*/
|
||||
bool gki_is_module_unprotected_symbol(const char *name)
|
||||
{
|
||||
if (NR_UNPROTECTED_SYMBOLS) {
|
||||
return bsearch(name, gki_unprotected_symbols, NR_UNPROTECTED_SYMBOLS,
|
||||
MAX_UNPROTECTED_NAME_LEN, gki_cmp_name) != NULL;
|
||||
} else {
|
||||
/*
|
||||
* If there are no symbols in unprotected list;
|
||||
* there isn't a KMI enforcement for the kernel.
|
||||
* Treat everything accessible in this case.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -420,17 +420,3 @@ static inline int same_magic(const char *amagic, const char *bmagic, bool has_cr
|
||||
return strcmp(amagic, bmagic) == 0;
|
||||
}
|
||||
#endif /* CONFIG_MODVERSIONS */
|
||||
|
||||
#ifdef CONFIG_MODULE_SIG_PROTECT
|
||||
extern bool gki_is_module_unprotected_symbol(const char *name);
|
||||
extern bool gki_is_module_protected_export(const char *name);
|
||||
#else
|
||||
static inline bool gki_is_module_unprotected_symbol(const char *name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
static inline bool gki_is_module_protected_export(const char *name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_MODULE_SIG_PROTECT */
|
||||
|
||||
@@ -1147,8 +1147,6 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
|
||||
const char *name,
|
||||
char ownername[])
|
||||
{
|
||||
bool is_vendor_module;
|
||||
bool is_vendor_exported_symbol;
|
||||
struct find_symbol_arg fsa = {
|
||||
.name = name,
|
||||
.gplok = !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)),
|
||||
@@ -1185,24 +1183,6 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
|
||||
goto getname;
|
||||
}
|
||||
|
||||
/*
|
||||
* ANDROID GKI
|
||||
*
|
||||
* Vendor (i.e., unsigned) modules are only permitted to use:
|
||||
*
|
||||
* 1. symbols exported by other vendor (unsigned) modules
|
||||
* 2. unprotected symbols
|
||||
*/
|
||||
is_vendor_module = !mod->sig_ok;
|
||||
is_vendor_exported_symbol = fsa.owner && !fsa.owner->sig_ok;
|
||||
|
||||
if (is_vendor_module &&
|
||||
!is_vendor_exported_symbol &&
|
||||
!gki_is_module_unprotected_symbol(name)) {
|
||||
fsa.sym = ERR_PTR(-EACCES);
|
||||
goto getname;
|
||||
}
|
||||
|
||||
err = ref_module(mod, fsa.owner);
|
||||
if (err) {
|
||||
fsa.sym = ERR_PTR(err);
|
||||
@@ -1404,14 +1384,6 @@ static int verify_exported_symbols(struct module *mod)
|
||||
.name = kernel_symbol_name(s),
|
||||
.gplok = true,
|
||||
};
|
||||
|
||||
if (!mod->sig_ok && gki_is_module_protected_export(
|
||||
kernel_symbol_name(s))) {
|
||||
pr_err("%s: exports protected symbol %s\n",
|
||||
mod->name, kernel_symbol_name(s));
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (find_symbol(&fsa)) {
|
||||
pr_err("%s: exports duplicate symbol %s"
|
||||
" (owned by %s)\n",
|
||||
@@ -1492,15 +1464,9 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
|
||||
ignore_undef_symbol(info->hdr->e_machine, name)))
|
||||
break;
|
||||
|
||||
if (PTR_ERR(ksym) == -EACCES) {
|
||||
ret = -EACCES;
|
||||
pr_warn("%s: Protected symbol: %s (err %d)\n",
|
||||
mod->name, name, ret);
|
||||
} else {
|
||||
ret = PTR_ERR(ksym) ?: -ENOENT;
|
||||
pr_warn("%s: Unknown symbol %s (err %d)\n",
|
||||
mod->name, name, ret);
|
||||
}
|
||||
ret = PTR_ERR(ksym) ?: -ENOENT;
|
||||
pr_warn("%s: Unknown symbol %s (err %d)\n",
|
||||
mod->name, name, ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2450,7 +2416,6 @@ static void module_augment_kernel_taints(struct module *mod, struct load_info *i
|
||||
}
|
||||
#ifdef CONFIG_MODULE_SIG
|
||||
mod->sig_ok = info->sig_ok;
|
||||
#ifndef CONFIG_MODULE_SIG_PROTECT
|
||||
if (!mod->sig_ok) {
|
||||
pr_notice_once("%s: module verification failed: signature "
|
||||
"and/or required key missing - tainting "
|
||||
@@ -2458,9 +2423,6 @@ static void module_augment_kernel_taints(struct module *mod, struct load_info *i
|
||||
add_taint_module(mod, TAINT_UNSIGNED_MODULE, LOCKDEP_STILL_OK);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
mod->sig_ok = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ndiswrapper is under GPL by itself, but loads proprietary modules.
|
||||
|
||||
@@ -19,20 +19,8 @@
|
||||
#undef MODULE_PARAM_PREFIX
|
||||
#define MODULE_PARAM_PREFIX "module."
|
||||
|
||||
/*
|
||||
* ANDROID: GKI:
|
||||
* Only enforce signature if SIG_PROTECT is not set
|
||||
*/
|
||||
#ifndef CONFIG_MODULE_SIG_PROTECT
|
||||
static bool sig_enforce = IS_ENABLED(CONFIG_MODULE_SIG_FORCE);
|
||||
module_param(sig_enforce, bool_enable_only, 0644);
|
||||
void set_module_sig_enforced(void)
|
||||
{
|
||||
sig_enforce = true;
|
||||
}
|
||||
#else
|
||||
#define sig_enforce false
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Export sig_enforce kernel cmdline parameter to allow other subsystems rely
|
||||
@@ -44,6 +32,11 @@ bool is_module_sig_enforced(void)
|
||||
}
|
||||
EXPORT_SYMBOL(is_module_sig_enforced);
|
||||
|
||||
void set_module_sig_enforced(void)
|
||||
{
|
||||
sig_enforce = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the signature on a module.
|
||||
*/
|
||||
@@ -128,13 +121,5 @@ int module_sig_check(struct load_info *info, int flags)
|
||||
return -EKEYREJECTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* ANDROID: GKI: Do not prevent loading of unsigned modules;
|
||||
* as all modules except GKI modules are not signed.
|
||||
*/
|
||||
#ifndef CONFIG_MODULE_SIG_PROTECT
|
||||
return security_locked_down(LOCKDOWN_MODULE_SIGNATURE);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Copyright 2022 Google LLC
|
||||
# Author: ramjiyani@google.com (Ramji Jiyani)
|
||||
#
|
||||
|
||||
#
|
||||
# Generates header file with list of unprotected symbols
|
||||
#
|
||||
# Called By: KERNEL_SRC/kernel/Makefile if CONFIG_MODULE_SIG_PROTECT=y
|
||||
#
|
||||
# gki_module_unprotected.h: Symbols allowed to _access_ by unsigned modules
|
||||
#
|
||||
# If valid symbol file doesn't exists then still generates valid C header files for
|
||||
# compilation to proceed with no symbols to protect
|
||||
#
|
||||
|
||||
# Collect arguments from Makefile
|
||||
TARGET=$1
|
||||
SRCTREE=$2
|
||||
SYMBOL_LIST=$3
|
||||
|
||||
set -e
|
||||
|
||||
#
|
||||
# Common Definitions
|
||||
#
|
||||
# Use "make V=1" to debug this script.
|
||||
case "$KBUILD_VERBOSE" in
|
||||
*1*)
|
||||
set -x
|
||||
;;
|
||||
esac
|
||||
|
||||
#
|
||||
# generate_header():
|
||||
# Args: $1 = Name of the header file
|
||||
# $2 = Input symbol list
|
||||
# $3 = Symbol type ("unprotected")
|
||||
#
|
||||
generate_header() {
|
||||
local header_file=$1
|
||||
local symbol_file=$2
|
||||
local symbol_type=$3
|
||||
|
||||
if [ -f "${header_file}" ]; then
|
||||
rm -f -- "${header_file}"
|
||||
fi
|
||||
|
||||
# If symbol_file exist preprocess it and find maximum name length
|
||||
if [ -s "${symbol_file}" ]; then
|
||||
# Remove any trailing CR, leading / trailing whitespace,
|
||||
# line comments, empty lines and symbol list markers.
|
||||
sed -i '
|
||||
s/\r$//
|
||||
s/^[[:space:]]*//
|
||||
s/[[:space:]]*$//
|
||||
/^#/d
|
||||
/^$/d
|
||||
/^\[abi_symbol_list\]$/d
|
||||
' "${symbol_file}"
|
||||
|
||||
# Sort in byte order for kernel binary search at runtime
|
||||
LC_ALL=C sort -u -o "${symbol_file}" "${symbol_file}"
|
||||
|
||||
# Trim white spaces & +1 for null termination
|
||||
local max_name_len=$(awk '
|
||||
{
|
||||
$1=$1;
|
||||
if ( length > L ) {
|
||||
L=length
|
||||
}
|
||||
} END { print ++L }' "${symbol_file}")
|
||||
else
|
||||
# Set to 1 to generate valid C header file
|
||||
local max_name_len=1
|
||||
fi
|
||||
|
||||
# Header generation
|
||||
cat > "${header_file}" <<- EOT
|
||||
/*
|
||||
* DO NOT EDIT
|
||||
*
|
||||
* Build generated header file with ${symbol_type}
|
||||
*/
|
||||
|
||||
#define NR_$(printf ${symbol_type} | tr [:lower:] [:upper:])_SYMBOLS \\
|
||||
$(printf '\t')(ARRAY_SIZE(gki_${symbol_type}_symbols))
|
||||
#define MAX_$(printf ${symbol_type} | tr [:lower:] [:upper:])_NAME_LEN (${max_name_len})
|
||||
|
||||
static const char gki_${symbol_type}_symbols[][MAX_$(printf ${symbol_type} |
|
||||
tr [:lower:] [:upper:])_NAME_LEN] = {
|
||||
EOT
|
||||
|
||||
# If a valid symbol_file present add symbols in an array except the 1st line
|
||||
if [ -s "${symbol_file}" ]; then
|
||||
sed -e 's/^[ \t]*/\t"/;s/[ \t]*$/",/' "${symbol_file}" >> "${header_file}"
|
||||
fi
|
||||
|
||||
# Terminate the file
|
||||
echo "};" >> "${header_file}"
|
||||
}
|
||||
|
||||
if [ "$(basename "${TARGET}")" = "gki_module_unprotected.h" ]; then
|
||||
# Union of vendor symbol lists
|
||||
GKI_VENDOR_SYMBOLS="${SYMBOL_LIST}"
|
||||
generate_header "${TARGET}" "${GKI_VENDOR_SYMBOLS}" "unprotected"
|
||||
else
|
||||
# Sorted list of exported symbols
|
||||
GKI_EXPORTED_SYMBOLS="include/config/abi_gki_protected_exports"
|
||||
|
||||
if [ -z "${SYMBOL_LIST}" ]; then
|
||||
# Create empty list if ARCH doesn't have protected exports
|
||||
touch "${GKI_EXPORTED_SYMBOLS}"
|
||||
else
|
||||
# Make a temp copy to avoid changing source during pre-processing
|
||||
cp -f "${SYMBOL_LIST}" "${GKI_EXPORTED_SYMBOLS}"
|
||||
fi
|
||||
|
||||
generate_header "${TARGET}" "${GKI_EXPORTED_SYMBOLS}" "protected_exports"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user