From patchwork Thu Oct 3 00:50:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthieu Buffet X-Patchwork-Id: 13820590 Received: from mx1.buffet.re (mx1.buffet.re [51.83.41.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 64B18C8CE; Thu, 3 Oct 2024 00:49:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=51.83.41.69 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727916545; cv=none; b=CNLjAfNvdjSNc99tN6aDA0mHqKlbB7E+xj34R72BH4LDyiI5qS1vcgww9BXZl0UBfbYESJXYqZcMWN8B5XOAJ2uRtf2ynYrhrFLazlMLQUSP9Mh93rFUHhH5myzB98lqfAigQXaP2kpXZdGOSmkUAo/UkSuyXJYO3+d1akBECxE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727916545; c=relaxed/simple; bh=Q1ce3jn9XQL6ANvPMCddF9t/Fksz4njwik0p/EWHY0I=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=rIEWK6BBb6IiNE6+9Z9v1L74cE1eu+kVFU3oziO43Zbl2KTnWVI9ZRCXR2boDbcfYYT7rS9UOcuE4RkyNk/zPkpn+sZNNJaJ5JHy9MQrgup7kIwmxDlhpakuLy/YdNvfMOefXel2qFB1czoOVV3nfOS4OCd/9ZQtQ5VzHViBpFU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=buffet.re; spf=pass smtp.mailfrom=buffet.re; dkim=pass (2048-bit key) header.d=buffet.re header.i=@buffet.re header.b=Uv0Y+37u; arc=none smtp.client-ip=51.83.41.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=buffet.re Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=buffet.re Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=buffet.re header.i=@buffet.re header.b="Uv0Y+37u" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=buffet.re; s=mx1; t=1727916534; bh=Q1ce3jn9XQL6ANvPMCddF9t/Fksz4njwik0p/EWHY0I=; h=From:To:Cc:Subject:Date:From; b=Uv0Y+37u3klwaP+PUx1ESXBB68fehYPQkIt0vCc3srTPzu9KZsLoAPyBEhSq6PN+p If8etRln5s83I2m9LbrqPbGBJj/QjTEelo26JS0ukFJsIi5X7og8ak/busBE1JTVar Xrxaod1vQPYQZhEaIG/j3B5tnEl3WbDWMeLvjRreZSuvTN9D4YGrzdO7vWB/X1lTT1 CinYtxUn25yQXTSGCi26dhwE/xBQnMUxz3yvbW4Wxeuci+G0Umxb9tTHNdaG4XC7sn sLeBGbS4j0xpHh9s6U4tRNt7NgBCfy1dTJ4YohtW59Cu/aJezd+uDnxvZv2iyCnVMN /7yknT4CprncQ== Received: from localhost.localdomain (unknown [10.0.1.3]) by mx1.buffet.re (Postfix) with ESMTPA id BDAF41230C1; Thu, 3 Oct 2024 02:48:54 +0200 (CEST) From: Matthieu Buffet To: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= Cc: =?utf-8?q?G=C3=BCnther_Noack?= , Konstantin Meskhidze , Ivanov Mikhail , linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, Matthieu Buffet Subject: [PATCH v2 1/3] samples/landlock: Fix port parsing in sandboxer Date: Thu, 3 Oct 2024 02:50:40 +0200 Message-Id: <20241003005042.258991-1-matthieu@buffet.re> X-Mailer: git-send-email 2.39.2 Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 If you want to specify that no port can be bind()ed, you would think (looking quickly at both help message and code) that setting LL_TCP_BIND="" would do it. However the code splits on ":" then applies atoi(), which does not allow checking for errors. Passing an empty string returns 0, which is interpreted as "allow bind(0)", which means bind to any ephemeral port. This bug occurs whenever passing an empty string or when leaving a trailing/leading colon, making it impossible to completely deny bind(). To reproduce: export LL_FS_RO="/" LL_FS_RW="" LL_TCP_BIND="" ./sandboxer strace -e bind nc -n -vvv -l -p 0 Executing the sandboxed command... bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 Listening on 0.0.0.0 37629 Use strtoul() instead, which allows error checking. Check that the entire string has been parsed correctly without overflows/underflows. Don't check that the __u64 (the type of struct landlock_net_port_attr.port) is a valid __u16 port: that is already done by the kernel. Two places check for an empty string, that is just to make the helper function safer to use in the future. Fixes: 5e990dcef12e ("samples/landlock: Support TCP restrictions") Signed-off-by: Matthieu Buffet --- samples/landlock/sandboxer.c | 37 ++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c index f847e832ba14..aff5ef808e22 100644 --- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,29 @@ static inline int landlock_restrict_self(const int ruleset_fd, #define ENV_SCOPED_NAME "LL_SCOPED" #define ENV_DELIMITER ":" +static int str2num(const char *numstr, __u64 *num_dst) +{ + char *endptr = NULL; + int err = 1; + __u64 num; + + if (*numstr == '\0') + goto out; + + errno = 0; + num = strtoull(numstr, &endptr, 10); + if (errno != 0) + goto out; + + if (*endptr != '\0') + goto out; + + *num_dst = num; + err = 0; +out: + return err; +} + static int parse_path(char *env_path, const char ***const path_list) { int i, num_paths = 0; @@ -160,7 +184,6 @@ static int populate_ruleset_net(const char *const env_var, const int ruleset_fd, char *env_port_name, *env_port_name_next, *strport; struct landlock_net_port_attr net_port = { .allowed_access = allowed_access, - .port = 0, }; env_port_name = getenv(env_var); @@ -171,7 +194,17 @@ static int populate_ruleset_net(const char *const env_var, const int ruleset_fd, env_port_name_next = env_port_name; while ((strport = strsep(&env_port_name_next, ENV_DELIMITER))) { - net_port.port = atoi(strport); + __u64 port; + + if (strcmp(strport, "") == 0) + continue; + + if (str2num(strport, &port)) { + fprintf(stderr, + "Failed to parse port at \"%s\"\n", strport); + goto out_free_name; + } + net_port.port = port; if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, &net_port, 0)) { fprintf(stderr, From patchwork Thu Oct 3 00:50:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthieu Buffet X-Patchwork-Id: 13820591 Received: from mx1.buffet.re (mx1.buffet.re [51.83.41.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 493B210A1E; Thu, 3 Oct 2024 00:49:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=51.83.41.69 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727916595; cv=none; b=GS1XY+H5FpBWMOPRinAP5IfV/SDosDaV3T06WUGwfAO0huDBARC77zHlPcFdkKffik/KjhDQdH9vNsu2PgcvKPzCOlSWd8Ono5pz4p2sd3HXPAprZMDcqjjfINL7m2xSo6rnNtqzH3QOyEouHNnhfLy1iDVUJOYEPm6yyW7efxI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727916595; c=relaxed/simple; bh=C5qXtRGtWzV670O3uJBwz7I/tQySbHayzPKy/MjpAAg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NtM5LmICANT13WwDcydWkj3fSyx5xQSG7Crktd6XsIyJShL/F2kggk41/mTkyTQCuQ4zBbznlyC9vHjOH/ALb8IUzlOINBGR6+q8/8lllhykxNpwak6T5FPJznhxEsPhL+r98I0QqXczHtUCZLSpr3DFR62OTFTRsUf3jMBn6Zw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=buffet.re; spf=pass smtp.mailfrom=buffet.re; dkim=pass (2048-bit key) header.d=buffet.re header.i=@buffet.re header.b=CvI8Ov9Q; arc=none smtp.client-ip=51.83.41.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=buffet.re Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=buffet.re Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=buffet.re header.i=@buffet.re header.b="CvI8Ov9Q" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=buffet.re; s=mx1; t=1727916581; bh=C5qXtRGtWzV670O3uJBwz7I/tQySbHayzPKy/MjpAAg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CvI8Ov9QiOHnnNX1YY1hzMRtMOPzmUSPadwinnZuRWGTZy+Vujdcroty6/btx5+M6 e5dScVXqB5N5KUU7ns2HbimHl8qSIIaJ8C8mkUnSHiaRxql65ZEQvNv0GtwWoM1N/y TuuuN7C30L+yRrI6kwA8+VbKlnN6YpdV1J9ir2QYILpSeTKeWhiMjF59XQ3hfDHJ9u /iXmAV1a8Wx5mUjxEdMQa2XqR1nG7+qhfRUR21F9QTv7zuNUG9DOTGr+lVkeJBffW/ H4jsz1+wba+LGV0+YT9pHkC6Ixl+7Tj+zpuXD32w1SeTqGf7+XFGarwA0U43cGUMmw QQk2gjXReCVSA== Received: from localhost.localdomain (unknown [10.0.1.3]) by mx1.buffet.re (Postfix) with ESMTPA id 65F641230C1; Thu, 3 Oct 2024 02:49:41 +0200 (CEST) From: Matthieu Buffet To: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= Cc: =?utf-8?q?G=C3=BCnther_Noack?= , Konstantin Meskhidze , Ivanov Mikhail , linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, Matthieu Buffet Subject: [PATCH v2 2/3] samples/landlock: Refactor --help message in function Date: Thu, 3 Oct 2024 02:50:41 +0200 Message-Id: <20241003005042.258991-2-matthieu@buffet.re> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20241003005042.258991-1-matthieu@buffet.re> References: <20241003005042.258991-1-matthieu@buffet.re> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Help message is getting larger with each new supported feature (scopes, and soon UDP). Refactor it away into a separate helper function. Signed-off-by: Matthieu Buffet --- samples/landlock/sandboxer.c | 87 +++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c index aff5ef808e22..f16994d35d9e 100644 --- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c @@ -295,6 +295,51 @@ static bool check_ruleset_scope(const char *const env_var, #define LANDLOCK_ABI_LAST 6 +static void print_help(const char *argv0) +{ + fprintf(stderr, + "usage: %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\" %s " + " [args]...\n\n", + ENV_FS_RO_NAME, ENV_FS_RW_NAME, ENV_TCP_BIND_NAME, + ENV_TCP_CONNECT_NAME, ENV_SCOPED_NAME, argv0); + fprintf(stderr, + "Execute a command in a restricted environment.\n\n"); + fprintf(stderr, + "Environment variables containing paths and ports " + "each separated by a colon:\n"); + fprintf(stderr, + "* %s: list of paths allowed to be used in a read-only way.\n", + ENV_FS_RO_NAME); + fprintf(stderr, + "* %s: list of paths allowed to be used in a read-write way.\n\n", + ENV_FS_RW_NAME); + fprintf(stderr, + "Environment variables containing ports are optional " + "and could be skipped.\n"); + fprintf(stderr, + "* %s: list of ports allowed to bind (server).\n", + ENV_TCP_BIND_NAME); + fprintf(stderr, + "* %s: list of ports allowed to connect (client).\n", + ENV_TCP_CONNECT_NAME); + fprintf(stderr, "* %s: list of scoped IPCs.\n", + ENV_SCOPED_NAME); + fprintf(stderr, + "\nexample:\n" + "%s=\"${PATH}:/lib:/usr:/proc:/etc:/dev/urandom\" " + "%s=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" " + "%s=\"9418\" " + "%s=\"80:443\" " + "%s=\"a:s\" " + "%s bash -i\n\n", + ENV_FS_RO_NAME, ENV_FS_RW_NAME, ENV_TCP_BIND_NAME, + ENV_TCP_CONNECT_NAME, ENV_SCOPED_NAME, argv0); + fprintf(stderr, + "This sandboxer can use Landlock features " + "up to ABI version %d.\n", + LANDLOCK_ABI_LAST); +} + int main(const int argc, char *const argv[], char *const *const envp) { const char *cmd_path; @@ -313,47 +358,7 @@ int main(const int argc, char *const argv[], char *const *const envp) }; if (argc < 2) { - fprintf(stderr, - "usage: %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\" %s " - " [args]...\n\n", - ENV_FS_RO_NAME, ENV_FS_RW_NAME, ENV_TCP_BIND_NAME, - ENV_TCP_CONNECT_NAME, ENV_SCOPED_NAME, argv[0]); - fprintf(stderr, - "Execute a command in a restricted environment.\n\n"); - fprintf(stderr, - "Environment variables containing paths and ports " - "each separated by a colon:\n"); - fprintf(stderr, - "* %s: list of paths allowed to be used in a read-only way.\n", - ENV_FS_RO_NAME); - fprintf(stderr, - "* %s: list of paths allowed to be used in a read-write way.\n\n", - ENV_FS_RW_NAME); - fprintf(stderr, - "Environment variables containing ports are optional " - "and could be skipped.\n"); - fprintf(stderr, - "* %s: list of ports allowed to bind (server).\n", - ENV_TCP_BIND_NAME); - fprintf(stderr, - "* %s: list of ports allowed to connect (client).\n", - ENV_TCP_CONNECT_NAME); - fprintf(stderr, "* %s: list of scoped IPCs.\n", - ENV_SCOPED_NAME); - fprintf(stderr, - "\nexample:\n" - "%s=\"${PATH}:/lib:/usr:/proc:/etc:/dev/urandom\" " - "%s=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" " - "%s=\"9418\" " - "%s=\"80:443\" " - "%s=\"a:s\" " - "%s bash -i\n\n", - ENV_FS_RO_NAME, ENV_FS_RW_NAME, ENV_TCP_BIND_NAME, - ENV_TCP_CONNECT_NAME, ENV_SCOPED_NAME, argv[0]); - fprintf(stderr, - "This sandboxer can use Landlock features " - "up to ABI version %d.\n", - LANDLOCK_ABI_LAST); + print_help(argv[0]); return 1; } From patchwork Thu Oct 3 00:50:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthieu Buffet X-Patchwork-Id: 13820592 Received: from mx1.buffet.re (mx1.buffet.re [51.83.41.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B0BFADDAB; Thu, 3 Oct 2024 00:50:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=51.83.41.69 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727916630; cv=none; b=mcIt4QY6MumQtbr/GevXHhyEiTmzKKTEKLWGkkxcyIKH8q+JrIeC31iuQDbCbFSvUspe205fEWy80Hs7GVG555PbQePMHYYRdNEw1Ro9oIIAmuStFiJZ52gIV+ysL8IRhagDn5KulberSaIMZVILfZ9tAeSERs7NrppYeL6uj2Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727916630; c=relaxed/simple; bh=SFt8Izw3k9oW8PRPnRr3j1kF25WKNW3bL1ymvtdIDvw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ai8d+AJ1zn3b60qpzo+yTAUkbW/Hf2HfagMpIk7belGk4I0M/SSbFs+FUtY8i9P3AC5CO1a5WsdxGqh0w+vZ19zNMVcW47vyNG5VsOxT0vnRmESUEqUKvsLg4vfRO0K8TXGXK5xEE/SRzeI9KR7SU5h38yWG01HZbyPF4bBbXrE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=buffet.re; spf=pass smtp.mailfrom=buffet.re; dkim=pass (2048-bit key) header.d=buffet.re header.i=@buffet.re header.b=haQ4uImw; arc=none smtp.client-ip=51.83.41.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=buffet.re Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=buffet.re Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=buffet.re header.i=@buffet.re header.b="haQ4uImw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=buffet.re; s=mx1; t=1727916620; bh=SFt8Izw3k9oW8PRPnRr3j1kF25WKNW3bL1ymvtdIDvw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=haQ4uImwh1ZMug4jCAxX2a/Kjn/JJ/a4K6uNldjeF3wkgO7OBFvtcQN76BlTZQa2L 4vNbGt8CNdeCoXC4RQ0Uri9dT3BxxhMuzE2fCTwmfluD0y+yALCC+bKzT02RWumCyq xUlOdGfsvzjeU3HZ5C4lKdKjjYyJGtWHtE6ZKvnctFMKNCZs07GNGpou/RPtYtYXol 4JmX6v3rVh70RcJieBEFz+FL77M61/y8m9s+pOjl7hXt+8yDx6dOEYNlb6K9J0VPN8 sZsKZTZmHVwqrobwTCK8goUY5kiaBfFsrU1mF7W5Pheg5bhPiCAKSGYFlC6S+0un5C YzfQlsvCgtetA== Received: from localhost.localdomain (unknown [10.0.1.3]) by mx1.buffet.re (Postfix) with ESMTPA id 9525D1230C1; Thu, 3 Oct 2024 02:50:20 +0200 (CEST) From: Matthieu Buffet To: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= Cc: =?utf-8?q?G=C3=BCnther_Noack?= , Konstantin Meskhidze , Ivanov Mikhail , linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, Matthieu Buffet Subject: [PATCH v2 3/3] samples/landlock: Clarify option parsing behaviour Date: Thu, 3 Oct 2024 02:50:42 +0200 Message-Id: <20241003005042.258991-3-matthieu@buffet.re> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20241003005042.258991-1-matthieu@buffet.re> References: <20241003005042.258991-1-matthieu@buffet.re> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 - Clarify which environment variables are optional, which ones are mandatory - Clarify the difference between unset variables and empty ones Signed-off-by: Matthieu Buffet --- samples/landlock/sandboxer.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c index f16994d35d9e..a28e4a9c5f87 100644 --- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c @@ -298,24 +298,27 @@ static bool check_ruleset_scope(const char *const env_var, static void print_help(const char *argv0) { fprintf(stderr, - "usage: %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\" %s " + "usage: %s=\"...\" %s=\"...\" [other environment variables] %s " " [args]...\n\n", - ENV_FS_RO_NAME, ENV_FS_RW_NAME, ENV_TCP_BIND_NAME, - ENV_TCP_CONNECT_NAME, ENV_SCOPED_NAME, argv0); + ENV_FS_RO_NAME, ENV_FS_RW_NAME, argv0); fprintf(stderr, "Execute a command in a restricted environment.\n\n"); fprintf(stderr, - "Environment variables containing paths and ports " - "each separated by a colon:\n"); + "All environment variables can be multi-valued, with a " + "colon delimiter.\n" + "\n" + "Mandatory settings:\n"); fprintf(stderr, "* %s: list of paths allowed to be used in a read-only way.\n", ENV_FS_RO_NAME); fprintf(stderr, - "* %s: list of paths allowed to be used in a read-write way.\n\n", + "* %s: list of paths allowed to be used in a read-write way.\n", ENV_FS_RW_NAME); fprintf(stderr, - "Environment variables containing ports are optional " - "and could be skipped.\n"); + "\n" + "Optional settings (when not set, their associated access " + "check is always allowed, which is different from an empty " + "string which means an empty list)\n"); fprintf(stderr, "* %s: list of ports allowed to bind (server).\n", ENV_TCP_BIND_NAME); @@ -325,7 +328,8 @@ static void print_help(const char *argv0) fprintf(stderr, "* %s: list of scoped IPCs.\n", ENV_SCOPED_NAME); fprintf(stderr, - "\nexample:\n" + "\n" + "Example:\n" "%s=\"${PATH}:/lib:/usr:/proc:/etc:/dev/urandom\" " "%s=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" " "%s=\"9418\" "