Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv24704
Modified Files:
sort.c
Log Message:
Resolves: #472457
Summary: Specially crafted Server Side Sort crashes directory server or makes
it unresponsive
Description: The cause of the problem was a buffer overflow. The length of the
2 sort specs "-sn;2.16.840.1.113730.3.3.2.18.1.6 -givenName;2.16.840.1.113730.3.
3.2.18.1.6 " is just about the prepared buffer size, which is unfortunate since
there is no space for the candidate size, e.g., "(1944)" being added later. By
adding the "(1944)" to the static buffer, it caused buffer overflow and crashed
your server. The code to check the length of the candidate size before
calculating the buffer size is added.
Index: sort.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/sort.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- sort.c 15 Oct 2008 06:30:10 -0000 1.12
+++ sort.c 24 Nov 2008 20:26:32 -0000 1.13
@@ -113,22 +113,32 @@
int size = SORT_LOG_BSZ + SORT_LOG_PAD;
char *prefix = "SORT ";
int prefix_size = strlen(prefix);
+ char candidate_buffer[32]; /* store u_long value; max 20 digits */
+ int candidate_size = 0;
buffer = stack_buffer;
size -= PR_snprintf(buffer,sizeof(stack_buffer),"%s",prefix);
+ if (candidates) {
+ if (ALLIDS(candidates)) {
+ PR_snprintf(candidate_buffer, sizeof(candidate_buffer), "(*)");
+ candidate_size = strlen(candidate_buffer);
+ } else {
+ PR_snprintf(candidate_buffer, sizeof(candidate_buffer),
+ "(%lu)", (u_long)candidates->b_nids);
+ candidate_size = strlen(candidate_buffer);
+ }
+ }
+ size -= (candidate_size + 1); /* 1 for '\0' */
ret = print_out_sort_spec(buffer+prefix_size,s,&size);
if (0 != ret) {
/* It wouldn't fit in the buffer */
- buffer = slapi_ch_malloc(prefix_size + size + SORT_LOG_PAD);
+ buffer =
+ slapi_ch_malloc(prefix_size + size + candidate_size + SORT_LOG_PAD);
sprintf(buffer,"%s",prefix);
ret = print_out_sort_spec(buffer+prefix_size,s,&size);
}
- if (candidates) {
- if (ALLIDS(candidates)) {
- sprintf(buffer+size+prefix_size,"(*)");
- } else {
- sprintf(buffer+size+prefix_size,"(%lu)",(u_long)candidates->b_nids);
- }
+ if (0 == ret && candidates) {
+ sprintf(buffer+size+prefix_size, "%s", candidate_buffer);
}
/* Now output it */
ldbm_log_access_message(pb,buffer);
Show replies by date