krb5 commit: Fix princflags memory management

Tom Yu tlyu at mit.edu
Thu Jul 16 14:24:59 EDT 2015


https://github.com/krb5/krb5/commit/dd5f948614b6662fc40dc8de3f567078cfe6295e
commit dd5f948614b6662fc40dc8de3f567078cfe6295e
Author: Tom Yu <tlyu at mit.edu>
Date:   Mon Jul 13 18:05:35 2015 -0400

    Fix princflags memory management
    
    Fix some out of memory error cases (found by Coverity) that could
    cause multiple frees or freeing of invalid pointers.  In
    krb5_flagnum_to_string(), don't assume that asprintf() stores a null
    pointer on failure (it does in BSD but not in glibc).  In
    krb5_flags_to_strings(), free the correct pointer in the cleanup loop
    in on error.
    
    ticket: 8215

 src/lib/kadm5/str_conv.c  |   18 ++++++++++--------
 src/tests/t_princflags.py |   13 +++++++++++++
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/lib/kadm5/str_conv.c b/src/lib/kadm5/str_conv.c
index fd9a1d1..0441a17 100644
--- a/src/lib/kadm5/str_conv.c
+++ b/src/lib/kadm5/str_conv.c
@@ -196,7 +196,8 @@ krb5_flagspec_to_mask(const char *spec, krb5_flags *toset, krb5_flags *toclear)
 }
 
 /*
- * Copy the flag name of flagnum to outstr.
+ * Copy the flag name of flagnum to outstr.  On error, outstr points to a null
+ * pointer.
  */
 krb5_error_code
 krb5_flagnum_to_string(int flagnum, char **outstr)
@@ -204,14 +205,15 @@ krb5_flagnum_to_string(int flagnum, char **outstr)
     const char *s = NULL;
 
     *outstr = NULL;
-    if ((unsigned int)flagnum < NOUTFLAGS) {
+    if ((unsigned int)flagnum < NOUTFLAGS)
         s = outflags[flagnum];
-    }
-    if (s == NULL)
+    if (s == NULL) {
         /* Assume that krb5_flags are 32 bits long. */
-        asprintf(outstr, "0x%08lx", 1UL<<flagnum);
-    else
+        if (asprintf(outstr, "0x%08lx", 1UL << flagnum) == -1)
+            *outstr = NULL;
+    } else {
         *outstr = strdup(s);
+    }
     if (*outstr == NULL)
         return ENOMEM;
     return 0;
@@ -242,15 +244,15 @@ krb5_flags_to_strings(krb5_int32 flags, char ***outarray)
         }
         a = a_new;
         retval = krb5_flagnum_to_string(i, &a[amax++]);
+        a[amax] = NULL;
         if (retval)
             goto cleanup;
-        a[amax] = NULL;
     }
     *outarray = a;
     return 0;
 cleanup:
     for (ap = a; ap != NULL && *ap != NULL; ap++) {
-        free(ap);
+        free(*ap);
     }
     free(a);
     return retval;
diff --git a/src/tests/t_princflags.py b/src/tests/t_princflags.py
index 03817bf..6378ef9 100755
--- a/src/tests/t_princflags.py
+++ b/src/tests/t_princflags.py
@@ -103,6 +103,18 @@ def one_aclcheck(ftuple, doset):
             fail('Failed to keep flag ' + outname + ' clear')
 
 
+# Set all flags simultaneously, even the ones that aren't defined yet.
+def lamptest():
+    pat = re.compile('^Attributes: ' +
+                     ' '.join(flags2namelist(0xffffffff)) +
+                     '$', re.MULTILINE)
+    realm.run([kadminl, 'ank', '-pw', 'password', '+0xffffffff', 'test'])
+    out = realm.run([kadminl, 'getprinc', 'test'])
+    if not pat.search(out):
+        fail('Failed to simultaenously set all flags')
+    realm.run([kadminl, 'delprinc', 'test'])
+
+
 for ftuple in kadmin_ftuples:
     one_kadmin_flag(ftuple)
 
@@ -122,5 +134,6 @@ for ftuple in strconv_ftuples:
     one_aclcheck(ftuple, True)
     one_aclcheck(ftuple, False)
 
+lamptest()
 
 success('KDB principal flags')


More information about the cvs-krb5 mailing list