Dovecot 2.3.6 on Solaris10: build issues, segfaults
Hopefully, there is some fix for issue 3 which is beyond my skill to fix.
Issue 1) Need recent gcc version
Building Dovecot versions <=2.2.x using gcc 3.4.4 worked,
but this gcc version fails to build 2.3.x properly: symptoms
include compile failures and executable crashes that depended
on the amount of optimization used, which is usually a sign of
compiler bugs. (It could also be issue 3 in disguise.)
Either way, I updated to gcc 9.1.0.
Issue 2) Cannot build with --enable-hardening
Using gcc 9.1.0, "configure" step fails because fd passing was
broken, but the real problem was a compilation failure when
"--enable-hardening" is used. Demonstration:
# echo 'int main(){char a[1]; strcpy(a,a);} ' | gcc -w -fstack-protector-strong -x c -
Undefined first referenced
symbol in file
__stack_chk_guard /var/tmp//cc12L9zV.o (symbol scope specifies local binding)
ld: fatal: symbol referencing errors. No output written to a.out
collect2: error: ld returned 1 exit status
I'm not sure if this is a Solaris10 fumble, but configuring
"--disable-hardening" removes the "-fstack-protector-strong"
compiler option, which resolves this issue.
Issue 3) dovecot/doveconf segfaults on startup
It crashes here while processing dovecot.conf, as does "doveconf"
(settings-parser.c:1519 in setting_copy())
*dest_size = *src_size;
It appears *src_size is not an 8-byte address aligned (0x5597c).
It inherits this value from the calling routine as the sum of
"set" (8-byte aligned) + "def->offset"=20 => misaligned address.
(settings-parser.c:1597 in settings_dup_full())
src = CONST_PTR_OFFSET(set, def->offset);
(gdb) p set
$2 = (const void *) 0x55968
(gdb) p *def
$3 = {type = SET_SIZE, key = 0x2d548 "submission_max_mail_size", offset = 20, list_info = 0x0}
(gdb) bt full
#0 0xff190690 in setting_copy (type=SET_SIZE, src=0x5798c, dest=0xf7ed4, pool=0xf29a0,
keep_values=false) at settings-parser.c:1519
src_size = 0x5798c
dest_size = 0xf7ed4
__func__ = "setting_copy"
#1 0xff190bc4 in settings_dup_full (info=0x2d9ac <submission_setting_parser_info>, set=0x57978,
pool=0xf29a0, keep_values=false) at settings-parser.c:1600
def = 0x2d7d4 <submission_setting_defines+80>
src = 0x5798c
dest_set = 0xf7ec0
dest = 0xf7ed4
children = 0x2c
i = 1105688
count = 4279837964
#2 0xff192724 in settings_parser_dup (old_ctx=0x9ec08, new_pool=0xf29a0) at settings-parser.c:1946
new_ctx = 0x10def0
iter = 0x0
links = {_table = 0xa23c0, _key = 0xa23c0, _keyp = 0xa23c0, _const_key = 0xa23c0,
_value = 0xa23c0, _valuep = 0xa23c0}
new_link = 0x10b488
value = 0x0
key = 0x0
i = 0
parser_pool = 0x10ded8
keep_values = false
__func__ = "settings_parser_dup"
#3 0x0001fc0c in config_filter_parsers_get (ctx=0x657a8, pool=0xf29a0, modules=0x0,
filter=0x583e8, parsers_r=0xffbff9c4, output_r=0xffbff9bc, error_r=0xffbffa44)
at config-filter.c:372
src = 0xf29d8
dest = 0xf2a48
error = 0x0
error_p = 0x52cfc
i = 26
count = 33
__func__ = "config_filter_parsers_get"
#4 0x00021be4 in config_all_parsers_check (ctx=0xffbffac8, new_filter=0x657a8, error_r=0xffbffa44)
at config-parser.c:441
parsers = 0x58180
tmp_parsers = 0x4
output = {specific_services = 0xf2a20, service_uses_local = false,
service_uses_remote = false, used_local = false, used_remote = false,
permission_denied = false}
i = 0
count = 3
ssl_set = 0x4 <error: Cannot access memory at address 0x4>
global_ssl_set = 0x32188 ""
tmp_pool = 0xf29a0
ssl_warned = false
ret = 0
__func__ = "config_all_parsers_check"
#5 0x00022ec8 in config_parse_finish (ctx=0xffbffac8, error_r=0xffbffb98) at config-parser.c:747
new_filter = 0x657a8
error = 0x33c22 "/user=%s"
ret = 0
#6 0x00024230 in config_parse_file (path=0x50468 "/local/dovecot/etc/dovecot/dovecot.conf",
expand_values=false, modules=0x0, error_r=0xffbffb98) at config-parser.c:1064
root = {prev = 0x0, input = 0x0, path = 0x50468 "/local/dovecot/etc/dovecot/dovecot.conf",
linenum = 400}
ctx = {pool = 0x52b58, path = 0x50468 "/local/dovecot/etc/dovecot/dovecot.conf",
, all_parsers = {arr = {buffer = 0x58160, element_size = 4}, v = 0x58160,
v_modifiable = 0x58160}, root_parsers = 0x52b70, cur_section = 0x58388,
cur_input = 0x0, str = 0x58458, pathlen = 0, section_counter = 6, error = 0x0,
old = 0x58580, seen_settings = {_table = 0x0, _key = 0x0, _keyp = 0x0, _const_key = 0x0,
_value = 0x0, _valuep = 0x0}, filter = 0x0, expand_values = false, hide_errors = false}
i = 33
count = 33
key = 0x0
value = 0x0
full_line = 0x0
type = CONFIG_LINE_TYPE_SKIP
line = 0x0
fd = -1
ret = 0
handled = false
#7 0x000188dc in main (argc=1, argv=0xffbffc94) at doveconf.c:979
master_service_flags = (MASTER_SERVICE_FLAG_STANDALONE | MASTER_SERVICE_FLAG_NO_INIT_DATASTACK_FRAME | MASTER_SERVICE_FLAG_DONT_SEND_STATS)
scope = CONFIG_DUMP_SCOPE_ALL
orig_config_path = 0x46300 "/local/dovecot/etc/dovecot/dovecot.conf"
config_path = 0x50468 "/local/dovecot/etc/dovecot/dovecot.conf"
module = 0x1c00 <error: Cannot access memory at address 0x1c00>
module_names = {arr = {buffer = 0x46338, element_size = 4}, v = 0x46338,
v_modifiable = 0x46338}
filter = {service = 0x0, local_name = 0x0, local_host = 0x0, remote_host = 0x0,
local_net = {family = 0, u = {ip6 = {_S6_un = {_S6_u8 = '\000' <repeats 15 times>,
_S6_u32 = {0, 0, 0, 0}, __S6_align = 0}}, ip4 = {S_un = {S_un_b = {
s_b1 = 0 '\000', s_b2 = 0 '\000', s_b3 = 0 '\000', s_b4 = 0 '\000'}, S_un_w = {
s_w1 = 0, s_w2 = 0}, S_addr = 0}}}}, remote_net = {family = 0, u = {ip6 = {
_S6_un = {_S6_u8 = '\000' <repeats 15 times>, _S6_u32 = {0, 0, 0, 0},
__S6_align = 0}}, ip4 = {S_un = {S_un_b = {s_b1 = 0 '\000', s_b2 = 0 '\000',
s_b3 = 0 '\000', s_b4 = 0 '\000'}, S_un_w = {s_w1 = 0, s_w2 = 0},
S_addr = 0}}}}, local_bits = 0, remote_bits = 0}
wanted_modules = 0x0
error = 0xfef47940 <_uberdata> ""
exec_args = 0x0
setting_name_filters = 0x0
i = 5
c = -1
ret = -4195172
ret2 = 4
config_path_specified = false
expand_vars = false
hide_key = false
parse_full_config = false
simple_output = false
dump_defaults = false
host_verify = false
print_plugin_banner = true
hide_passwords = true
Joseph Tam <jtam.home@gmail.com>
On 9.7.2019 3.02, Joseph Tam via dovecot wrote:
Hopefully, there is some fix for issue 3 which is beyond my skill to fix.
Issue 1) Need recent gcc version
Building Dovecot versions <=2.2.x using gcc 3.4.4 worked, but this gcc version fails to build 2.3.x properly: symptoms include compile failures and executable crashes that depended on the amount of optimization used, which is usually a sign of compiler bugs. (It could also be issue 3 in disguise.)
Either way, I updated to gcc 9.1.0.
Issue 2) Cannot build with --enable-hardening
Using gcc 9.1.0, "configure" step fails because fd passing was broken, but the real problem was a compilation failure when "--enable-hardening" is used. Demonstration:
# echo 'int main(){char a[1]; strcpy(a,a);} ' | gcc -w -fstack-protector-strong -x c - Undefined first referenced symbol in file __stack_chk_guard /var/tmp//cc12L9zV.o (symbol scope specifies local binding) ld: fatal: symbol referencing errors. No output written to a.out collect2: error: ld returned 1 exit status
I'm not sure if this is a Solaris10 fumble, but configuring "--disable-hardening" removes the "-fstack-protector-strong" compiler option, which resolves this issue.
Issue 3) dovecot/doveconf segfaults on startup
It crashes here while processing dovecot.conf, as does "doveconf"
Just to be sure ...
You did gmake clean; ./configure <opts>; gmake
We'll look at the 3rd issue, the 2nd issue looks really odd, and I'm verging on compiler bug there. As for 1st, isn't gcc 3 rather old?
Aki
On Tue, 9 Jul 2019, Aki Tuomi wrote:
Hopefully, there is some fix for issue 3 which is beyond my skill to fix.
Issue 1) Need recent gcc version Issue 2) Cannot build with --enable-hardening Issue 3) dovecot/doveconf segfaults on startup
Just to be sure ...
You did gmake clean; ./configure <opts>; gmake
I did a bazillion iterations of "make distclean; make; make install", so it's no problem to do it once more to make sure.
We'll look at the 3rd issue,
Thank you.
the 2nd issue looks really odd, verging on compiler bug there.
Googling "-fstack-protector-strong" and "__stack_chk_guard" brings up this issue often.
As for 1st, isn't gcc 3 rather old?
Yeah. I hoped we could retire together, but gcc3 violated the adage "if it ain't broke, don't fix it". It broke, so ...
Thanks again for looking into this.
Joseph Tam <jtam.home@gmail.com>
On 09/07/2019 06:35, Aki Tuomi via dovecot wrote:
As for 1st, isn't gcc 3 rather old?
As is Solaris 10. Solaris 10 predates gcc4 and comes/came with gcc3. No one says we have keep using the system gcc3 exclusively. 9.1.0 works too.
Solaris 10 03/05 = March 2005, release January 31, 2005 [1] gcc 4.0.0: April 20, 2005 [2]
$ pkginfo -l SUNWgcc PKGINST: SUNWgcc NAME: gcc - The GNU C compiler CATEGORY: system ARCH: i386 VERSION: 11.10.0,REV=2005.01.08.01.09 BASEDIR: / VENDOR: Oracle Corporation DESC: GNU C - The GNU C compiler 3.4.3 PSTAMP: sfw10-patch-x20121120060015 ...
On 9 Jul 2019, at 3.02, Joseph Tam via dovecot <dovecot@dovecot.org> wrote:
Issue 3) dovecot/doveconf segfaults on startup
It crashes here while processing dovecot.conf, as does "doveconf"
(settings-parser.c:1519 in setting_copy()) *dest_size = *src_size;
This is correct code.
It appears *src_size is not an 8-byte address aligned (0x5597c). It inherits this value from the calling routine as the sum of "set" (8-byte aligned) + "def->offset"=20 => misaligned address.
(settings-parser.c:1597 in settings_dup_full()) src = CONST_PTR_OFFSET(set, def->offset); (gdb) p set $2 = (const void *) 0x55968 (gdb) p *def $3 = {type = SET_SIZE, key = 0x2d548 "submission_max_mail_size", offset = 20, list_info = 0x0}
This is unexpected. But I don't see how it's a Dovecot bug. It seems as if your compiler doesn't do padding correctly and then crashes because it didn't do it correctly. I guess you're compiling this as 32bit? Is size_t 32bit or 64bit?
Can you try with the below small test program if it prints the same 20?
#include <stdio.h> #include <stdbool.h> #include <stddef.h>
#define in_port_t unsigned short
struct submission_settings { bool verbose_proctitle; const char *rawlog_dir;
const char *hostname;
const char *login_greeting;
const char *login_trusted_networks;
/* submission: */
size_t submission_max_mail_size;
unsigned int submission_max_recipients;
const char *submission_client_workarounds;
const char *submission_logout_format;
/* submission backend: */
const char *submission_backend_capabilities;
/* submission relay: */
const char *submission_relay_host;
in_port_t submission_relay_port;
bool submission_relay_trusted;
const char *submission_relay_user;
const char *submission_relay_master_user;
const char *submission_relay_password;
const char *submission_relay_ssl;
bool submission_relay_ssl_verify;
const char *submission_relay_rawlog_dir;
unsigned int submission_relay_max_idle_time;
unsigned int submission_relay_connect_timeout;
unsigned int submission_relay_command_timeout;
/* imap urlauth: */
const char *imap_urlauth_host;
in_port_t imap_urlauth_port;
int parsed_workarounds;
};
int main(void) { struct submission_settings set;
printf("offset = %ld\n", offsetof(struct submission_settings, submission_max_mail_size));
printf("size = %ld\n", sizeof(set.submission_max_mail_size));
return 0;
}
On Wed, 10 Jul 2019, Timo Sirainen wrote:
This is unexpected. But I don't see how it's a Dovecot bug. It seems as if your compiler doesn't do padding correctly and then crashes because it didn't do it correctly. I guess you're compiling this as 32bit?
Yes, 32-bit.
Is size_t 32bit or 64bit? ... Can you try with the below small test program if it prints the same 20? ...
(Output without compile flags -m64)
offset = 20
size = 4
(Output with compile flags -m64)
offset = 40
size = 8
Same output whether I use gcc 9.1.0 or Solaris c99.
I'll try building 64bit executables but I think that means I'll have to build 64bit versions of third-party libraries.
Joseph Tam <jtam.home@gmail.com>
On 09/07/2019 01:02, Joseph Tam via dovecot wrote:
Issue 2) Cannot build with --enable-hardening
Using gcc 9.1.0, "configure" step fails because fd passing was broken, but the real problem was a compilation failure when "--enable-hardening" is used. Demonstration:
See: https://dovecot.org/pipermail/dovecot/2019-January/114121.html
Issue 3) dovecot/doveconf segfaults on startup
It crashes here while processing dovecot.conf, as does "doveconf" (settings-parser.c:1519 in setting_copy()) *dest_size = *src_size; It appears *src_size is not an 8-byte address aligned (0x5597c). It inherits this value from the calling routine as the sum of "set" (8-byte aligned) + "def->offset"=20 => misaligned address.
32 bit or 64bit? cflags? I use 32 bit cc 12.6 and have no problem. My test with gcc 9.1.0 didn't dump core either.
participants (4)
-
Aki Tuomi
-
James
-
Joseph Tam
-
Timo Sirainen