Richard W.M. Jones
2020-Feb-18 10:52 UTC
[Libguestfs] [PATCH nbdkit 2/2] server: Avoid modifying argv by saving keys in a list and freeing on exit.
Unfortunately you cannot restore argv by setting *p = '=' :-( The reason is we advertize that plugins are allowed to save they ‘const char *key’ pointer passed to them in .config, but assigning *p = '=' changes the key string from "key" back to "key=value". Surprisingly only test-eval.sh actually broke, but other plugins are undoubtedly affected. My alternate fix is fairly horrible, but passes all the tests and valgrind. Rich.
Richard W.M. Jones
2020-Feb-18 10:52 UTC
[Libguestfs] [PATCH nbdkit 1/2] Revert "main: Restore argv after .config"
This reverts commit ea4bb3dde2823231eeae1b5408e1bfadf8b95267. --- server/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/server/main.c b/server/main.c index a1d307b1..dbeca624 100644 --- a/server/main.c +++ b/server/main.c @@ -621,7 +621,6 @@ main (int argc, char *argv[]) if (p && is_config_key (argv[optind], p - argv[optind])) { /* key=value */ *p = '\0'; top->config (top, argv[optind], p+1); - *p = '='; } else if (magic_config_key == NULL) { if (i == 0) /* magic script parameter */ -- 2.24.1
Richard W.M. Jones
2020-Feb-18 10:52 UTC
[Libguestfs] [PATCH nbdkit 2/2] server: Avoid modifying argv by saving keys in a list and freeing on exit.
--- server/main.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/server/main.c b/server/main.c index dbeca624..c65c78f7 100644 --- a/server/main.c +++ b/server/main.c @@ -614,13 +614,32 @@ main (int argc, char *argv[]) * scripting languages, if magic_config_key == NULL then if the * first parameter is bare it is prefixed with the key "script", and * any other bare parameters are errors. + * + * Keys must live for the life of nbdkit. Since we want to avoid + * modifying argv (so that /proc/PID/cmdline remains sane) but we + * need to create a key from argv[i] = "key=value" we must save the + * keys in an array which is freed at the end of main(). */ + char **keys = calloc (argc, sizeof (char *)); + if (keys == NULL) { + perror ("calloc"); + exit (EXIT_FAILURE); + } + magic_config_key = top->magic_config_key (top); for (i = 0; optind < argc; ++i, ++optind) { + size_t n; + p = strchr (argv[optind], '='); - if (p && is_config_key (argv[optind], p - argv[optind])) { /* key=value */ - *p = '\0'; - top->config (top, argv[optind], p+1); + n = p - argv[optind]; + if (p && is_config_key (argv[optind], n)) { /* Is it key=value? */ + keys[optind] = strndup (argv[optind], n); + + if (keys[optind] == NULL) { + perror ("strndup"); + exit (EXIT_FAILURE); + } + top->config (top, keys[optind], p+1); } else if (magic_config_key == NULL) { if (i == 0) /* magic script parameter */ @@ -679,6 +698,10 @@ main (int argc, char *argv[]) crypto_free (); close_quit_pipe (); + for (i = 1; i < argc; ++i) + free (keys[i]); + free (keys); + /* Note: Don't exit here, otherwise this won't work when compiled * for libFuzzer. */ -- 2.24.1
Richard W.M. Jones
2020-Feb-18 11:26 UTC
Re: [Libguestfs] [PATCH nbdkit 0/2] server: Avoid modifying argv by saving keys in a list and freeing on exit.
On Tue, Feb 18, 2020 at 10:52:19AM +0000, Richard W.M. Jones wrote:> Unfortunately you cannot restore argv by setting *p = '=' :-( > > The reason is we advertize that plugins are allowed to save they > ‘const char *key’ pointer passed to them in .config, but assigning > *p = '=' changes the key string from "key" back to "key=value". > > Surprisingly only test-eval.sh actually broke, but other plugins are > undoubtedly affected.Most plugins only compare key to some string, but the eval plugin actually saves the key which is why it fails. I have pushed the revert commit (part 1). Rich.> My alternate fix is fairly horrible, but passes all the tests and > valgrind. > > Rich. > > > > _______________________________________________ > Libguestfs mailing list > Libguestfs@redhat.com > https://www.redhat.com/mailman/listinfo/libguestfs-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW
Eric Blake
2020-Feb-18 12:34 UTC
Re: [Libguestfs] [PATCH nbdkit 2/2] server: Avoid modifying argv by saving keys in a list and freeing on exit.
On 2/18/20 4:52 AM, Richard W.M. Jones wrote:> Unfortunately you cannot restore argv by setting *p = '=' :-( > > The reason is we advertize that plugins are allowed to save they > ‘const char *key’ pointer passed to them in .config, but assigning > *p = '=' changes the key string from "key" back to "key=value".D'oh. And my bad for only running the subset of the testsuite that I was working on ('make -C tests check TESTS=test-vddk.sh') rather than the full suite, or I would have noticed the regression from my one-liner. Thanks for fixing it.> > Surprisingly only test-eval.sh actually broke, but other plugins are > undoubtedly affected. > > My alternate fix is fairly horrible, but passes all the tests and > valgrind.It looks right to me - if we can't modify argv[] in place, we have to copy off a stable version somewhere. Your patch is definitely longer than my one-liner, but I don't see any way to shorten it. ACK. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Seemingly Similar Threads
- [PATCH nbdkit v3 0/6] plugins: Implement magic config key.
- [PATCH nbdkit v2 0/6] plugins: Implement magic config key.
- [PATCH nbdkit 0/6] plugins: Implement magic config key.
- [PATCH nbdkit] server: Try hard to maintain invariant that fds 0, 1 and 2 are always open.
- [PATCH nbdkit v2 2/6] main: Tighten up characters permitted in config keys.