Linuxで実行されているプロセスの機能を変更できますか?ファイルを開くパスを変更できます(出力リダイレクトなど)。
それではどうですか?
ベストアンサー1
そのようなプロセスの環境を外部から変えることはできませんが、必ずしなければならない場合があります。ptrace(2)
プロセス(実際にはスレッドですが、単純化のためにプロセスと言い続けます)と変更を実行するのに十分なツールを使用します。運転中。もちろんプロダクション用途に頼るのはおかしいだろうがptrace
、それが唯一の選択なら…
gdb
これができる
プロセス(またはより多くのgdb-fuを持ついくつかのスレッド)に接続して、動作を変更および切り離すことができます。十分にすばやく完了すると(スクリプトで書くなど)、プロセスはよりスマートになりません。に従ってプロセスの運用と対策初期化時に常にptrace
同じユーザーにすることはできないため、rootアクセス権が必要または最小限CAP_SYS_PTRACE
能力。プロセスで行われた操作は実際に行われました。それ自体を通して:プロセスがすでにその機能を変更することを許可されている場合(しばしば必須ですCAP_SETPCAP
)、それ自体を行うことができます。操作が許可されていない場合は、ptrace
ルートを介して実行しても役に立ちません。同様に、ログファイルを閉じて他の場所で再度開くのも簡単です。
UL Q&Aのいくつかの例(そのいくつかは私が書いたものです):
タブインターフェイスとそのファイル記述子間の接続を見つけるには?解決策は、カーネル 3.14 以前では、カーネルが /proc/pid/fdinfo/ を介してこの情報を提供していなかったためです。
現在のプロセスのネットワーク共有をキャンセルする方法:gdbを実行してプロセスのネットワーク名前空間を(永久に)変更し、それをネットワークから効果的に分離します。
プログラムが削除されたファイルを書き込むのを防ぐ:プログラムにランアウェイのログファイルを変更させます。あなたの質問に対する答えの2番目の例です。
問題を解決するには、最初の例を見てください...
gdbを使用して実行中のプロセスの機能制限
bash
例は、ルートとして実行される(したがって完全に機能する)シェルで実行されますgdb
(また、ルートとして実行されます)。これは複雑なのでクカ機能プログラムがリンクされていないかどうかわからないので、開発環境を必要とせず、追加のgdb-fuを必要としない、よりシンプルだが退屈な(構造操作が必要なので)アプローチを選択しました。直接gdbからAlways Knownで定義されたシステムコールを使用します。
最初の学期:
# echo test > /tmp/test
# chown nobody /tmp/test
# chmod 600 /tmp/test
# cat < /tmp/test
test
# cat /tmp/test
test
# echo $$
5237
# grep ^Cap /proc/$$/status
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
#
第二学期:
# gdb -q -p 5237
Attaching to process 5237
Reading symbols from /bin/bash...(no debugging symbols found)...done.
[...]
0x00007fb774737681 in pselect () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) set $malloc=(void *(*)(long long)) malloc
(gdb) print $malloc(4*(2+3*2))
$1 = (void *) 0xc4ecc8
(gdb) set *((unsigned int *)($1))=0x20080522
(gdb) set *((unsigned int *)($1)+1)=getpid()
(gdb) print capget($1, (unsigned int *)$1+2)
$2 = 0
(gdb) set *((unsigned int *)($1)+2) &= ~(1<<1|1<<2)
(gdb) print capset($1, (unsigned int *)$1+2)
$3 = 0
(gdb) call free($1)
$4 = 0
(gdb) quit
A debugging session is active.
Inferior 1 [process 5237] will be detached.
Quit anyway? (y or n) y
Detaching from program: /bin/bash, process 5237
#
だから、この割り当てられたメモリは64ビット回避策スタイル、必須*cap_user_header_t
そしてcap_user_data_t[2]
構造、いくつかの設定魔法の価値、検索済み現在のプロセス能力と削除済み CAP_DAC_OVERRIDE
そしてCAP_DAC_READ_SEARCH
機能で効果的に設定してその機能を読み取ることができないようにし、/tmp/test
最終的に割り当てられたメモリを解放します。
最初の学期に戻って:
# grep ^Cap /proc/$$/status
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003ffffffff9
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
# cat < /tmp/test
bash: /tmp/test: Permission denied
# cat /tmp/test
test
#
違いは何ですか?リダイレクトを使用すると、bashプロセスは制限されたアクセスでルート以外のファイルにアクセスできなくなり(フォーク後、実行前cat
)新しいプロセスを(パッキングして)実行すると、ルートはすべての機能を復元します。他のセットから削除されない限り:他の方法で変更できる機能境界セット(prctl(PR_CAPBSET_DROP, ...)
)。これがcat
リダイレクトなしで実行されてもまだうまく機能する理由です(例:根)。