Skip to content

transport-haproxy.c - Bail out Error. Code should not be reached #5516

@Damianv99

Description

@Damianv99

Hi Everyone,

It looks like since lib/transport/transport-haproxy.c was implemented, you have the possibility to run into the scenario described below.
commit hash: 4e9dae7

syslog-ng

Version of syslog-ng

syslog-ng 4 (4.10.1)

Platform

Ubuntu 22.04 jammy

Debug bundle

Syslog-NG DEBUg buNdle generator
Start environment detection
Linux-type FHS detected
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.5 LTS
Release:        22.04
Codename:       jammy

Operating System Name: Linux

Debian specific checks
Check package files integrity
??5?????? c /etc/syslog-ng/syslog-ng.conf
Package syslog-ng-core files are intact
Package syslog-ng-mod-xml-parser files are intact
list syslog-related packages

Start general info collection
System's full uname: Linux syslog-server 5.15.0-157-generic #167-Ubuntu SMP Wed Sep 17 21:35:53 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Getting network-interface information: Success
Getting network routes: Success
Getting DNS resolution-related information: Done
List all processes
Mount and disk free info collection

Start Syslog-specific info collection
Copy configuration files from /etc/syslog-ng
134 blocks
Copy SCL configuration files
1 block
Gathering PKI information... done.
SVpid: 1 SNGpid: 193531 Chpids:
Syslog-ng's exact version: syslog-ng 4 (4.10.1)
/usr/sbin/syslog-ng-ctl stats
/usr/sbin/syslog-ng-ctl query get *
/usr/sbin/syslog-ng-ctl show-license-info
/usr/sbin/syslog-ng-ctl credentials status
33 blocks
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libglib-2.0.so.0
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libgmodule-2.0.so.0
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libpcre2-8.so.0
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libsystemd.so.0
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libssl.so.3
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libcrypto.so.3
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/liburing.so.2
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libzstd.so.1
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/liblz4.so.1
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libgcrypt.so.20
Detecting init system: systemd detected...
Generating second batch of statistics
/usr/sbin/syslog-ng-ctl stats
/usr/sbin/syslog-ng-ctl query get *

Generating hashes... done.
Debug Bundle generation: Done.
tar: ./var/syslog-ng.ctl: socket ignored

Issue

Failure

ERROR:../../lib/transport/transport-haproxy.c:535:_save_addresses: code should not be reached
Bail out! ERROR:../../lib/transport/transport-haproxy.c:535:_save_addresses: code should not be reached 
syslog-ng.service: Main process exited, code=killed, status=6/ABRT
syslog-ng.service: Failed with result 'signal'.

Steps to reproduce

Configure HAProxy to forward Syslog events to your Syslog-ng server using send-proxy-v2 specifically.
E.G.
server syslog2 1923.168.1.2:514 send-proxy-v2
No health check configuration required for this to reproduce the issue.
I am using HAProxy version 3.0 here.

Enable Proxy Protocol for your network() source:

source s_tcp_pp {
    channel {
        source {
            network(
                port(514)
                ip(0.0.0.0)
                transport("proxied-tcp")
                max-connections(100)
                flags(syslog-protocol)
            );
        };
    };
};

HAProxy will send a packet/s to your Syslog-ng server that contains the following payload, which causes the bail out error.
0d0a 0d0a 000d 0a51 5549 540a 2000 0000

In HAProxy's proxy protocol document under the section titled: '2.2. Binary header format (version 2)', it describes the header in question.
https://www.haproxy.org/download/3.0/doc/proxy-protocol.txt
'The lowest four bits represents the command' seems to indicate a 'LOCAL' command was sent and no address family included either, which I believe might be causing g_assert_not_reached() to trigger in transport-haproxy.c :535

In my testing, I seem to be able to trigger payload being sent by either restarting the HAProxy or Syslog-ng service.

Some more testing I did to make 100% sure it is actually this payload causing the problem:
I just configured my iptables on my Syslog-ng server to filter out and drop packets that contain it.
E.G.
-A INPUT -p tcp -m tcp --dport 514 -m string --hex-string "|515549540a20000000|" --algo bm --to 65535 -j DROP
It then drops the packet and Syslog-ng does not run into the error.

I will be doing some more testing by spinning up another instance of HAProxy that I can install the latest version on (3.2 stable) and running through a couple more scenarios.

Configuration

@version: 4.10
@include "scl.conf"

# Syslog-ng configuration file, compatible with default Debian syslogd
# installation.

# First, set some global options.
options { chain_hostnames(off); flush_lines(0); use_dns(no); use_fqdn(no);
          dns_cache(no); owner("root"); group("adm"); perm(0640);
          stats(freq(0)); bad_hostname("^gconfd$");
};

########################
# Sources
########################
# This is the default behavior of sysklogd package
# Logs may come from unix stream, but not from another machine.
#
source s_src {
       system();
       internal();
};

# If you wish to get logs from remote machine you should uncomment
# this and comment the above source line.
#
#source s_net { tcp(ip(127.0.0.1) port(1000)); };

