我们在 Solaris 11.4 中遇到了一个奇怪的问题。
当从 Perl 运行以下代码时会出现问题
my $emptystring = "";
syswrite STDOUT, $emptystring;
使用空变量执行 syswrite 调用会导致OpenSSH 会话被终止:-(
这个问题对我们来说是新问题,它是在从 Solaris 11.3 迁移到 Solaris 11.3 后出现的Solaris 11.4 和 OpenSSH 8.1(7.9之前的版本不存在这个问题)
出现此错误仅当输出是标准输出时. 如果脚本的输出重定向到文件,则一切正常
如果跟踪脚本并在如下调用truss
中发生错误:write
23886: write(1, 0x004B6450, 0) = 0
显示的写入调用是在一切正常的情况下进行的,当出现错误时,会话将被终止,桁架输出将停止,此行之后的所有内容都不会显示。
更多信息:我们已经测试了为 Solaris 11.3 编译的二进制文件,它们可以工作!所以显然问题来自我们的编译,但我们还不知道为什么......继续......
更多信息:la编译没有显着差异。这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
任何想法?
答案1
找到解决方案了! :-) 简而言之,我们必须设置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"