From mboxrd@z Thu Jan 1 00:00:00 1970 Received: by passt.top (Postfix, from userid 1000) id C846A5A0319; Wed, 07 Aug 2024 13:28:40 +0200 (CEST) From: Stefano Brivio To: passt-dev@passt.top Subject: [PATCH v2] conf: Stop parsing options at first non-option argument Date: Wed, 7 Aug 2024 13:28:40 +0200 Message-ID: <20240807112840.2113074-1-sbrivio@redhat.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: CDM3MWBNNVXE7F2BUGBZCF6LCWLZQFGY X-Message-ID-Hash: CDM3MWBNNVXE7F2BUGBZCF6LCWLZQFGY X-MailFrom: sbrivio@passt.top X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Paul Holzinger , David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Given that pasta supports specifying a command to be executed on the command line, even without the usual -- separator as long as there's no ambiguity, we shouldn't eat up options that are not meant for us. Paul reports, for instance, that with: pasta --config-net ip -6 route -6 is taken by pasta to mean --ipv6-only, and we execute 'ip route'. That's because getopt_long(), by default, shuffles the argument list to shift non-option arguments at the end. Avoid that by adding '-' at the beginning of 'optstring', and mark the position of the first non-option argument (getopt_long() will now return the character code 1 once we hit it), so that we can use that as command to run, or as PID for the target namespace. Reported-by: Paul Holzinger Signed-off-by: Stefano Brivio --- v2: Instead of overriding 'name' in the getopt_long() loop, to force exiting the loop, adjust the exit condition conf.c | 23 +++++++++++++++-------- util.c | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/conf.c b/conf.c index be5259e..1a30b47 100644 --- a/conf.c +++ b/conf.c @@ -1240,22 +1240,22 @@ void conf(struct ctx *c, int argc, char **argv) enum fwd_ports_mode fwd_default = FWD_NONE; bool v4_only = false, v6_only = false; struct fqdn *dnss = c->dns_search; + int name, ret, first_nonopt = -1; unsigned int ifi4 = 0, ifi6 = 0; const char *logfile = NULL; const char *optstring; size_t logsize = 0; char *runas = NULL; long fd_tap_opt; - int name, ret; uid_t uid; gid_t gid; if (c->mode == MODE_PASTA) { c->no_dhcp_dns = c->no_dhcp_dns_search = 1; fwd_default = FWD_AUTO; - optstring = "dqfel:hF:I:p:P:m:a:n:M:g:i:o:D:S:46t:u:T:U:"; + optstring = "-dqfel:hF:I:p:P:m:a:n:M:g:i:o:D:S:46t:u:T:U:"; } else { - optstring = "dqfel:hs:F:p:P:m:a:n:M:g:i:o:D:S:461t:u:"; + optstring = "-dqfel:hs:F:p:P:m:a:n:M:g:i:o:D:S:461t:u:"; } c->tcp.fwd_in.mode = c->tcp.fwd_out.mode = FWD_UNSET; @@ -1269,6 +1269,9 @@ void conf(struct ctx *c, int argc, char **argv) case -1: case 0: break; + case 1: + first_nonopt = optind - 1; + break; case 2: if (c->mode != MODE_PASTA) die("--userns is for pasta mode only"); @@ -1629,7 +1632,10 @@ void conf(struct ctx *c, int argc, char **argv) usage(argv[0], stderr, EXIT_FAILURE); break; } - } while (name != -1); + } while (name != -1 && name != 1); + + if (first_nonopt == -1) + first_nonopt = optind; if (c->mode == MODE_PASTA && !c->pasta_conf_ns) { if (copy_routes_opt) @@ -1689,9 +1695,9 @@ void conf(struct ctx *c, int argc, char **argv) } while (name != -1); if (c->mode == MODE_PASTA) - conf_pasta_ns(&netns_only, userns, netns, optind, argc, argv); - else if (optind != argc) - die("Extra non-option argument: %s", argv[optind]); + conf_pasta_ns(&netns_only, userns, netns, first_nonopt, argc, argv); + else if (first_nonopt != argc) + die("Extra non-option argument: %s", argv[first_nonopt]); conf_open_files(c); /* Before any possible setuid() / setgid() */ @@ -1705,7 +1711,8 @@ void conf(struct ctx *c, int argc, char **argv) pasta_open_ns(c, netns); } else { pasta_start_ns(c, uid, gid, - argc - optind, argv + optind); + argc - first_nonopt, + argv + first_nonopt); } } diff --git a/util.c b/util.c index 9c6be6a..13524e6 100644 --- a/util.c +++ b/util.c @@ -710,7 +710,7 @@ void close_open_files(int argc, char **argv) int name; do { - name = getopt_long(argc, argv, ":F", optfd, NULL); + name = getopt_long(argc, argv, "-:F", optfd, NULL); if (name == 'F') { errno = 0; -- 2.43.0