]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Fix print_supported_protocols and print_supported_protocols_usage
authorDaniel Lenski <dlenski@gmail.com>
Mon, 20 Apr 2020 17:14:50 +0000 (10:14 -0700)
committerDaniel Lenski <dlenski@gmail.com>
Mon, 20 Apr 2020 18:29:03 +0000 (11:29 -0700)
These were broken in 7cb8996e21b442c4ec60ce25c87e8a69516fac17, when the
empty sentinel value at the end of the array was removed, without changing
the way these functions iterate over that array.

For some reason, this continues to work on Linux (probably due to `calloc`
allocating more zeroed bytes than we request, in
`openconnect_get_supported_protocols`), but is causing the expected SIGSEGV on
Solaris:
https://lists.infradead.org/pipermail/openconnect-devel/2020-April/005640.html

Fix:

- Modify `print_supported_protocols` and `print_supported_protocols_usage` to
  rely on the length returned by `openconnect_get_supported_protocols`.
- Restore the sentinel value at the end of the array returned by
  `openconnect_get_supported_protocols`, to preserve ABI compatibility for
  other users who may depend on this sentinel.

Signed-off-by: Daniel Lenski <dlenski@gmail.com>
library.c
main.c

index 3caad64301e05db84bec5202c6b7f133bff0a039..586c5798a7f03f9a9932a38a138438bbcc44a686 100644 (file)
--- a/library.c
+++ b/library.c
@@ -195,7 +195,13 @@ int openconnect_get_supported_protocols(struct oc_vpn_proto **protos)
        struct oc_vpn_proto *pr;
        int i;
 
-       *protos = pr = calloc(NR_PROTOS, sizeof(*pr));
+        /* The original version of this function included an all-zero
+         * sentinel value at the end of the array, so we must continue
+         * to do so for ABI compatibility even though it's
+         * functionally redundant as a marker of the array's length,
+         * along with the explicit length in the return value.
+         */
+       *protos = pr = calloc(NR_PROTOS + 1, sizeof(*pr));
        if (!pr)
                return -ENOMEM;
 
diff --git a/main.c b/main.c
index 21a36461fc5aa39a0bffd7d9f5cfe89f0230706e..cc3dd91ee3328e38ef7dd0992670acf37f16933e 100644 (file)
--- a/main.c
+++ b/main.c
@@ -659,10 +659,12 @@ static void print_supported_protocols(void)
 {
        const char *comma = ", ", *sep = comma + 1;
        struct oc_vpn_proto *protos, *p;
+       int n;
 
-       if (openconnect_get_supported_protocols(&protos)>=0) {
+       n = openconnect_get_supported_protocols(&protos);
+        if (n>=0) {
                printf(_("Supported protocols:"));
-               for (p=protos; p->name; p++) {
+               for (p=protos; n; p++, n--) {
                        printf("%s%s%s", sep, p->name, p==protos ? _(" (default)") : "");
                        sep = comma;
                }
@@ -674,10 +676,12 @@ static void print_supported_protocols(void)
 static void print_supported_protocols_usage(void)
 {
        struct oc_vpn_proto *protos, *p;
+       int n;
 
-       if (openconnect_get_supported_protocols(&protos)>=0) {
+       n = openconnect_get_supported_protocols(&protos);
+        if (n>=0) {
                printf("\n%s:\n", _("Set VPN protocol"));
-               for (p=protos; p->name; p++)
+               for (p=protos; n; p++, n--)
                        printf("      --protocol=%-16s %s%s\n",
                                   p->name, p->description, p==protos ? _(" (default)") : "");
                openconnect_free_supported_protocols(protos);