Commit graph

2088 commits

Author SHA1 Message Date
Andrei Zeliankou
d1cb8ab2bb Tests: added tests with abstract UNIX sockets. 2022-08-25 15:50:49 +01:00
Alejandro Colomar
7e4a8a5422 Disallowed abstract unix socket syntax in non-Linux systems.
The previous commit added/fixed support for abstract Unix domain sockets
on Linux with a leading '@' or '\0'.  To be consistent in all platforms,
treat those prefixes as markers for abstract sockets in all platforms,
and fail if abstract sockets are not supported by the platform.

That will avoid mistakes when copying a config file from a Linux system
and using it in non-Linux, which would surprisingly create a normal socket.
2022-08-18 18:58:41 +02:00
Alejandro Colomar
e2aec6686a Storing abstract sockets with @ internally.
We accept both "\u0000socket-name" and "@socket-name" as abstract
unix sockets.  The first one is passed to the kernel pristine,
while the second is transformed '@'->'\0'.

The commit that added support for unix sockets accepts both
variants, but we internally stored it in the same way, using
"\u0000..." for both.

We want to support abstract sockets transparently to the user, so
that if the user configures unitd with '@', if we receive a query
about the current configuration, the user should see the same
exact thing that was configured.  So, this commit avoids the
transformation in the internal state file, storing user input
pristine, and we only transform the '@' for a string that will
be used internally (not user-visible).

This commit (indirectly) fixes a small bug, where we created
abstract sockets with a trailing '\0' in their name due to calling
twice nxt_sockaddr_parse() on the same string.  By calling that
function only once with each copy of the string, we have fixed that
bug.
2022-08-18 18:56:24 +02:00
Alejandro Colomar
d8e0768a5b Fixed support for abstract Unix sockets.
Unix domain sockets are normally backed by files in the
filesystem.  This has historically been problematic when closing
and opening again such sockets, since SO_REUSEADDR is ignored for
Unix sockets (POSIX left the behavior of SO_REUSEADDR as
implementation-defined, and most --if not all-- implementations
decided to just ignore this flag).

Many solutions are available for this problem, but all of them
have important caveats:

- unlink(2) the file when it's not needed anymore.

  This is not easy, because the process that controls the fd may
  not be the same process that created the file, and may not have
  file permissions to remove it.

  Further solutions can be applied to that caveat:

  - unlink(2) the file right after creation.

    This will remove the pathname from the filesystem without
    closing the socket (it will continue to live until the last fd
    is closed).  This is not useful for us, since we need the
    pathname of the socket as its interface.

  - chown(2) or chmod(2) the directory that contains the socket.

    For removing a file from the filesystem, a process needs
    write permissions in the containing directory.  We could
    put sockets in dummy directories that can be chown(2)ed to
    nobody.  This could be dangerous, though, as we don't control
    the socket names.  It is our users who configure the socket
    name in their configuration, and so it's easy that they don't
    understand the many implications of not chosing an appropriate
    socket pathname.  A user could unknowingly put the socket in a
    directory that is not supposed to be owned by user nobody, and
    if we blindly chown(2) or chmod(2) the directory, we could be
    creating a big security hole.

  - Ask the main process to remove the socket.

    This would require a very complex communication mechanism with
    the main process, which is not impossible, but let's avoid it
    if there are simpler solutions.

  - Give the child process the CAP_DAC_OVERRIDE capability.

    That is one of the most powerful capabilities.  A process with
    that capability can be considered root for most practical
    aspects.  Even if the capability is disabled for most of the
    lifetime of the process, there's a slight chance that a
    malicious actor could activate it and then easily do serious
    damage to the system.

- unlink(2) the file right before calling bind(2).

  This is dangerous because another process (for example, another
  running instance of unitd(8)), could be using the socket, and
  removing the pathname from the filesystem would be problematic.
  To do this correctly, a lot of checks should be added before the
  actual unlink(2), which is error-prone, and difficult to do
  correctly, and atomically.

- Use abstract-namespace Unix domain sockets.

  This is the simplest solution, as it only requires accepting a
  slightly different syntax (basically a @ prefix) for the socket
  name, to transform it into a string starting with a null byte
  ('\0') that the kernel can understand.  The patch is minimal.

  Since abstract sockets live in an abstract namespace, they don't
  create files in the filesystem, so there's no need to remove
  them later.  The kernel removes the name when the last fd to it
  has been closed.

  One caveat is that only Linux currently supports this kind of
  Unix sockets.  Of course, a solution to that could be to ask
  other kernels to implement such a feature.

  Another caveat is that filesystem permissions can't be used to
  control access to the socket file (since, of course, there's no
  file).  Anyone knowing the socket name can access to it.  The
  only method to control access to it is by using
  network_namespaces(7).  Since in unitd(8) we're using 0666 file
  sockets, abstract sockets should be no more insecure than that
  (anyone can already read/write to the listener sockets).

- Ask the kernel to implement a simpler way to unlink(2) socket
  files when they are not needed anymore.  I've suggested that to
  the <linux-fsdevel@vger.kernel.org> mailing list, in:
<lore.kernel.org/linux-fsdevel/0bc5f919-bcfd-8fd0-a16b-9f060088158a@gmail.com/T>

In this commit, I decided to go for the easiest/simplest solution,
which is abstract sockets.  In fact, we already had partial
support.  This commit only fixes some small bug in the existing
code so that abstract Unix sockets work:

- Don't chmod(2) the socket if it's an abstract one.

This fixes the creation of abstract sockets, but doesn't make them
usable, since we produce them with a trailing '\0' in their name.
That will be fixed in the following commit.

This closes #669 issue on GitHub.
2022-08-18 18:55:14 +02:00
Alejandro Colomar
1c2f070ee2 Fixed include guard.
For consistency, use the same pattern as in the rest of the project.
2022-08-18 15:43:03 +02:00
Andrei Zeliankou
6ddf14a6c1 Tests: added test for ASGI with UNIX socket. 2022-08-16 03:12:12 +01:00
Andrei Zeliankou
c1ae86e930 Fixed UNIX sockets support for ASGI.
This change was forgotten in the original implementation 282123ba4f7b.
2022-08-16 03:11:36 +01:00
Alejandro Colomar
22c5100666 Removed dead code.
nxt_sockaddr_ntop() stopped being used in commit (git) 029942f4eb.
It has been replaced mostly by nxt_sockaddr_text().

    commit 029942f4eb
    Author: Igor Sysoev <igor@sysoev.ru>
    Date:   Wed Feb 22 15:09:59 2017 +0300

        I/O operations refactoring.

nxt_job_sockaddr_parse() stopped being used in commit (git) 794248090a.

    commit 794248090a
    Author: Igor Sysoev <igor@sysoev.ru>
    Date:   Wed Mar 4 14:04:08 2020 +0300

        Legacy upstream code removed.

Also, remove functions and types used only by those two functions:

nxt_job_sockaddr_unix_parse()
nxt_job_sockaddr_inet6_parse()
nxt_job_sockaddr_inet_parse()
nxt_job_sockaddr_parse_t
nxt_job_resolve()
nxt_job_resolve_t
2022-08-11 18:43:12 +02:00
Max Romanov
900828cc4b Fixing isolated process PID manipulation.
Registering an isolated PID in the global PID hash is wrong
because it can be duplicated.  Isolated processes are stored only
in the children list until the response for the WHOAMI message is
processed and the global PID is discovered.

To remove isolated siblings, a pointer to the children list is
introduced in the nxt_process_init_t struct.

This closes #633 issue on GitHub.
2022-08-11 13:33:46 +01:00
Alejandro Colomar
d37b76232e Put changes entry in the correct position. 2022-08-08 12:13:28 +02:00
Alejandro Colomar
c7543311ca Python: supporting UNIX sockets.
This closes #635 issue on GitHub.
2022-08-08 12:11:28 +02:00
Andrei Zeliankou
e5d835e159 Tests: added tests with UNIX sockets in "source". 2022-08-08 10:32:24 +01:00
Alejandro Colomar
418bc208d0 Rejecting non-Linux pivot_root(2).
Some non-Linux systems implement pivot_root(2), even if they
don't document that.  An example is MacOS:

$ grepc pivot_root / 2>/dev/null
.../sys/sysproto.h:3012:
int pivot_root(struct proc *, struct pivot_root_args *, int *);

Since the prototype of the syscall differs from that of Linux, we
can't use that syscall.  Let's make sure the test only detects
pivot_root(2) under Linux.  Also, rename the feature macro to make
clear that it's only about Linux's pivot_root(2).

This closes #737 issue on GitHub.
2022-08-02 19:50:10 +02:00
Alejandro Colomar
2c0888f69c Including <mntent.h> iff it exists.
With NXT_HAVE_PIVOT_ROOT, we had issues in MacOS.  Headers should
normally be included unconditionally, except of course if they
don't exist.

This fixes part of the #737 issue on GitHub.
2022-08-02 13:58:01 +02:00
Andrei Zeliankou
698680d894 Tests: added tests for the log format.
Also added tests for the following variables:
$request_line, $time_local, $bytes_sent, and $status.
2022-07-28 14:13:03 +01:00
Andrei Zeliankou
69e690affe Tests: added flags to search functions in proto.py.
Also removed unnesessary re.compile() calls.
2022-07-28 14:12:19 +01:00
Zhidao HONG
3f8cf62c03 Log: customizable access log format. 2022-07-28 11:05:04 +08:00
Zhidao HONG
8761501b48 Log: split access log from nxt_router.c.
No functional changes.
2022-07-14 11:14:20 +08:00
Zhidao HONG
2bd4a45527 Ruby: fixed segfault on SIGTERM signal.
This closes #562 issue on GitHub.
2022-07-28 11:00:15 +08:00
Alejandro Colomar
9b4b4925b3 Ruby: fixed contents of SCRIPT_NAME.
Having the basename of the script pathname was incorrect.  While
we don't have something more accurate, the best thing to do is to
have it empty (which should be the right thing most of the time).

This closes #715 issue on GitHub.

The bug was introduced in git commit
0032543fa6
'Ruby: added the Rack environment parameter "SCRIPT_NAME".'.
2022-07-27 12:46:42 +02:00
Alejandro Colomar
91ffd08d11 Fixed line removed by accident.
When fixing conflicts in the changelog, a line was removed by accident.

Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
2022-07-26 16:58:15 +02:00
Alejandro Colomar
6e36584a2e Supporting UNIX sockets in address matching.
This closes #645 issue on GitHub.

(Also moved a changelog line that was misplaced in a previous commit.)
2022-07-26 16:24:33 +02:00
Andrew Clayton
c1cea3c97d Router: avoided undefined behaviour.
In src/nxt_http_route_addr.c::nxt_http_route_addr_pattern_parse() there
was potentially undefined behaviour when shifting a 32 bit value by 32
bits, this could happen if cidr_prefix was 0.

Promote the shiftee to unsigned long long to avoid this issue.
2022-07-21 00:37:20 +01:00
Andrew Clayton
02659b1ee3 Tests: added tests for translating $dollar into a literal $.
If you need to specify a $ in a URI you can now use '$dollar' or
'${dollar}'.

Added some tests for the above to test_variables.py setting a Location
string.
2022-07-20 23:28:06 +01:00
Andrew Clayton
eebaff42ea Var: added a $dollar variable that translates to a '$'.
Allow $dollar (or ${dollar}) to translate to a literal $ to allow
support for sub-delimiters in URIs.

It is possible to have URLs like

  https://example.com/path/15$1588/9925$2976.html

and thus it would be useful to be able to specify them in various bits
of the unit config such as the location setting.

However this hadn't been possible due to $ being used to denote
variables for substitution. E.g $host.

As was noted in the below GitHub issue it was suggested by @VBart to
use $sign to represent a literal $, however I feel $dollar is more
appropriate so we have a variable named after the thing it represents,
also @tippexs found[0] that &dollar is used in HTML to represent a $, so
there is some somewhat related precedent.

(The other idea to use $$ was rejected in my original pull-request[1]
 for this issue.)

This means the above URL could be specified as

  https://example.com/path/15${dollar}1588/9925${dollar}2976.html

in the unit config.

This is done by adding a variable called 'dollar' which is loaded into
the variables hash table which translates into a literal $.

This is then handled in nxt_var_next_part() where variables are parsed
for lookup and $dollar is set for substitution by a literal '$'. Actual
variable substitution happens in nxt_var_query_finish().

[0]: https://github.com/nginx/unit/pull/693#issuecomment-1130412323
[1]: https://github.com/nginx/unit/pull/693

Closes: https://github.com/nginx/unit/issues/675
2022-07-20 23:28:02 +01:00
Andrei Zeliankou
a1cda6455f Tests: added tests for more HTTP variables. 2022-07-19 17:34:32 +01:00
Alejandro Colomar
3422e81ab6 Added missing inline keyword. 2022-07-18 19:09:30 +02:00
Alejandro Colomar
14857442c6 Added missing inline keyword. 2022-07-18 19:09:30 +02:00
Alejandro Colomar
6ba39ccf9b Fixed incorrect code.
The #endif was misplaced by accident during a refactor:
<029942f4eb>.

clang(1)'s -Wunreachable-code-break (implied by -Weverything) catches
that, but it is only produced for code compiled without support
for Unix sockets, which is probably the reason it was undetected:
no-one seems to be compiling Unit without Unix sockets support (at
least with clang(1)).
2022-07-18 19:09:30 +02:00
Alejandro Colomar
5015b05fc4 Replaced Linux syscall macros by libc macros.
User-space programs should use the SYS_*form, as documented in
syscall(2).  That also adds compatibility to non-Linux systems.
2022-07-18 19:09:30 +02:00
Alejandro Colomar
0d15cbd5b6 Removed unnecessary include.
Some OSes, as Linux, provide FIONBIO in <sys/ioctl.h>.  Others,
such as the BSDs and Illumos, provide it in <sys/filio.h>, but
they all include that header from <sys/ioctl.h>, so for this test,
we can simplify and just include <sys/ioctl.h>.
2022-07-18 19:09:30 +02:00
Alejandro Colomar
c8d9106a0d Removed code used when NXT_HAVE_POSIX_SPAWN is false.
posix_spawn(3POSIX) was introduced by POSIX.1d
(IEEE Std 1003.1d-1999), and was later consolidated in
POSIX.1-2001, requiring it in all POSIX-compliant systems.
It's safe to assume it's always available, more than 20 years
after its standardization.

Link: <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/spawn.h.html>
2022-07-18 19:09:30 +02:00
Alejandro Colomar
26a5af8591 Removed duplicate handling of './configure --help'.
That is already handled in auto/options.  It is better suited
there, since it's an option, and not a module, and also because it
makes use of variables declared there.
2022-07-18 18:33:59 +02:00
Zhidao HONG
8c5e2d5ce5 HTTP: added more variables.
This commit adds the following variables:
$remote_addr, $time_local, $request_line, $status,
$body_bytes_sent, $header_referer, $header_user_agent.
2022-07-14 04:34:05 +08:00
Andrei Zeliankou
d358b1d448 Tests: added tests for dynamic variables. 2022-07-14 11:50:41 +01:00
Zhidao HONG
45b89e3257 Var: dynamic variables support.
This commit adds the variables $arg_NAME, $header_NAME, and $cookie_NAME.
2022-07-14 04:32:49 +08:00
Zhidao HONG
7b80186f09 Var: optimization to get rid of nxt_var_cache_find().
No functional changes.
2022-07-14 04:31:36 +08:00
Timo Stark
f83aef1aab Increased readtimeout for configuration endpoint.
Closes: <https://github.com/nginx/unit/issues/676>
2022-07-02 14:44:05 +02:00
Andrei Zeliankou
a3699557a3 Tests: minor improvements.
Added "go" availability check before trying to build an application.

update_action() method used were possible and fixed bug with
the relative path determination in test_static_chroot.py.

Templates optimization and style fixes.
2022-06-30 14:40:17 +01:00
Andrew Clayton
63667e2f9c Unit: removed a useless assignment.
As was pointed out by the cppcheck[0] static code analysis utility there
was a useless assignment in nxt_unit_request_read(). The size parameter
is passed in by value and was being modified without being used again.

[0]: https://cppcheck.sourceforge.io/
2022-06-22 00:53:53 +02:00
Andrew Clayton
39819143ea Unit: avoided needlessly setting lib in nxt_unit_shm_open().
As was pointed out by the cppcheck[0] static code analysis utility, lib
was being set in nxt_unit_shm_open() regardless of platform when in fact
it's only used when (NXT_HAVE_MEMFD_CREATE || NXT_HAVE_SHM_OPEN).

Move the variable declaration & definition to be within the

  #if (NXT_HAVE_MEMFD_CREATE || NXT_HAVE_SHM_OPEN)

block.

[0]: https://cppcheck.sourceforge.io/
2022-06-22 00:30:44 +02:00
Andrew Clayton
7a286ec079 Socket: removed useless port < 1 check.
In src/nxt_sockaddr.c::nxt_job_sockaddr_inet_parse() there is a check
that port > 0 then there is a check that port < 1 || port > 65535, well
we _know_ it can't be less than 1.
2022-06-22 00:30:44 +02:00
Andrew Clayton
29c7208526 Marked a couple of variables 'const'.
As was pointed out by the cppcheck[0] static code analysis utility we
can mark a couple of variables as 'const'. This acts as a hint to the
compiler about our intentions and the compiler will tell us when we
deviate from them.

[0]: https://cppcheck.sourceforge.io/
2022-06-22 00:30:44 +02:00
Andrew Clayton
4418f99cd4 Constified numerous function parameters.
As was pointed out by the cppcheck[0] static code analysis utility we
can mark numerous function parameters as 'const'. This acts as a hint to
the compiler about our intentions and the compiler will tell us when we
deviate from them.

[0]: https://cppcheck.sourceforge.io/
2022-06-22 00:30:44 +02:00
Konstantin Pavlov
637a2006a6 Packages: cleanup targets that are not supported anymore. 2022-06-20 18:20:11 +04:00
Alejandro Colomar
c3e40ae932 Static: Fixed finding the file extension.
The code for finding the extension made a few assumptions that are
no longer true.  It didn't account for pathnames that didn't
contain '/', including the empty string, or the NULL string.  That
code was used with "share", which always had a '/', but now it's
also used with "index", which should not have a '/' in it.

This fix works by limiting the search to the beginning of the
string, so that if no '/' is found in it, it doesn't continue
searching before the beginning of the string.

This also happens to work for NULL.  It is technically Undefined
Behavior, as we rely on `NULL + 0 == NULL` and `NULL - NULL == 0`.
But that is the only sane behavior for an implementation, and all
existing POSIX implementations will Just Work for this code.

Relying on this UB is useful, because we don't need to add an
explicit check for NULL, and therefore we have faster code.
Although the current code can't have a NULL, I expect that when we
add support for variables in the index, it will be NULL in some
cases.

Link: <https://stackoverflow.com/q/67291052/6872717>

The same code seems to be defined behavior in C++, which normally
will share implementation in the compiler for these cases, and
therefore it is really unlikely to be in trouble.

Link: <https://stackoverflow.com/q/59409034/6872717>
2022-06-21 12:47:01 +02:00
Konstantin Pavlov
d220eb2996 Packages: dropped /etc/unit directory.
It's never used.
2022-06-20 10:53:24 +04:00
Konstantin Pavlov
e42c52cff6 Switched changelogs to packaging alias instead of personal emails. 2022-06-20 18:21:43 +04:00
Zhidao HONG
045c05e468 Tests: forwarded header replacement tests. 2022-06-20 17:19:35 +08:00
Zhidao HONG
9d2672a701 Router: forwared header replacement. 2022-06-20 13:22:13 +08:00