アカウント名:
パスワード:
argv[0]にファイル名が入っていることはposixで明言されているが、Linuxでは慣習扱い。linux man pageのexecve(2),exec(3)でもそう書いてある。Linuxをposix準拠だと思い込み、しっかりlinux man pageを読まなかったのが悪い。
この件はargv[1]の内容を無条件に読んでしまう脆弱性で、argv[0]に何が入っているかは関係ないのだが
そうすると、ストーリーの「常に 1 以上として扱うため、引数リスト (argv) が空の状態でも」は間違い、ってことだな。「常に 1 より大きいとして扱うため、」と書くべきか。
でもリンク先の修正をみると、argc1の場合に対処してるよ。
「常に 1 以上として扱うため、引数リスト (argv) が空の状態でも」は正しい。argc==0でもargv[1]を読んでしまう。execve()を使うと可能だそうだ。
argvの配列はNULLで終端されている(argv[argc]はNULLになる)ので、たとえ引数の個数(argc)がゼロ個でもargv[0]は常に有効(もちろん*argv[0]が有効とは限らないが)。だから「argv[1]の内容を無条件に読んでしまう」も「(argcを)常に 1 以上として扱うため」も正しい。
つまり#4192327は「posix準拠ならargv[0]に必ずファイル名がセットされるのでargcが0になることはありえない、Linuxだとargcが0でargv[0]に終端NULLがセットされるケースがあるためにこのようなことが起きる」と言いたかったわけか
argvを頭から呼び出して引数が何個入ってるか調べるとどうせ1万回に一回くらいヘマをやらかすので素直にargcを見たほうがいいと思う。これなら引数の数を取り違えたせいでメモリを書き換えたり変なところを読んだりする不具合を生む確率が多分1万1千回に一回くらいにへる。
配列とその要素数を別々に管理しなければならない言語を捨てたほうがいいと思う。よく反論で持ち出される組み込み(フリースタンディング環境)ではmainの存在すら保証されていないからここの議論のスコープ外だし。
arg[0]に必ずファイル名が入るのか、それとも終端NULLが入っているかもしれないかは、この脆弱性に関係大有りだろ。
この(Polkitの)脆弱性は、argv[1]は常に値が(最悪でも終端NULLが)入っていると仮定してアクセスしてしまったというものなので。もっと一般的な話として*argv[0]にアクセスしてしまったという脆弱性なら関係あるけど。
もう少し正確に言うと、書き変えても大丈夫だと思っていた、ですな。
argv[n] を書きかえるというトリックを使ってるのは、pkexec のコードがダサいargc=0 で呼び出されると argv[1] には environ が入ってるというのは *nix がダサいargv** が const* const* じゃないのは main() の仕様がダサいargv[n] で範囲外アクセス出来るのは C がダサい
世の中ダサいものばかりですね
2番めは4番目の未定義動作の結果としてたまたま生じたことなので*nixのせいにするのは少々酷ではありませんかね
やはりC言語は滅ばなければならないですな。いつもの流れ。
argc=0はLinux環境でしか起こらないんだから、*unix全般に広げている2番目はそもそも見当違い。
C99では起きます。C89は調べていない。
範囲外アクセスを許すOSに根本的な問題があるのではないでしょうか
読んでいるのはあくまでargv[1]だから、argv[0]に何が入っていようが直接には関係ない。現実にはそんな実装はまずありえないけど、argv[0]が終端NULLでもargv[1]にもNULLがセットされていれば大丈夫だったわけだから。
POSIX.1-2017から削除されたって書いてあるぞ。どれくらあてになる文章かわからんけど。https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html [opengroup.org]まあだから、それまではargc>=1だったってことだし、argc==0みたいなことをするのはやめようよって長々と書いてあるけど。こういう問題がおきそうだって予想してたようだね。
argv、argcだからとか特別視せずに配列とその要素数が与えられてるのだから基本に忠実にできるのならそうした方が良い。
mainは呼び出し頻度的にパフォーマンスに影響しにくいし、mainをある種の外部とのインターフェースとして見て、呼び出し側をあまり信用しないという考え方に立って、(パラメータの仕様がどうあれ)型の仕様として取りうる値の範囲でちゃんとチェックすべきだと思う。
pkexec.c見たけど、輸送機械、産業機械系なんかの組込みやってる人なら割と目視で見つけられる気がする。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
「科学者は100%安全だと保証できないものは動かしてはならない」、科学者「えっ」、プログラマ「えっ」
Linuxはposix準拠ではない (スコア:0)
argv[0]にファイル名が入っていることはposixで明言されているが、Linuxでは慣習扱い。
linux man pageのexecve(2),exec(3)でもそう書いてある。
Linuxをposix準拠だと思い込み、しっかりlinux man pageを読まなかったのが悪い。
Re:Linuxはposix準拠ではない (スコア:1)
この件はargv[1]の内容を無条件に読んでしまう脆弱性で、argv[0]に何が入っているかは関係ないのだが
Re: (スコア:0)
そうすると、ストーリーの「常に 1 以上として扱うため、引数リスト (argv) が空の状態でも」は間違い、ってことだな。「常に 1 より大きいとして扱うため、」と書くべきか。
Re: (スコア:0)
でもリンク先の修正をみると、argc1の場合に対処してるよ。
Re: (スコア:0)
「常に 1 以上として扱うため、引数リスト (argv) が空の状態でも」は正しい。
argc==0でもargv[1]を読んでしまう。execve()を使うと可能だそうだ。
Re: (スコア:0)
argvの配列はNULLで終端されている(argv[argc]はNULLになる)ので、たとえ引数の個数(argc)がゼロ個でもargv[0]は常に有効(もちろん*argv[0]が有効とは限らないが)。だから「argv[1]の内容を無条件に読んでしまう」も「(argcを)常に 1 以上として扱うため」も正しい。
Re: (スコア:0)
つまり#4192327は
「posix準拠ならargv[0]に必ずファイル名がセットされるのでargcが0になることはありえない、Linuxだとargcが0でargv[0]に終端NULLがセットされるケースがあるためにこのようなことが起きる」
と言いたかったわけか
Re: (スコア:0)
argvを頭から呼び出して引数が何個入ってるか調べるとどうせ1万回に一回くらいヘマをやらかすので素直にargcを見たほうがいいと思う。
これなら引数の数を取り違えたせいでメモリを書き換えたり変なところを読んだりする不具合を生む確率が多分1万1千回に一回くらいにへる。
Re: (スコア:0)
配列とその要素数を別々に管理しなければならない言語を捨てたほうがいいと思う。よく反論で持ち出される組み込み(フリースタンディング環境)ではmainの存在すら保証されていないからここの議論のスコープ外だし。
Re: (スコア:0)
arg[0]に必ずファイル名が入るのか、それとも終端NULLが入っているかもしれないかは、この脆弱性に関係大有りだろ。
Re: (スコア:0)
この(Polkitの)脆弱性は、argv[1]は常に値が(最悪でも終端NULLが)入っていると仮定してアクセスしてしまったというものなので。もっと一般的な話として*argv[0]にアクセスしてしまったという脆弱性なら関係あるけど。
Re: (スコア:0)
もう少し正確に言うと、書き変えても大丈夫だと思っていた、ですな。
argv[n] を書きかえるというトリックを使ってるのは、pkexec のコードがダサい
argc=0 で呼び出されると argv[1] には environ が入ってるというのは *nix がダサい
argv** が const* const* じゃないのは main() の仕様がダサい
argv[n] で範囲外アクセス出来るのは C がダサい
世の中ダサいものばかりですね
Re: (スコア:0)
2番めは4番目の未定義動作の結果としてたまたま生じたことなので*nixのせいにするのは少々酷ではありませんかね
Re: (スコア:0)
やはりC言語は滅ばなければならないですな。
いつもの流れ。
Re: (スコア:0)
argc=0はLinux環境でしか起こらないんだから、*unix全般に広げている2番目はそもそも見当違い。
Re: (スコア:0)
C99では起きます。C89は調べていない。
Re: (スコア:0)
範囲外アクセスを許すOSに根本的な問題があるのではないでしょうか
Re: (スコア:0)
読んでいるのはあくまでargv[1]だから、argv[0]に何が入っていようが直接には関係ない。
現実にはそんな実装はまずありえないけど、argv[0]が終端NULLでもargv[1]にもNULLがセットされていれば大丈夫だったわけだから。
Re: (スコア:0)
POSIX.1-2017から削除されたって書いてあるぞ。どれくらあてになる文章かわからんけど。
https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html [opengroup.org]
まあだから、それまではargc>=1だったってことだし、argc==0みたいなことをするのは
やめようよって長々と書いてあるけど。こういう問題がおきそうだって予想してたようだね。
Re: (スコア:0)
argv、argcだからとか特別視せずに配列とその要素数が与えられてるのだから基本に忠実にできるのならそうした方が良い。
mainは呼び出し頻度的にパフォーマンスに影響しにくいし、mainをある種の外部とのインターフェースとして見て、呼び出し側をあまり信用しないという考え方に立って、(パラメータの仕様がどうあれ)型の仕様として取りうる値の範囲でちゃんとチェックすべきだと思う。
pkexec.c見たけど、輸送機械、産業機械系なんかの組込みやってる人なら割と目視で見つけられる気がする。