Under memory pressure, the use of strdup in strstr_rs could return NULL,
and that return value would then be dereferenced.

The following change replaces that function with this far
simpler one and removes a second copy of the original.

char *strstr_rs (const char *haystack, int byte)
{
        const char *end_address = strchr (haystack, byte);
        if (end_address) {
                end_address += 1; /* skip past { or = */
                end_address += strspn (end_address, " \t");
        }

        return ((char *) end_address);
}

Since the goal was just to remove the potential NULL-dereference,
I tried to keep this small, I didn't rename the function (it now looks
more like strchr than strstr), but can do that, too, if you'd like.
strchr_rs?

Jim

>From 63e669ea655d0b0fbbfd8fe7d22e336f22eeba1f Mon Sep 17 00:00:00 2001
From: Jim Meyering <[email protected]>
Date: Fri, 20 Mar 2009 20:39:08 +0100
Subject: [PATCH] rewrite strstr_rs not to use strdup

strstr_rs used strdup and didn't handle failure.  This change removes
the use of strdup as well as the uses of strstr, since all callers
passed a string of length 1 as the second argument.  This also changes
the prototype so that the 2nd parameter is a byte, not a string.

* util.h (strstr_rs): Adjust prototype.
* util.c (strstr_rs): Rewrite/simplify.
* sa-confdb.c (strstr_rs): Remove duplicate definition.
* coroparse.c (parse_section): Update callers.
---
 exec/coroparse.c |    6 +++---
 exec/util.c      |   25 ++++---------------------
 exec/util.h      |    2 +-
 lib/sa-confdb.c  |   30 ------------------------------
 4 files changed, 8 insertions(+), 55 deletions(-)

diff --git a/exec/coroparse.c b/exec/coroparse.c
index 02c6e97..8228856 100644
--- a/exec/coroparse.c
+++ b/exec/coroparse.c
@@ -114,7 +114,7 @@ static int parse_section(FILE *fp,
                }

                /* New section ? */
-               if ((loc = strstr_rs (line, "{"))) {
+               if ((loc = strstr_rs (line, '{'))) {
                        hdb_handle_t new_parent;
                        char *section = remove_whitespace(line);

@@ -127,7 +127,7 @@ static int parse_section(FILE *fp,
                }

                /* New key/value */
-               if ((loc = strstr_rs (line, ":"))) {
+               if ((loc = strstr_rs (line, ':'))) {
                        char *key;
                        char *value;

@@ -139,7 +139,7 @@ static int parse_section(FILE *fp,
                                value, strlen (value) + 1);
                }

-               if ((loc = strstr_rs (line, "}"))) {
+               if ((loc = strstr_rs (line, '}'))) {
                        return 0;
                }
        }
diff --git a/exec/util.c b/exec/util.c
index 6737a4f..ec41ea3 100644
--- a/exec/util.c
+++ b/exec/util.c
@@ -108,32 +108,15 @@ char *getcs_name_t (cs_name_t *name)
        return ((char *)name->value);
 }

-char *strstr_rs (const char *haystack, const char *needle)
+char *strstr_rs (const char *haystack, int byte)
 {
-       char *end_address;
-       char *new_needle;
-
-       new_needle = (char *)strdup (needle);
-       new_needle[strlen (new_needle) - 1] = '\0';
-
-       end_address = strstr (haystack, new_needle);
-       if (end_address) {
-               end_address += strlen (new_needle);
-               end_address = strstr (end_address, needle + strlen 
(new_needle));
-       }
+       const char *end_address = strchr (haystack, byte);
        if (end_address) {
                end_address += 1; /* skip past { or = */
-               do {
-                       if (*end_address == '\t' || *end_address == ' ') {
-                               end_address++;
-                       } else {
-                               break;
-                       }
-               } while (*end_address != '\0');
+               end_address += strspn (end_address, " \t");
        }

-       free (new_needle);
-       return (end_address);
+       return ((char *) end_address);
 }

 void setcs_name_t (cs_name_t *name, char *str) {
diff --git a/exec/util.h b/exec/util.h
index 385a361..3d73d68 100644
--- a/exec/util.h
+++ b/exec/util.h
@@ -73,7 +73,7 @@ extern void _corosync_exit_error (
        enum e_ais_done err, const char *file, unsigned int line);
 void _corosync_out_of_memory_error (void);
 extern char *getcs_name_t (cs_name_t *name);
-extern char *strstr_rs (const char *haystack, const char *needle);
+extern char *strstr_rs (const char *haystack, int byte);
 extern void setcs_name_t (cs_name_t *name, char *str);
 char *get_mar_name_t (mar_name_t *name);
 extern int cs_name_tisEqual (cs_name_t *str1, char *str2);
diff --git a/lib/sa-confdb.c b/lib/sa-confdb.c
index 57b2d7e..c195ede 100644
--- a/lib/sa-confdb.c
+++ b/lib/sa-confdb.c
@@ -62,7 +62,6 @@ static int num_config_modules;
 static struct config_iface_ver0 *config_modules[128];

 void main_get_config_modules(struct config_iface_ver0 ***modules, int *num);
-char *strstr_rs (const char *haystack, const char *needle);

 static int load_objdb(void)
 {
@@ -150,35 +149,6 @@ void main_get_config_modules(struct config_iface_ver0 
***modules, int *num)
        *num = num_config_modules;
 }

-/* Needed by some modules ... */
-char *strstr_rs (const char *haystack, const char *needle)
-{
-       char *end_address;
-       char *new_needle;
-
-       new_needle = (char *)strdup (needle);
-       new_needle[strlen (new_needle) - 1] = '\0';
-
-       end_address = strstr (haystack, new_needle);
-       if (end_address) {
-               end_address += strlen (new_needle);
-               end_address = strstr (end_address, needle + strlen 
(new_needle));
-       }
-       if (end_address) {
-               end_address += 1; /* skip past { or = */
-               do {
-                       if (*end_address == '\t' || *end_address == ' ') {
-                               end_address++;
-                       } else {
-                               break;
-                       }
-               } while (*end_address != '\0');
-       }
-
-       free (new_needle);
-       return (end_address);
-}
-
 int confdb_sa_init (void)
 {
        int res;
--
1.6.2.rc1.285.gc5f54
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to