Libseccomp: バグ:seccomp_arch_add()はエンディアンの不一致で-EEXISTSを返します

作成日 2017年06月20日  ·  18コメント  ·  ソース: seccomp/libseccomp

(私の問題の説明はgolangで始まりますが、実際にはCの問題であることに注意してください。以下を参照してください)

私は今日、amd64システムでScmpFilter.AddArch(seccomp.ArchPPC)を実行するいくつかの単体テストを作成していました。 これはエラーを返しませんでしたが、アーキテクチャはフィルターに追加されませんでした(exportPFCで確認できます)。

これは簡単な再現機能です(amd64またはi386で実行する必要があります):

package main

import (
    "os"
    "github.com/seccomp/libseccomp-golang"
)

func main() {
    secFilter, err := seccomp.NewFilter(seccomp.ActKill)
    if err != nil {
        panic(err)
    }
    err = secFilter.AddArch(seccomp.ArchPPC)
    if err != nil {
        panic(err)
    }
    secFilter.ExportPFC(os.Stdout)
}

少しデバッグした後、endianの不一致がある場合、seccomp_arch_add()はEEXISTを返すことが判明しました。 db.c:db_col_db_add()には次のものがあります。

if (col->endian != 0 && col->endian != db->arch->endian)
        return -EFAULT;

golangコードは(当然のことながら)EEXISTを無視するため、私が観察した動作につながります。

seccomp_arch_add()が別のエラーコード(おそらくEINVALか何か)を返すのは理にかなっているのだろうか? これが危険すぎる場合(既存のアプリケーションを壊す可能性があるため)、より適切に文書化できる可能性があります。 私はPRを提供させていただきます。

bug prioritmedium

全てのコメント18件

これを報告してくれてありがとう、私はもっと詳しく調べる必要があります。

この@ mvo5に戻るのに時間がかかって申し訳ありませんが、

少し明確にするために、関連する現在のdb.c:db_col_db_add()は次のようになります。

        if (col->endian != 0 && col->endian != db->arch->endian)
                return -EEXIST;

...元の問題レポートの上記のバージョンは、問題を回避するためにローカルでパッチが適用されたコピーだったと思います。 とはいえ、ここで返されたエラーを変更することは合理的に聞こえます。 私たちは他のアーチ/エンディアンコードの少なくともいくつかでEDOMを使用してきましたが、それはあなたにとって合理的に聞こえますか?

@mheonはどう思いますか?

おそらく、db.c:db_col_merge()も更新する必要があるようです。

APIの観点からは、変更を加えることは間違いなく理にかなっていると思います。エラーコードのオーバーロードは、デバッグにとって常に問題があります。

libseccomp-golang側では、負のERRNO規則が維持されている限り、コードを変更する必要はありません。 AddArchに数行のコメントがあり、新しいエラーの意味を説明しているので、APIドキュメントが完成します。

Travisはまだカーネルが古すぎるため、テスト#47が再び失敗しました。 @pcmooreがしばらく前に述べたように、これを回避するために、テストにいくつかのスマートを追加しようとします。

そうでなければ、この変更からの他のすべては私の本でよく見えます

@drakenclimber 47ではなく46のテストだと思いますよね?

数か月前にライブテスト用のAPIレベルチェックを追加しましたが、bpf-simテスト用にそれが必要だとクリーンされていました...?

Travisは、上記の実行のためにテスト#47(KILL_PROCESS)を確実に実行しました。 また、今朝、マスターのHEADを健全性チェックとして別のブランチにプッシュしたときに、同じ障害が発生しました。

テスト47-live-kill_process %% 001-00001結果:失敗47-live-kill_process 3 KILL_PROCESS rc = 12

これについてはかなり前に話しましたので、私の記憶は曇っているかもしれませんが、Travisのカーネルはその機能が導入されたときに4.14より古いため、TravisにはKILL_PROCESSテストの問題があると思いました。

それとも私は夢中ですか...そして完全に覚えていませんか?

うーん、同じログを見ていますか? 私は以下のビルドとログを見ています:

...次の結果を示しています(ここでは「c」テストのみをコピーしました。「python」の結果は同じでした)。

 batch name: 46-sim-kill_process
 test mode:  c
 test type:  bpf-sim
Test 46-sim-kill_process%%001-00001 result:   ERROR 46-sim-kill_process rc=12
Test 46-sim-kill_process%%002-00001 result:   ERROR 46-sim-kill_process rc=12
Test 46-sim-kill_process%%003-00001 result:   ERROR 46-sim-kill_process rc=12
Test 46-sim-kill_process%%004-00001 result:   ERROR 46-sim-kill_process rc=12
Test 46-sim-kill_process%%005-00001 result:   ERROR 46-sim-kill_process rc=12
Test 46-sim-kill_process%%006-00001 result:   ERROR 46-sim-kill_process rc=12
 batch name: 47-live-kill_process
 test mode:  c
 test type:  live
Test 47-live-kill_process%%001-00001 result:   SKIPPED (must specify live tests)

...はい、古いカーネルにはいくつかのライブテストで問題がありますが、それは9d4f7f69714d5af80309aa1b8a6d2c8300bb6730で修正されているはずです。

FWIW、マスターブランチでの最後のTravisビルドはクリーンに実行されました:

Travisですべてが「OK」であることを確認するために、masterブランチを使用して新しいビルドをトリガーしました。

私は今、_本当に_混乱していることを認めます。 あなたのリンクは間違いなくテスト#46が問題であることを示しています。 しかし、右上隅にある[Raw Log]リンクをクリックすると、#47が失敗したことがわかります。 上にリストしたリンクについては、生のログが私をリダイレクトした場所は次のとおりです。

よく見ると、私たちは両方とも正しいと思います。

ご指摘のとおり、46はERRORを返しています。 そして、#47はFAILURE返します(これは私が最初に検索したものです)。

そして、これは要約にも表示されます。

Regression Test Summary
 tests run: 14090
 tests skipped: 114
 tests passed: 14090
 tests failed: 0
 tests errored: 12
Regression Test Summary
 tests run: 16
 tests skipped: 0
 tests passed: 14
 tests failed: 2
 tests errored: 0

3.xカーネルで起動すると、システムの1つでTravisCIの問題を再現できます。 テスト46は、 sys_chk_seccomp_action()で問題が発生することに

テスト47の問題は似ていると思いますが、その障害パスは調査しませんでした。 (APIを検証するために追加された@pcmooreの変更により、これを防ぐことができたはずですが。うーん...)

これを引き起こすためにTravisで何が変わったのか興味があります。 彼らは本当に古いカーネルにフォールバックしましたか? 私たちの側に何か?

これを処理するには、bpf-simテストにいくつかのスマートを追加する必要があるようです。 * .testsファイルに追加されたAPI列を模倣したいですか、それとも完全に何か他のことをしたいですか?

ええ、なぜ今は機能していないのか、私は本当に混乱しています。 Ubuntu 14.xxは最近本当に古いので、Travisで利用できるより新しいバージョンがあるかどうかを確認します。

Ubuntu 16.04(Xenial)が利用できるようです。試してみましょう...

コミット06f63ba691cb9df119c6759e8f0a150a2a9cbe69はUbuntu16.04に私たちをぶつけます。 この切り替えを強制したいので、PRとしてではなく、マスターブランチでこれを行っています。 ビルドが壊れた場合は修正します。

そのビルドでテストの問題が修正されたようですが、clangはエラー処理コードパスでメモリリークを検出しました。 すぐに修正します。

素晴らしい! 助けてくれてありがとう、@ pcmoore

さて、コミットf8854f990004e71ccb9955c33d88d82cdb97ea42を使用すると、クリーンな建物のマスターブランチが必要になります。 それは私の個人的なブランチでうまく機能し、現在メインビルドを待っています。

@drakenclimber上記の問題ログにこのためのパッチの準備ができているようですが、PRはまだ表示されていません-まだパッチのいくつかの問題を追跡していますか、それともPRの準備ができていますか?

これは、コミット4a35b6ea6f7c836734536420c50a2745a9e24c69で解決する必要があり、今すぐ終了します。 誰かがこれに問題を見つけた場合は、この問題を再度開くか、新しい問題を作成してください。

このページは役に立ちましたか?
0 / 5 - 0 評価