2017-03-24 20 views
2

いくつかの動作をシミュレートするには、プローブをシステムコールに接続し、特定のパラメータが渡されたときに戻り値を変更したいと思います。あるいは、関数が処理される前に関数のパラメータを変更するだけで十分です。eBPFはシステムコールの戻り値またはパラメータを変更できますか?

これはBPFで可能ですか?

+1

のSystemTapはそれを – fche

+0

を行うことができます誰でもネットワーキングのためのeBPFを使用することに興味を持ってここに来た場合、パケットをある程度制御することができますXDPがあります。 [Forwarding example](https://github.com/torvalds/linux/blob/master/samples/bpf/xdp_redirect_kern.c) –

答えて

2

私は、eBPFをkprobes/kretprobesに付けると、関数の引数と戻り値に読み取りアクセスできますが、それらを改ざんすることはできないと思います。私は100%確実ではない。確認を求める良い場所は、IO Visorプロジェクトmailing listまたはIRCチャンネル(irc.oftc.netの#iovisor)です。

別の解決策として、少なくともstraceのシステムコールの戻り値を-eオプションで変更することができます。 the manual page引用:それはあなたにどんな興味がある場合

-e inject=set[:error=errno|:retval=value][:signal=sig][:when=expr] 
     Perform syscall tampering for the specified set of syscalls. 

はまた、フォールトインジェクションは、FOSDEM 2017で、そこにこの上 a presentationだった、と。

strace -P precious.txt -efault=unlink:retval=0 unlink precious.txt 

編集:ここではスライドから1つの例のコマンドでkprobesとトレースポイントにベン、eBPFで述べたようにすることは決定的にユースケースを追跡し、監視するため、読み取り専用です。私もIRCでこれについての確認を得ました。

3

カーネルプローブ(kprobes)内で、eBPF仮想マシンは、syscallパラメータと戻り値への読み取り専用アクセス権を持ちます。

しかし、eBPFプログラムは、それ自身のリターンコードを持ちます。 BPF(NOT eBPF; thanks @ qeole)リターンコードをトラップし、実行中にシステムコールを中断するseccompプロファイルを適用することは可能です。

許容ランタイム変更は、次のとおり SECCOMP_RET_KILL: Immediate kill with SIGSYS SECCOMP_RET_TRAP: Send a catchable SIGSYS, giving a chance to emulate the syscall SECCOMP_RET_ERRNO: Force errno value SECCOMP_RET_TRACE: Yield decision to ptracer or set errno to -ENOSYS SECCOMP_RET_ALLOW: Allow https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt

SECCOMP_RET_TRACE方法は、システムコールを行っ、引数、または戻り値を変更することが可能となります。これはアーキテクチャに依存し、必須の外部参照を変更するとENOSYSエラーが発生する可能性があります。

トレースされたプロセスメモリ、レジスタ、およびファイルディスクリプタを変更できる待機中のユーザースペースptraceに実行を渡すことで、これを行います。

トレーサはptraceを呼び出してからwaitpidを呼び出す必要があります。例:waitpid戻り、statusの内容に応じて、一方がPTRACE_GETEVENTMSG ptraceの操作を使用してseccomp戻り値を取得でき ptrace(PTRACE_SETOPTIONS, tracee_pid, 0, PTRACE_O_TRACESECCOMP); waitpid(tracee_pid, &status, 0); http://man7.org/linux/man-pages/man2/ptrace.2.html

。これは、seccomp SECCOMP_RET_DATA値を取得します。これは、BPFプログラムによって設定された16ビットフィールドです。例:

ptrace(PTRACE_GETEVENTMSG, tracee_pid, 0, &data);

、システムコールの引数には、操作を続行する前にメモリ内で変更することができます。 PTRACE_SYSCALLステップで1つのシステムコール入力または終了を実行できます。実行を再開する前に、ユーザ空間でSyscallの戻り値を変更することができます。基礎となるプログラムは、システムコールの戻り値が変更されたことを見ることができません。

実装例: Filter and Modify System Calls with seccomp and ptrace

+1

マイナーな修正:seccompはBPFの「クラシック」バージョンのみをサポートしています。この時点で** e ** BPF(拡張BPF)はサポートされていません。 – Qeole

+0

更新済み!ありがとうQeole。 –

関連する問題