########################
# Destinations
########################
# First some standard logfile
#
destination d_auth { file("/var/log/auth.log"); };
destination d_cron { file("/var/log/cron.log"); };
destination d_daemon { file("/var/log/daemon.log"); };
destination d_kern { file("/var/log/kern.log"); };
destination d_lpr { file("/var/log/lpr.log"); };
destination d_mail { file("/var/log/mail.log"); };
destination d_syslog { file("/var/log/syslog"); };
destination d_user { file("/var/log/user.log"); };
destination d_uucp { file("/var/log/uucp.log"); };

# This files are the log come from the mail subsystem.
#
destination d_mailinfo { file("/var/log/mail.info"); };
destination d_mailwarn { file("/var/log/mail.warn"); };
destination d_mailerr { file("/var/log/mail.err"); };

# Logging for INN news system
#
destination d_newscrit { file("/var/log/news/news.crit"); };
destination d_newserr { file("/var/log/news/news.err"); };
destination d_newsnotice { file("/var/log/news/news.notice"); };

# Some 'catch-all' logfiles.
#
destination d_debug { file("/var/log/debug"); };
destination d_error { file("/var/log/error"); };
destination d_messages { file("/var/log/messages"); };

# The root's console.
#
destination d_console { usertty("root"); };

# Virtual console.
#
destination d_console_all { file(`tty10`); };

# The named pipe /dev/xconsole is for the nsole' utility.  To use it,
# you must invoke nsole' with the -file' option:
#
#    $ xconsole -file /dev/xconsole [...]
#
destination d_xconsole { pipe("/dev/xconsole"); };

# Send the messages to an other host
#
#destination d_net { tcp("127.0.0.1" port(1000) log_fifo_size(1000)); };

# Debian only
destination d_ppp { file("/var/log/ppp.log"); };

########################
# Filters
########################
# Here's come the filter options. With this rules, we can set which
# message go where.

filter f_dbg { level(debug); };
filter f_info { level(info); };
filter f_notice { level(notice); };
filter f_warn { level(warn); };
filter f_err { level(err); };
filter f_crit { level(crit .. emerg); };

filter f_debug { level(debug) and not facility(auth, authpriv, news, mail); };
filter f_error { level(err .. emerg) ; };
filter f_messages { level(info,notice,warn) and
                    not facility(auth,authpriv,cron,daemon,mail,news); };

filter f_auth { facility(auth, authpriv) and not filter(f_debug); };
filter f_cron { facility(cron) and not filter(f_debug); };
filter f_daemon { facility(daemon) and not filter(f_debug); };
filter f_kern { facility(kern) and not filter(f_debug); };
filter f_lpr { facility(lpr) and not filter(f_debug); };
filter f_local { facility(local0, local1, local3, local4, local5,
                        local6, local7) and not filter(f_debug); };
filter f_mail { facility(mail) and not filter(f_debug); };
filter f_news { facility(news) and not filter(f_debug); };
filter f_syslog3 { not facility(auth, authpriv, mail) and not filter(f_debug); };
filter f_user { facility(user) and not filter(f_debug); };
filter f_uucp { facility(uucp) and not filter(f_debug); };

filter f_cnews { level(notice, err, crit) and facility(news); };
filter f_cother { level(debug, info, notice, warn) or facility(daemon, mail); };

filter f_ppp { facility(local2) and not filter(f_debug); };
filter f_console { level(warn .. emerg); };

########################
# Log paths
########################
log { source(s_src); filter(f_auth); destination(d_auth); };
log { source(s_src); filter(f_cron); destination(d_cron); };
log { source(s_src); filter(f_daemon); destination(d_daemon); };
log { source(s_src); filter(f_kern); destination(d_kern); };
log { source(s_src); filter(f_lpr); destination(d_lpr); };
log { source(s_src); filter(f_syslog3); destination(d_syslog); };
log { source(s_src); filter(f_user); destination(d_user); };
log { source(s_src); filter(f_uucp); destination(d_uucp); };

log { source(s_src); filter(f_mail); destination(d_mail); };
#log { source(s_src); filter(f_mail); filter(f_info); destination(d_mailinfo); };
#log { source(s_src); filter(f_mail); filter(f_warn); destination(d_mailwarn); };
#log { source(s_src); filter(f_mail); filter(f_err); destination(d_mailerr); };

log { source(s_src); filter(f_news); filter(f_crit); destination(d_newscrit); };
log { source(s_src); filter(f_news); filter(f_err); destination(d_newserr); };
log { source(s_src); filter(f_news); filter(f_notice); destination(d_newsnotice); };
#log { source(s_src); filter(f_cnews); destination(d_console_all); };
#log { source(s_src); filter(f_cother); destination(d_console_all); };

#log { source(s_src); filter(f_ppp); destination(d_ppp); };

log { source(s_src); filter(f_debug); destination(d_debug); };
log { source(s_src); filter(f_error); destination(d_error); };
log { source(s_src); filter(f_messages); destination(d_messages); };

log { source(s_src); filter(f_console); destination(d_console_all);
                                    destination(d_xconsole); };
log { source(s_src); filter(f_crit); destination(d_console); };

# All messages send to a remote site
#
#log { source(s_src); destination(d_net); };

###
# Include all config files in /etc/syslog-ng/conf.d/
###
@include "/etc/syslog-ng/conf.d/*.conf"

Input and output logs (if possible)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions