Skip to content

Commit

Permalink
Import nginx code to set process title, use it for "cinit"
Browse files Browse the repository at this point in the history
When debugging things, it's really useful to be able to see from the process
output which thing is which. Here, we're using the term "cinit" for the
in-container init.

I looked around on the internets for this - I thought systemd would have a good
implementation, but they don't do the requsite trick with malloc to ensure we
have enough space. nginx does.  Now, I also found
https://tycho.ws/blog/2015/02/setproctitle.html but their implementation
sounded way more complex.

So, going from the nginx code, I heavily edited it to drop Solaris/FreeBSD etc.
Also, to use `xmalloc` instead of their allocator, etc.

This just makes things easier to debug; there's a risk though that it's new
parsing code that is reachable in the suid case by an attacker outside; I'll do
some extra review on this if we agree to take it.
  • Loading branch information
cgwalters committed Jan 26, 2017
1 parent e3a3f15 commit 8e1b983
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Makefile-bwrap.am
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ bwrap_SOURCES = \
$(bwrap_srcpath)/network.c \
$(bwrap_srcpath)/utils.h \
$(bwrap_srcpath)/utils.c \
$(bwrap_srcpath)/ngx_setproctitle.h \
$(bwrap_srcpath)/ngx_setproctitle.c \
$(NULL)

bwrap_CFLAGS = $(AM_CFLAGS)
Expand Down
5 changes: 5 additions & 0 deletions bubblewrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "utils.h"
#include "network.h"
#include "bind-mount.h"
#include "ngx_setproctitle.h"

#ifndef CLONE_NEWCGROUP
#define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace */
Expand Down Expand Up @@ -399,6 +400,8 @@ do_init (int event_fd, pid_t initial_pid, struct sock_fprog *seccomp_prog)
/* Keep fd open to hang on to lock */
}

ngx_setproctitle ("cinit");

if (seccomp_prog != NULL &&
prctl (PR_SET_SECCOMP, SECCOMP_MODE_FILTER, seccomp_prog) != 0)
die_with_error ("prctl(PR_SET_SECCOMP)");
Expand Down Expand Up @@ -1700,6 +1703,8 @@ main (int argc,

read_overflowids ();

ngx_init_setproctitle(argc, argv);

argv0 = argv[0];

if (isatty (1))
Expand Down
135 changes: 135 additions & 0 deletions ngx_setproctitle.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright (C) 2002-2017 Igor Sysoev
* Copyright (C) 2011-2017 Nginx, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

/* walters: replaced nginx util C headers and functions with ours */
#include "ngx_setproctitle.h"
#include "utils.h"


/*
* To change the process title in Linux and Solaris we have to set argv[1]
* to NULL and to copy the title to the same place where the argv[0] points to.
* However, argv[0] may be too small to hold a new title. Fortunately, Linux
* and Solaris store argv[] and environ[] one after another. So we should
* ensure that is the continuous memory and then we allocate the new memory
* for environ[] and copy it. After this we could use the memory starting
* from argv[0] for our process title.
*
* The Solaris's standard /bin/ps does not show the changed process title.
* You have to use "/usr/ucb/ps -w" instead. Besides, the UCB ps does not
* show a new title if its length less than the origin command line length.
* To avoid it we append to a new title the origin command line in the
* parenthesis.
*/

/* The original */
static char **ngx_os_argv;
static char **ngx_os_environ;
/* A copy we make */
static int ngx_argc;
static char **ngx_argv;
extern char **environ;

static char *ngx_os_argv_last;

/* In upstream nginx, this is called early in main. However,
* I don't see a reason not to merge it with ngx_init_setproctitle()
*/
static void
ngx_save_argv(int argc, char *const *argv)
{
int i;

ngx_os_argv = (char **) argv;
ngx_argc = argc;

ngx_argv = xmalloc((argc + 1) * sizeof(char *));

for (i = 0; i < argc; i++) {
ngx_argv[i] = xstrdup(argv[i]);
}

ngx_argv[i] = NULL;
ngx_os_environ = environ;
}

void
ngx_init_setproctitle(int argc, char *const *argv)
{
char *p;
size_t size;
unsigned i;

ngx_save_argv(argc, argv);

size = 0;

for (i = 0; environ[i]; i++) {
size += strlen(environ[i]) + 1;
}

p = xmalloc(size);

ngx_os_argv_last = ngx_os_argv[0];

for (i = 0; ngx_os_argv[i]; i++) {
if (ngx_os_argv_last == ngx_os_argv[i]) {
ngx_os_argv_last = ngx_os_argv[i] + strlen(ngx_os_argv[i]) + 1;
}
}

for (i = 0; environ[i]; i++) {
if (ngx_os_argv_last == environ[i]) {

size = strlen(environ[i]) + 1;
ngx_os_argv_last = environ[i] + size;

strncpy(p, environ[i], size);
environ[i] = (char *) p;
p += size;
}
}

ngx_os_argv_last--;
}

void
ngx_setproctitle(char *title)
{
char *p;

ngx_os_argv[1] = NULL;

p = stpncpy(ngx_os_argv[0], "bwrap: ",
ngx_os_argv_last - ngx_os_argv[0]);

p = stpncpy(p, title, ngx_os_argv_last - p);

if (ngx_os_argv_last - p) {
memset(p, NGX_SETPROCTITLE_PAD, ngx_os_argv_last - p);
}
}
37 changes: 37 additions & 0 deletions ngx_setproctitle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2002-2017 Igor Sysoev
* Copyright (C) 2011-2017 Nginx, Inc.
* All rights reserved.
* Copyright 2017 Colin Walters <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

/* walters: stripped out all non-linux stuff */

#pragma once

#define NGX_SETPROCTITLE_USES_ENV 1
#define NGX_SETPROCTITLE_PAD '\0'

void ngx_init_setproctitle(int argc, char *const*argv);
void ngx_setproctitle(char *title);

0 comments on commit 8e1b983

Please sign in to comment.