eBPF を kprobes/kretprobes にアタッチすると、関数の引数と戻り値への読み取りアクセスが可能になりますが、それらを改ざんすることはできません。 100% 確信はありません。 IO Visor プロジェクトのメーリング リストまたは IRC チャンネル (irc.oftc.net の #iovisor) で確認を求めるのに適しています。
別の解決策として、少なくともシステムコールの戻り値を strace で -e
で変更できることを知っています オプション。マニュアルページの引用:
-e inject=set[:error=errno|:retval=value][:signal=sig][:when=expr] Perform syscall tampering for the specified set of syscalls.
また、興味があれば、Fosdem 2017 でこれとフォールト注入に関するプレゼンテーションがありました。スライドのコマンドの例を次に示します:
strace -P precious.txt -efault=unlink:retval=0 unlink precious.txt
編集: Ben が述べたように、kprobes と tracepoints の eBPF は、トレースと監視のユースケースのために、明らかに読み取り専用です。これについては IRC でも確認しました。
カーネル プローブ (kprobes) 内では、eBPF 仮想マシンは syscall パラメーターと戻り値に読み取り専用でアクセスできます。
ただし、eBPF プログラムには独自のリターン コードがあります。 BPF (eBPF ではありません。@qeole に感謝します) リターン コードをトラップする seccomp プロファイルを適用し、実行中にシステム コールを中断することができます。
許可されているランタイムの変更は次のとおりです:
SECCOMP_RET_KILL
:SIGSYS
で即死SECCOMP_RET_TRAP
:キャッチ可能なSIGSYS
を送信します 、syscall をエミュレートする機会を与えますSECCOMP_RET_ERRNO
:errno
を強制する 値SECCOMP_RET_TRACE
:ptracer に決定を渡すか、errno
を設定します-ENOSYS
までSECCOMP_RET_ALLOW
:許可
https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
SECCOMP_RET_TRACE
メソッドを使用すると、実行されるシステム コール、引数、または戻り値を変更できます。これはアーキテクチャに依存し、必須の外部参照を変更すると ENOSYS エラーが発生する場合があります。
これは、トレースされたプロセスのメモリ、レジスタ、およびファイル記述子を変更する機能を持つ、待機中のユーザー空間 ptrace に実行を渡すことによって行われます。
トレーサーは、ptrace を呼び出してから、waitpid を呼び出す必要があります。例:
ptrace(PTRACE_SETOPTIONS, tracee_pid, 0, PTRACE_O_TRACESECCOMP);
waitpid(tracee_pid, &status, 0);
http://man7.org/linux/man-pages/man2/ptrace.2.html
waitpid
のとき status
の内容に応じて戻ります PTRACE_GETEVENTMSG
を使用して seccomp の戻り値を取得できます。 ptrace 操作。これにより、seccomp SECCOMP_RET_DATA
が取得されます これは、BPF プログラムによって設定される 16 ビット フィールドです。例:
ptrace(PTRACE_GETEVENTMSG, tracee_pid, 0, &data);
syscall 引数は、操作を続行する前にメモリ内で変更できます。 PTRACE_SYSCALL
を使用して、単一のシステムコールのエントリまたは終了を実行できます ステップ。 syscall の戻り値は、実行を再開する前にユーザー空間で変更できます。基になるプログラムは、syscall の戻り値が変更されたことを認識できません。
実装例:seccomp と ptrace を使用したシステム コールのフィルタリングと変更