Move seccomp policy to bionic

Test: Built and checked booted
Change-Id: Iaec1265fe5a55c4df90ab9e45b010ef36faf6bba
This commit is contained in:
Paul Lawrence 2017-02-16 09:24:39 -08:00
parent c712aedb0c
commit dfe8434a62
9 changed files with 205 additions and 19 deletions

View file

@ -960,6 +960,22 @@ SUCH DAMAGE.
-------------------------------------------------------------------
Copyright (C) 2017 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.
-------------------------------------------------------------------
Copyright (C) 2017 The Android Open Source Project
All rights reserved.

View file

@ -5,8 +5,9 @@ include $(CLEAR_VARS)
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_MODULE := libseccomp_policy
LOCAL_CLANG := true
LOCAL_SRC_FILES := arm_policy.c arm64_policy.c
LOCAL_SRC_FILES := seccomp_policy.cpp arm_policy.cpp arm64_policy.cpp
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
LOCAL_SHARED_LIBRARIES := libbase
include $(BUILD_STATIC_LIBRARY)

View file

@ -3,8 +3,8 @@
#include <linux/filter.h>
#include <errno.h>
#include "seccomp_policy.h"
const struct sock_filter arm64_filter[] = {
#include "seccomp_bpfs.h"
const sock_filter arm64_filter[] = {
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5, 0, 25),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 203, 13, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 101, 7, 0),

View file

@ -3,8 +3,8 @@
#include <linux/filter.h>
#include <errno.h>
#include "seccomp_policy.h"
const struct sock_filter arm_filter[] = {
#include "seccomp_bpfs.h"
const sock_filter arm_filter[] = {
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 125),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 63, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 31, 0),

View file

@ -0,0 +1,28 @@
/*
* Copyright (C) 2017 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.
*/
#ifndef SECCOMP_BPFS_H
#define SECCOMP_BPFS_H
#include <stddef.h>
#include <linux/seccomp.h>
extern const struct sock_filter arm_filter[];
extern const size_t arm_filter_size;
extern const struct sock_filter arm64_filter[];
extern const size_t arm64_filter_size;
#endif

View file

@ -0,0 +1,147 @@
/*
* Copyright (C) 2017 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 "seccomp_policy.h"
#include <linux/audit.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <sys/prctl.h>
#include <vector>
#include <android-base/logging.h>
#if defined __arm__ || defined __aarch64__
extern const struct sock_filter arm_filter[];
extern const size_t arm_filter_size;
extern const struct sock_filter arm64_filter[];
extern const size_t arm64_filter_size;
#define syscall_nr (offsetof(struct seccomp_data, nr))
#define arch_nr (offsetof(struct seccomp_data, arch))
typedef std::vector<sock_filter> filter;
// We want to keep the below inline functions for debugging and future
// development even though they are not all sed currently.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
static inline void Kill(filter& f) {
f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL));
}
static inline void Trap(filter& f) {
f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP));
}
static inline void Error(filter& f, __u16 retcode) {
f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO + retcode));
}
inline static void Trace(filter& f) {
f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE));
}
inline static void Allow(filter& f) {
f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW));
}
#pragma clang diagnostic pop
inline static void ExamineSyscall(filter& f) {
f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_nr));
}
inline static int SetValidateArchitectureJumpTarget(size_t offset, filter& f) {
size_t jump_length = f.size() - offset - 1;
auto u8_jump_length = (__u8) jump_length;
if (u8_jump_length != jump_length) {
LOG(FATAL)
<< "Can't set jump greater than 255 - actual jump is " << jump_length;
return -1;
}
f[offset] = BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_ARM, u8_jump_length, 0);
return 0;
}
inline static size_t ValidateArchitectureAndJumpIfNeeded(filter& f) {
f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, arch_nr));
f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_AARCH64, 2, 0));
f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_ARM, 1, 0));
Trap(f);
return f.size() - 2;
}
static bool install_filter(filter const& f) {
struct sock_fprog prog = {
static_cast<unsigned short>(f.size()),
const_cast<struct sock_filter*>(&f[0]),
};
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
PLOG(FATAL) << "Could not set seccomp filter of size " << f.size();
return false;
}
LOG(INFO) << "Global filter of size " << f.size() << " installed";
return true;
}
bool set_seccomp_filter() {
filter f;
// Note that for mixed 64/32 bit architectures, ValidateArchitecture inserts a
// jump that must be changed to point to the start of the 32-bit policy
// 32 bit syscalls will not hit the policy between here and the call to SetJump
auto offset_to_32bit_filter = ValidateArchitectureAndJumpIfNeeded(f);
// 64-bit filter
ExamineSyscall(f);
// arm64-only filter - autogenerated from bionic syscall usage
for (size_t i = 0; i < arm64_filter_size; ++i) {
f.push_back(arm64_filter[i]);
}
Trap(f);
if (SetValidateArchitectureJumpTarget(offset_to_32bit_filter, f) != 0) {
return -1;
}
// 32-bit filter
ExamineSyscall(f);
// arm32 filter - autogenerated from bionic syscall usage
for (size_t i = 0; i < arm_filter_size; ++i) {
f.push_back(arm_filter[i]);
}
Trap(f);
return install_filter(f);
}
#else // if defined __arm__ || defined __aarch64__
bool set_seccomp_filter() {
LOG(INFO) << "Not setting seccomp filter - wrong architecture";
return true;
}
#endif

View file

@ -17,12 +17,6 @@
#ifndef SECCOMP_POLICY_H
#define SECCOMP_POLICY_H
#include <stddef.h>
#include <linux/seccomp.h>
extern const struct sock_filter arm_filter[];
extern const size_t arm_filter_size;
extern const struct sock_filter arm64_filter[];
extern const size_t arm64_filter_size;
bool set_seccomp_filter();
#endif

View file

@ -149,8 +149,8 @@ def convert_bpf_to_output(bpf, architecture):
#include <linux/filter.h>
#include <errno.h>
#include "seccomp_policy.h"
const struct sock_filter {architecture}_filter[] = {{
#include "seccomp_bpfs.h"
const sock_filter {architecture}_filter[] = {{
""").format(architecture=architecture)
footer = textwrap.dedent("""\
@ -196,7 +196,7 @@ def main():
# And output policy
existing = ""
output_path = "seccomp/{}_policy.c".format(arch)
output_path = "seccomp/{}_policy.cpp".format(arch)
if os.path.isfile(output_path):
existing = open(output_path).read()
if output == existing:

View file

@ -107,8 +107,8 @@ ssize_t read(int, void*, size_t) all
#include <linux/filter.h>
#include <errno.h>
#include "seccomp_policy.h"
const struct sock_filter arm_filter[] = {
#include "seccomp_bpfs.h"
const sock_filter arm_filter[] = {
line1
line2
};
@ -136,8 +136,8 @@ ssize_t read(int, void*, size_t) all
#include <linux/filter.h>
#include <errno.h>
#include "seccomp_policy.h"
const struct sock_filter arm_filter[] = {
#include "seccomp_bpfs.h"
const sock_filter arm_filter[] = {
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 0, 3),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 140, 1, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 2, 1), //read