zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

Linux/Android之seccomp介绍及使用(一百一十六)

AndroidLinux 介绍 一百一十 使用
2023-09-14 09:09:56 时间

1.背景

seccomp是Linux的一种安全机制,android 8.1以后版本使用seccomp.

主要功能是限制直接通过syscall去调用某些系统函数

2.功能介绍

1.linux的沙箱机制,可以限制进程对系统调用的访问,从系统调用号,到系统调用的参数,都可以检查和限制.

2.有两种模式
SECCOMP_MODE_STRICT, 进程只能访问read,write,_exit,sigreturn系统调用.
SECCOM_MODE_FILTER,通过设置bpf规则,来过滤和检查系统调用号,和系统调用参数,来决定对进程访问系
统调用的处理.

3.systemd,container都使用seccomp机制来限定对进程的对系统调用的访问权限.

3.strict模式和filter模式应用

1.strict模式

# emacs strict.c

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <linux/seccomp.h>
#include <sys/prctl.h>

int main(){
	int output = open("test.txt", O_WRONLY);
	const char *val = "test";
	//1.通过prctl函数设置seccomp的模式为strict
	prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);

	//写入
	write(output, val, strlen(val)+1);

	//设置完毕seccomp以后再次尝试open,设置了secomp的模式是strict,直接sign -9 信号
	int input = open("test.txt", O_RDONLY);
}

2.基于BPF(伯克利分组过滤器)的seccomp

安装依赖包

​​​​​​​# sudo apt install libseccomp-dev

上述基于prctl系统调用的seccomp机制不够灵活,在linux 3.5之后引入了基于BPF的可定制的系统调用过滤功能。

# emacs filter.c

#include <stdio.h>
#include <unistd.h>
#include <seccomp.h>
 
int main() {
  printf("step 1: unrestricted\n");
 
  // Init the filter
  scmp_filter_ctx ctx;
  ctx = seccomp_init(SCMP_ACT_KILL); // default action: kill
 
  // setup basic whitelist
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0);
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
  
  // setup our rule
  seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(dup2), 2, SCMP_A0(SCMP_CMP_EQ, 1),SCMP_A1(SCMP_CMP_EQ, 2));
 
  // build and load the filter
  seccomp_load(ctx);
  printf("step 2: only 'write' and dup2(1, 2) syscalls\n");
  
  // Redirect stderr to stdout
  dup2(1, 2);
  printf("step 3: stderr redirected to stdout\n");
 
  // Duplicate stderr to arbitrary fd
  dup2(2, 42);
  printf("step 4: !! YOU SHOULD NOT SEE ME !!\n");
 
  // Success (well, not so in this case...)
  return 0; 
}