ANDROID: GKI: Protect exports of protected GKI modules
Implement support for protecting the exported symbols of protected GKI modules. Only signed GKI modules are permitted to export symbols listed in the android/abi_gki_protected_exports file. Attempting to export these symbols from an unsigned module will result in the module failing to load, with a 'Permission denied' error message. Bug: 232430739 Test: TH Change-Id: I3e8b330938e116bb2e022d356ac0d55108a84a01 Signed-off-by: Ramji Jiyani <ramjiyani@google.com>
This commit is contained in:
committed by
Treehugger Robot
parent
5e28b84896
commit
fd1e768866
0
android/abi_gki_protected_exports
Normal file
0
android/abi_gki_protected_exports
Normal file
@@ -160,12 +160,18 @@ $(obj)/kheaders_data.tar.xz: FORCE
|
|||||||
clean-files := kheaders_data.tar.xz kheaders.md5
|
clean-files := kheaders_data.tar.xz kheaders.md5
|
||||||
|
|
||||||
#
|
#
|
||||||
# ANDROID: GKI: Generate headerfile required for gki_module.o
|
# ANDROID: GKI: Generate headerfiles required for gki_module.o
|
||||||
#
|
#
|
||||||
# Dependencies on generated files need to be listed explicitly
|
# Dependencies on generated files need to be listed explicitly
|
||||||
$(obj)/gki_module.o: $(obj)/gki_module_unprotected.h
|
$(obj)/gki_module.o: $(obj)/gki_module_protected_exports.h \
|
||||||
|
$(obj)/gki_module_unprotected.h
|
||||||
|
|
||||||
$(obj)/gki_module_unprotected.h: $(srctree)/scripts/gen_gki_modules_headers.sh \
|
$(obj)/gki_module_unprotected.h: $(srctree)/scripts/gen_gki_modules_headers.sh \
|
||||||
$(if $(wildcard ${OUT_DIR}/abi_symbollist.raw), ${OUT_DIR}/abi_symbollist.raw)
|
$(if $(wildcard ${OUT_DIR}/abi_symbollist.raw), ${OUT_DIR}/abi_symbollist.raw)
|
||||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/gen_gki_modules_headers.sh $@ \
|
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/gen_gki_modules_headers.sh $@ \
|
||||||
"$(srctree)"
|
"$(srctree)"
|
||||||
|
|
||||||
|
$(obj)/gki_module_protected_exports.h: $(srctree)/android/abi_gki_protected_exports \
|
||||||
|
$(srctree)/scripts/gen_gki_modules_headers.sh
|
||||||
|
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/gen_gki_modules_headers.sh $@ \
|
||||||
|
"$(srctree)"
|
||||||
|
|||||||
@@ -13,14 +13,29 @@
|
|||||||
/*
|
/*
|
||||||
* Build time generated header files
|
* 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
|
* gki_module_unprotected.h -- Symbols allowed to _access_ by unsigned modules
|
||||||
*/
|
*/
|
||||||
|
#include "gki_module_protected_exports.h"
|
||||||
#include "gki_module_unprotected.h"
|
#include "gki_module_unprotected.h"
|
||||||
|
|
||||||
|
#define MAX_STRCMP_LEN (max(MAX_UNPROTECTED_NAME_LEN, MAX_PROTECTED_EXPORTS_NAME_LEN))
|
||||||
|
|
||||||
/* bsearch() comparision callback */
|
/* bsearch() comparision callback */
|
||||||
static int cmp_name(const void *sym, const void *protected_sym)
|
static int cmp_name(const void *sym, const void *protected_sym)
|
||||||
{
|
{
|
||||||
return strncmp(sym, protected_sym, MAX_UNPROTECTED_NAME_LEN);
|
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)
|
||||||
|
{
|
||||||
|
return bsearch(name, gki_protected_exports_symbols, NR_PROTECTED_EXPORTS_SYMBOLS,
|
||||||
|
MAX_PROTECTED_EXPORTS_NAME_LEN, cmp_name) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,8 +45,8 @@ static int cmp_name(const void *sym, const void *protected_sym)
|
|||||||
*/
|
*/
|
||||||
bool gki_is_module_unprotected_symbol(const char *name)
|
bool gki_is_module_unprotected_symbol(const char *name)
|
||||||
{
|
{
|
||||||
if (NO_OF_UNPROTECTED_SYMBOLS) {
|
if (NR_UNPROTECTED_SYMBOLS) {
|
||||||
return bsearch(name, gki_unprotected_symbols, NO_OF_UNPROTECTED_SYMBOLS,
|
return bsearch(name, gki_unprotected_symbols, NR_UNPROTECTED_SYMBOLS,
|
||||||
MAX_UNPROTECTED_NAME_LEN, cmp_name) != NULL;
|
MAX_UNPROTECTED_NAME_LEN, cmp_name) != NULL;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -32,9 +32,14 @@ extern int mod_verify_sig(const void *mod, struct load_info *info);
|
|||||||
|
|
||||||
#ifdef CONFIG_MODULE_SIG_PROTECT
|
#ifdef CONFIG_MODULE_SIG_PROTECT
|
||||||
extern bool gki_is_module_unprotected_symbol(const char *name);
|
extern bool gki_is_module_unprotected_symbol(const char *name);
|
||||||
|
extern bool gki_is_module_protected_export(const char *name);
|
||||||
#else
|
#else
|
||||||
static inline bool gki_is_module_unprotected_symbol(const char *name)
|
static inline bool gki_is_module_unprotected_symbol(const char *name)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
static inline bool gki_is_module_protected_export(const char *name)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif /* CONFIG_MODULE_SIG_PROTECT */
|
#endif /* CONFIG_MODULE_SIG_PROTECT */
|
||||||
|
|||||||
@@ -2282,6 +2282,14 @@ static int verify_exported_symbols(struct module *mod)
|
|||||||
.name = kernel_symbol_name(s),
|
.name = kernel_symbol_name(s),
|
||||||
.gplok = true,
|
.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)) {
|
if (find_symbol(&fsa)) {
|
||||||
pr_err("%s: exports duplicate symbol %s"
|
pr_err("%s: exports duplicate symbol %s"
|
||||||
" (owned by %s)\n",
|
" (owned by %s)\n",
|
||||||
|
|||||||
@@ -49,11 +49,11 @@ generate_header() {
|
|||||||
|
|
||||||
# Find Maximum symbol name length if valid symbol_file exist
|
# Find Maximum symbol name length if valid symbol_file exist
|
||||||
if [ -s "${symbol_file}" ]; then
|
if [ -s "${symbol_file}" ]; then
|
||||||
# Skip 1st line (symbol header), Trim white spaces & +1 for null termination
|
# Trim white spaces & +1 for null termination
|
||||||
local max_name_len=$(awk '
|
local max_name_len=$(awk '
|
||||||
{
|
{
|
||||||
$1=$1;
|
$1=$1;
|
||||||
if ( length > L && NR > 1) {
|
if ( length > L ) {
|
||||||
L=length
|
L=length
|
||||||
}
|
}
|
||||||
} END { print ++L }' "${symbol_file}")
|
} END { print ++L }' "${symbol_file}")
|
||||||
@@ -67,11 +67,11 @@ generate_header() {
|
|||||||
/*
|
/*
|
||||||
* DO NOT EDIT
|
* DO NOT EDIT
|
||||||
*
|
*
|
||||||
* Build generated header file with unprotected symbols/exports
|
* Build generated header file with ${symbol_type}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NO_OF_$(printf ${symbol_type} | tr [:lower:] [:upper:])_SYMBOLS \\
|
#define NR_$(printf ${symbol_type} | tr [:lower:] [:upper:])_SYMBOLS \\
|
||||||
$(printf '\t')(sizeof(gki_${symbol_type}_symbols) / sizeof(gki_${symbol_type}_symbols[0]))
|
$(printf '\t')(ARRAY_SIZE(gki_${symbol_type}_symbols))
|
||||||
#define MAX_$(printf ${symbol_type} | tr [:lower:] [:upper:])_NAME_LEN (${max_name_len})
|
#define MAX_$(printf ${symbol_type} | tr [:lower:] [:upper:])_NAME_LEN (${max_name_len})
|
||||||
|
|
||||||
static const char gki_${symbol_type}_symbols[][MAX_$(printf ${symbol_type} |
|
static const char gki_${symbol_type}_symbols[][MAX_$(printf ${symbol_type} |
|
||||||
@@ -87,8 +87,15 @@ generate_header() {
|
|||||||
echo "};" >> "${header_file}"
|
echo "};" >> "${header_file}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if [ "$(basename "${TARGET}")" = "gki_module_unprotected.h" ]; then
|
||||||
# Sorted list of vendor symbols
|
# Sorted list of vendor symbols
|
||||||
GKI_VENDOR_SYMBOLS="${OUT_DIR}/abi_symbollist.raw"
|
GKI_VENDOR_SYMBOLS="${OUT_DIR}/abi_symbollist.raw"
|
||||||
|
|
||||||
generate_header "${TARGET}" "${GKI_VENDOR_SYMBOLS}" "unprotected"
|
generate_header "${TARGET}" "${GKI_VENDOR_SYMBOLS}" "unprotected"
|
||||||
|
else
|
||||||
|
# Sorted list of exported symbols
|
||||||
|
GKI_EXPORTED_SYMBOLS="${SRCTREE}/android/abi_gki_protected_exports"
|
||||||
|
|
||||||
|
generate_header "${TARGET}" "${GKI_EXPORTED_SYMBOLS}" "protected_exports"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user