When xenwatchdogd is invoked with -h/--help (or any non-number), the
argument value is converted to 0, which immediately shutdowns dom0.
So make sure only numbers are passed to the program, otherwise fail.
For the help, use getopt_long as suggested.
While there, reformat the code a bit (s/tabs/spaces/, indentation, etc).
Bug fix only, no functional change intended.
Reported-by: Leigh Brown <leigh@solinno.co.uk>
Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Cyril Rébert / zithro <slack@rabbit.lu>
---
- Not sure about the preprocessor stanzas, copied them from xentop.
- A small explanation about what the program does could be helpful,
like some kind of synopsis ? Purpose, gotchas, etc. I can do the
writing, but please be specific !
- Built on 4.17 and unstable, tested on 4.17.
---
tools/misc/xenwatchdogd.c | 77 +++++++++++++++++++++++++++++----------
1 file changed, 57 insertions(+), 20 deletions(-)
diff --git a/tools/misc/xenwatchdogd.c b/tools/misc/xenwatchdogd.c
index 254117b554..6ef5eaf45c 100644
--- a/tools/misc/xenwatchdogd.c
+++ b/tools/misc/xenwatchdogd.c
@@ -8,26 +8,34 @@
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
+#include <string.h>
#include <stdio.h>
+#define _GNU_SOURCE
+#include <getopt.h>
+#if !defined(__GNUC__) && !defined(__GNUG__)
+#define __attribute__(arg) /* empty */
+#endif
+
xc_interface *h;
int id = 0;
void daemonize(void)
{
switch (fork()) {
- case -1:
- err(1, "fork");
- case 0:
- break;
- default:
- exit(0);
+ case -1:
+ err(1, "fork");
+ case 0:
+ break;
+ default:
+ exit(0);
}
+
umask(0);
if (setsid() < 0)
- err(1, "setsid");
+ err(1, "setsid");
if (chdir("/") < 0)
- err(1, "chdir /");
+ err(1, "chdir /");
if (freopen("/dev/null", "r", stdin) == NULL)
err(1, "reopen stdin");
if(freopen("/dev/null", "w", stdout) == NULL)
@@ -52,39 +60,68 @@ void catch_usr1(int sig)
int main(int argc, char **argv)
{
+
int t, s;
int ret;
+
+ char *usage = "usage: %s <timeout> <sleep>";
+ int opt, optind = 0;
+
+ struct option lopts[] = {
+ { "help", no_argument, NULL, 'h' },
+ };
+ const char *sopts = "h";
+
+ while ((opt = getopt_long(argc, argv, sopts, lopts, &optind)) != -1) {
+ switch (opt) {
+ case '?':
+ case 'h':
+ errx(1, usage, argv[0]);
+ break;
+ default:
+ errx(1, usage, argv[0]);
+ }
+ }
if (argc < 2)
- errx(1, "usage: %s <timeout> <sleep>", argv[0]);
+ errx(1, usage, argv[0]);
daemonize();
h = xc_interface_open(NULL, NULL, 0);
if (h == NULL)
- err(1, "xc_interface_open");
+ err(1, "xc_interface_open");
+
+ t = strtoul(argv[1], &argv[1], 0);
+
+ // argv1 NaN
+ if ( *argv[1] != '\0' )
+ errx(1, "Error: timeout must be a number, got '%s'", argv[1]);
- t = strtoul(argv[1], NULL, 0);
if (t == ULONG_MAX)
- err(1, "strtoul");
+ err(1, "strtoul");
s = t / 2;
if (argc == 3) {
- s = strtoul(argv[2], NULL, 0);
- if (s == ULONG_MAX)
- err(1, "strtoul");
+ s = strtoul(argv[2], &argv[2], 0);
+ // argv2 NaN
+ if ( *argv[2] != '\0' ){
+ errx(1, "Error: sleep must be a number, got '%s'", argv[2]);
+ }
+ if (s == ULONG_MAX)
+ err(1, "strtoul");
}
if (signal(SIGHUP, &catch_exit) == SIG_ERR)
- err(1, "signal");
+ err(1, "signal");
if (signal(SIGINT, &catch_exit) == SIG_ERR)
- err(1, "signal");
+ err(1, "signal");
if (signal(SIGQUIT, &catch_exit) == SIG_ERR)
- err(1, "signal");
+ err(1, "signal");
if (signal(SIGTERM, &catch_exit) == SIG_ERR)
- err(1, "signal");
+ err(1, "signal");
if (signal(SIGUSR1, &catch_usr1) == SIG_ERR)
- err(1, "signal");
+ err(1, "signal");
id = xc_watchdog(h, 0, t);
if (id <= 0)
--
2.39.2
argument value is converted to 0, which immediately shutdowns dom0.
So make sure only numbers are passed to the program, otherwise fail.
For the help, use getopt_long as suggested.
While there, reformat the code a bit (s/tabs/spaces/, indentation, etc).
Bug fix only, no functional change intended.
Reported-by: Leigh Brown <leigh@solinno.co.uk>
Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Cyril Rébert / zithro <slack@rabbit.lu>
---
- Not sure about the preprocessor stanzas, copied them from xentop.
- A small explanation about what the program does could be helpful,
like some kind of synopsis ? Purpose, gotchas, etc. I can do the
writing, but please be specific !
- Built on 4.17 and unstable, tested on 4.17.
---
tools/misc/xenwatchdogd.c | 77 +++++++++++++++++++++++++++++----------
1 file changed, 57 insertions(+), 20 deletions(-)
diff --git a/tools/misc/xenwatchdogd.c b/tools/misc/xenwatchdogd.c
index 254117b554..6ef5eaf45c 100644
--- a/tools/misc/xenwatchdogd.c
+++ b/tools/misc/xenwatchdogd.c
@@ -8,26 +8,34 @@
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
+#include <string.h>
#include <stdio.h>
+#define _GNU_SOURCE
+#include <getopt.h>
+#if !defined(__GNUC__) && !defined(__GNUG__)
+#define __attribute__(arg) /* empty */
+#endif
+
xc_interface *h;
int id = 0;
void daemonize(void)
{
switch (fork()) {
- case -1:
- err(1, "fork");
- case 0:
- break;
- default:
- exit(0);
+ case -1:
+ err(1, "fork");
+ case 0:
+ break;
+ default:
+ exit(0);
}
+
umask(0);
if (setsid() < 0)
- err(1, "setsid");
+ err(1, "setsid");
if (chdir("/") < 0)
- err(1, "chdir /");
+ err(1, "chdir /");
if (freopen("/dev/null", "r", stdin) == NULL)
err(1, "reopen stdin");
if(freopen("/dev/null", "w", stdout) == NULL)
@@ -52,39 +60,68 @@ void catch_usr1(int sig)
int main(int argc, char **argv)
{
+
int t, s;
int ret;
+
+ char *usage = "usage: %s <timeout> <sleep>";
+ int opt, optind = 0;
+
+ struct option lopts[] = {
+ { "help", no_argument, NULL, 'h' },
+ };
+ const char *sopts = "h";
+
+ while ((opt = getopt_long(argc, argv, sopts, lopts, &optind)) != -1) {
+ switch (opt) {
+ case '?':
+ case 'h':
+ errx(1, usage, argv[0]);
+ break;
+ default:
+ errx(1, usage, argv[0]);
+ }
+ }
if (argc < 2)
- errx(1, "usage: %s <timeout> <sleep>", argv[0]);
+ errx(1, usage, argv[0]);
daemonize();
h = xc_interface_open(NULL, NULL, 0);
if (h == NULL)
- err(1, "xc_interface_open");
+ err(1, "xc_interface_open");
+
+ t = strtoul(argv[1], &argv[1], 0);
+
+ // argv1 NaN
+ if ( *argv[1] != '\0' )
+ errx(1, "Error: timeout must be a number, got '%s'", argv[1]);
- t = strtoul(argv[1], NULL, 0);
if (t == ULONG_MAX)
- err(1, "strtoul");
+ err(1, "strtoul");
s = t / 2;
if (argc == 3) {
- s = strtoul(argv[2], NULL, 0);
- if (s == ULONG_MAX)
- err(1, "strtoul");
+ s = strtoul(argv[2], &argv[2], 0);
+ // argv2 NaN
+ if ( *argv[2] != '\0' ){
+ errx(1, "Error: sleep must be a number, got '%s'", argv[2]);
+ }
+ if (s == ULONG_MAX)
+ err(1, "strtoul");
}
if (signal(SIGHUP, &catch_exit) == SIG_ERR)
- err(1, "signal");
+ err(1, "signal");
if (signal(SIGINT, &catch_exit) == SIG_ERR)
- err(1, "signal");
+ err(1, "signal");
if (signal(SIGQUIT, &catch_exit) == SIG_ERR)
- err(1, "signal");
+ err(1, "signal");
if (signal(SIGTERM, &catch_exit) == SIG_ERR)
- err(1, "signal");
+ err(1, "signal");
if (signal(SIGUSR1, &catch_usr1) == SIG_ERR)
- err(1, "signal");
+ err(1, "signal");
id = xc_watchdog(h, 0, t);
if (id <= 0)
--
2.39.2