Print this page
1668 CVE 2011-3508 (ldap format string issues)

@@ -20,14 +20,13 @@
  */
 
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  */
 
-#pragma ident   "%Z%%M% %I%     %E% SMI"
-
 #include <stdlib.h>
 #include <libintl.h>
 #include <stdio.h>
 #include <errno.h>
 #include <strings.h>

@@ -70,28 +69,41 @@
 __s_api_merge_SSD_filter(const ns_ldap_search_desc_t *desc,
                         char **realfilter,
                         const void *userdata)
 {
         int     len;
+        char *checker;
 
         /* sanity check */
         if (realfilter == NULL)
                 return (NS_LDAP_INVALID_PARAM);
         *realfilter = NULL;
 
-        if (desc == NULL || desc->filter == NULL ||
-                        userdata == NULL)
+        if (desc == NULL || desc->filter == NULL || userdata == NULL)
                 return (NS_LDAP_INVALID_PARAM);
 
+        /* Parameter check.  We only want one %s here, otherwise bail. */
+        len = 0;        /* Reuse 'len' as "Number of %s hits"... */
+        checker = (char *)userdata;
+        do {
+                checker = strchr(checker, '%');
+                if (checker != NULL) {
+                        if (len > 0 || *(checker + 1) != 's')
+                                return (NS_LDAP_INVALID_PARAM);
+                        len++;  /* Got our %s. */
+                        checker += 2;
+                } else if (len != 1)
+                        return (NS_LDAP_INVALID_PARAM);
+        } while (checker != NULL);
+
         len = strlen(userdata) + strlen(desc->filter) + 1;
 
         *realfilter = (char *)malloc(len);
         if (*realfilter == NULL)
                 return (NS_LDAP_MEMORY);
 
-        (void) sprintf(*realfilter, (char *)userdata,
-                        desc->filter);
+        (void) sprintf(*realfilter, (char *)userdata, desc->filter);
 
         return (NS_LDAP_SUCCESS);
 }
 char *
 __getldapaliasbyname(char *alias, int *retval)