私のBASH_FUNC_foobar%%環境変数がシェルサブプロセスに設定されていないのはなぜですか?

私のBASH_FUNC_foobar%%環境変数がシェルサブプロセスに設定されていないのはなぜですか?

私はsetuidバイナリのセキュリティに触れています(明らかに私が見つけたすべてを作者に公開するため)。シェルスクリプトを呼び出して環境を削除しないため、ランダムなコード実行の脆弱性があると確信しています。 Bashについて考えましたが、export -f実際に概念証明を行うことはできません。

基本的な問題は、何らかの理由でBASH_FUNC_foobar%%foobarエクスポートされた関数がある場合)、一部の子プロセスの環境では不思議に消えることです。シェルでない場合でも動作します。

% env 'BASH_FUNC_foobar%%=() { echo pwd lol; }' env | grep BASH
BASH_FUNC_foobar%%=() { echo pwd lol; }

env | grep BASHただし、実際のプログラム名に変更して環境をダンプするように変更すると(デフォルトではsystem("env")Cソースコードから)、変数は削除されます。sh呼び出すコマンドを指定すると、同じことが発生します。しかし、奇妙なことに指定すると、bash関数は正しく選択されます。

私のテストシステム/bin/shではdash

一体何が起こったのでしょうか?この変数はなぜ消えますか?

ベストアンサー1

多くのLinuxシステムでは、/bin/shこれは実際に/bin/dash

すでに述べたようにコメントby @MichaelHomerは/bin/dash環境を整理し、forを含む/^[a-zA-Z_][a-zA-Z_0-9]*=.*/フォームの一部ではないすべての文字列を削除します。BASH_FUNC_foo%%=...%%

これはdashOpenBSD ksh(およびそれに基づくもの)mkshにのみ適用されます。他のシェルではこれを行いません。

たとえば、Debianでは/bin/sh次のようになりますdash

$ env - '@#%=' 'foo%%=bar' /bin/sh -c /usr/bin/printenv
PWD=/your/cwd
$ env - '@#%=' 'foo%%=bar' /usr/bin/printenv
@#%=
foo%%=bar
$ env - '@#%=' 'foo%%=bar' /bin/bash -c /usr/bin/printenv
[...]
@#%=
foo%%=bar

ソース参照用に確認できますsrc/var.cdashソースから:

    initvar();
    for (envp = environ ; *envp ; envp++) {
            p = endofname(*envp);
            if (p != *envp && *p == '=') {
                    setvareq(*envp, VEXPORT|VTEXTFIXED);
            }
    }

dashexecが別のバイナリの場合、envここに渡された引数はexecve変数のリストで(listvars(VEXPORT, VUNSET, 0)マクロ呼び出しを介してenvironment())動的に設定されます。

おすすめ記事