graygnuorg / pound

Light-weight reverse proxy, load balancer and HTTPS front-end for Web servers.
GNU General Public License v3.0
43 stars 13 forks source link

Segmentation fault with pound 4.11 on OpenSUSE #24

Closed geminixdev closed 7 months ago

geminixdev commented 8 months ago

I compiled pound 4.11 on some OpenSUSE servers, and installed it.

When running pound and pointing it to the configuration file, it results in: Segmentation fault (core dumped).

This happens already when verifying the configuration file with "-c", example

 /usr/local/sbin/pound -c -f /path/to/my/poundconfiguration.cfg
Segmentation fault (core dumped)

Valgrind gives some details:

==11314== Memcheck, a memory error detector
==11314== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11314== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==11314== Command: /usr/sbin/pound.new -c -f /etc/pound.cfg
==11314==
==11314== Invalid read of size 4
==11314==    at 0x40E7B0: parse_config_file (config.c:5134)
==11314==    by 0x40ECD5: config_parse (config.c:5354)
==11314==    by 0x405813: main (pound.c:1000)
==11314==  Address 0x10 is not stack'd, malloc'd or (recently) free'd
==11314==
==11314==
==11314== Process terminating with default action of signal 11 (SIGSEGV)
==11314==  Access not within mapped region at address 0x10
==11314==    at 0x40E7B0: parse_config_file (config.c:5134)
==11314==    by 0x40ECD5: config_parse (config.c:5354)
==11314==    by 0x405813: main (pound.c:1000)
...
==11314== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

My crystal ball told me that pound expects a configuration file, even if empty, at /usr/local/etc/pound.cfg Based on that I found a workaround:

sudo mkdir /usr/local/etc
sudo touch /usr/local/etc/pound.cfg

and no more Segmentation fault.

I assume that at installation the file pound.cfg was not created because there was no directory yet at /usr/local/etc.

I suggest to either remove the requirement of having something at /usr/local/etc/pound.cfg or to make sure it is created at make install.

graygnuorg commented 8 months ago

==11314== Invalid read of size 4 ==11314== at 0x40E7B0: parse_config_file (config.c:5134) ==11314== by 0x40ECD5: config_parse (config.c:5354) ==11314== by 0x405813: main (pound.c:1000)

I need to have the content of /etc/pound.cfg to debug this. You can send it to my private email, if you prefer.

My crystal ball told me that pound expects a configuration file, even if

Your crystal ball is wrong. There is no such assumption.

Regards. Sergey

geminixdev commented 8 months ago

I need to have the content of /etc/pound.cfg to debug this.

It happens with any content. If there are errors it will tell the errors and segfault after that.

It also happens with a totally empty pound.cfg, or with just some basic lines, such as:

# Start pound as User with Group
User    "pound"
Group   "pound"
Threads     512
LogLevel    3
Alive       5

At first I thought the same, that it is the content of the config file, and I took out content out of it, step by step, until it was empty. Everytime there was the same segmentation fault.

I think it has to do with that the directory /usr/local/etc does not exist yet in a standard OpenSUSE, until some custom software creates it.

You might be able to reproduce by simply deleting the directory at /usr/local/etc and then restarting pound (or even just checking a configuration file, which can be /etc/pound.cfg or anywhere).

This is the line 5134 in config.c which valgrind claims would be causing the segfault:

          if (include_wd->refcount > 0 && include_wd->fd == AT_FDCWD)

which in a very quick look seems to access a working directory.

So I checked what happens if I delete the empty /usr/local/etc/pound.cfg, and still no segfault. But if I remove the directory /usr/local/etc then there it is again, the segfault. And if I create that directory again, just it, no content, that's enough, no more segfault.

So that directory should get created by install, if needed, or better checked in a way that there is no segfault when it does not exist.

Also, thanks to keep pound alive, I use it a lot, and I love the new features you added!

graygnuorg commented 8 months ago

You might be able to reproduce by simply deleting the directory at /usr/local/etc

Ah, you mean system configuration directory! Good point! Thanks a lot. I can reproduce the bug now.

A naive fix would be to just throw an error if the directory doesn't exist. However, this might be overly strict, since that directory is not always needed or used. I'll work out a better fix and let you know.

Until then, you can use the -Winclude-dir=DIR option to work over the bug. E.g. set -Winclude-dir=/etc to use /etc as a base directory for all relative file names in your configuration, or -Wno-include-dir, to use current working directory instead. See the manpage for details.

And, while at it, a minor question: you seem to use /etc/pound.cfg as your configuration file. Why not compile pound to use that directory by default, then? E.g.: ./configure --sysconfdir=/etc?

Regards, Sergey

geminixdev commented 7 months ago

Until then, you can use the -Winclude-dir=DIR option to work over the bug. E.g. set -Winclude-dir=/etc to use /etc as a base directory for all relative file names in your configuration, or -Wno-include-dir, to use current working directory instead. See the manpage for details. And, while at it, a minor question: you seem to use /etc/pound.cfg as your configuration file. Why not compile pound to use that directory by default, then? E.g.: ./configure --sysconfdir=/etc?

Thanks, yes, /etc/pound.cfg has always been the default configuration location on OpenSUSE and Centos, when installing the pound the distribution offered. That's the main reason I use /etc/pound.cfg.

./configure --sysconfdir=/etc seems to be what I need, I will use that in future.

Thanks!