Solaris11.4で奇妙な問題が発生しました。
次のようなコードをPerlから実行すると問題が発生します
my $emptystring = "";
syswrite STDOUT, $emptystring;
空の変数を使用してsyswrite呼び出しを実行すると、OpenSSHセッションが強制終了されます 🙁
この問題は私たちにとって新しいものであり、Solaris11.3からSolaris11.4およびOpenSSH8.1への移行後に発生します。 (以前の7.9バージョンでは、問題はありません)
このエラーは、出力が標準出力の場合にのみ発生します 。スクリプトの出力がファイルにリダイレクトされる場合、すべてが正常に機能します
スクリプトがtruss
でトレースされている場合 エラーはwrite
で発生します このように電話してください:
23886: write(1, 0x004B6450, 0) = 0
表示されている書き込み呼び出しは、すべてが正常である場合、エラーが発生した場合にセッションが強制終了され、トラス出力が停止され、この行以降はすべて表示されません。
詳細: Solaris 11.3用にコンパイルされたバイナリをテストしましたが、動作します。どうやら問題はコンパイルに起因しているようですが、理由はまだわかりません…。続行中…
詳細: ラコンパイルの間に顕著な違いはありません。 サーバーOpenSSHのログ 空の値がEOFと見なされることを示す 、次の画像でわかるように、このバグのあるOpenSSHと正しく動作する別のOpenSSHの違いを示しています。
それを示す線は次のとおりです:
debug2: channel 0: read<=0 rfd 16 len 0
debug2: channel 0: read failed
debug2: channel 0: chan_shutdown_read (i0 o0 sock -1 wfd 16 efd -1 [closed])
debug2: channel 0: input open -> drain
debug2: channel 0: ibuf empty
debug2: channel 0: send eof
debug3: send packet: type 96
debug2: channel 0: input drain -> closed
何かアイデアはありますか?
承認された回答:
解決策が見つかりました! 🙂要するに、Cフラグを設定する必要がありますPTY_ZEROREAD
コンパイルの構成フェーズで 。
channels.c
内 エラーがスローされた場所を確認できるソースコードのファイル…
#ifndef PTY_ZEROREAD
if (len <= 0) {
#else
if ((!c->isatty && len <= 0) ||
(c->isatty && (len < 0 || (len == 0 && errno != 0)))) {
#endif
debug2("channel %d: read<=0 rfd %d len %zd",
c->self, c->rfd, len);
if (c->type != SSH_CHANNEL_OPEN) {
debug2("channel %d: not open", c->self);
chan_mark_dead(ssh, c);
return -1;
} else {
chan_read_failed(ssh, c);
}
return -1;
}
そして、コンパイルフラグが PTY_ZEROREAD
であることがわかります。 長さゼロのメッセージが端末でどのように扱われるかを変更します。
この問題を解決するには、configure
コマンドは、次のコマンドの最後の行に示されているように、Cフラグを設定して実行する必要があります。
./configure --with-zlib \
--with-pam \
--with-md5-passwords \
CFLAGS="-DPTY_ZEROREAD=1"