Updated Branches:
  refs/heads/master 55f83a3a3 -> 2e8806466

[TS-1343] stat system doesn't check for buffer overflow


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/2e880646
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/2e880646
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/2e880646

Branch: refs/heads/master
Commit: 2e88064662c0e0255478c067bae365c4740c3e9f
Parents: 55f83a3
Author: Brian Geffon <[email protected]>
Authored: Tue Jul 10 17:21:21 2012 -0700
Committer: Brian Geffon <[email protected]>
Committed: Tue Jul 10 17:21:21 2012 -0700

----------------------------------------------------------------------
 CHANGES                |    2 ++
 lib/records/RecCore.cc |   27 +++++++++++++++++++++------
 2 files changed, 23 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2e880646/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 82382e7..b404605 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,7 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache Traffic Server 3.3.0
+  *) [TS-1343] Stat system doesn't check buffer sizes
+
   *) [TS-1342] Lua plugin initial hook support
 
   *) [TS-1314] Remove TS_ARG_MAX usage so that platforms with

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2e880646/lib/records/RecCore.cc
----------------------------------------------------------------------
diff --git a/lib/records/RecCore.cc b/lib/records/RecCore.cc
index b4435aa..c7e56dd 100644
--- a/lib/records/RecCore.cc
+++ b/lib/records/RecCore.cc
@@ -939,7 +939,7 @@ int
 RecGetRecordPrefix_Xmalloc(char *prefix, char **buf, int *buf_len)
 {
   int num_records = g_num_records;
-  int result_size = num_records * 128;  /* estimate buffer size */
+  int result_size = num_records * 256;  /* estimate buffer size */
   int num_matched = 0;
   char *result = NULL;
 
@@ -947,34 +947,49 @@ RecGetRecordPrefix_Xmalloc(char *prefix, char **buf, int 
*buf_len)
   memset(result, 0, result_size * sizeof(char));
 
   int i;
-  for (i = 0; i < num_records; i++) {
+  int total_bytes_written = 0;
+  int error = 0;
+  for (i = 0; !error && i < num_records; i++) {
+    int bytes_written = 0;
+    int bytes_avail = result_size - total_bytes_written;
     RecRecord *r = &(g_records[i]);
     if (strncmp(prefix, r->name, strlen(prefix)) == 0) {
       rec_mutex_acquire(&(r->lock));
       switch (r->data_type) {
       case RECD_INT:
         num_matched++;
-        sprintf(&result[strlen(result)], "%s=%" PRId64 "\r\n", r->name, 
r->data.rec_int);
+        bytes_written = snprintf(result + total_bytes_written, bytes_avail, 
"%s=%" PRId64 "\r\n", r->name, r->data.rec_int);
         break;
       case RECD_FLOAT:
         num_matched++;
-        sprintf(&result[strlen(result)], "%s=%f\r\n", r->name, 
r->data.rec_float);
+        bytes_written = snprintf(result + total_bytes_written, bytes_avail, 
"%s=%f\r\n", r->name, r->data.rec_float);
         break;
       case RECD_STRING:
         num_matched++;
-        sprintf(&result[strlen(result)], "%s=%s\r\n", r->name, 
r->data.rec_string ? r->data.rec_string : "NULL");
+        bytes_written = snprintf(result + total_bytes_written, bytes_avail, 
"%s=%s\r\n", r->name, r->data.rec_string ? r->data.rec_string : "NULL");
         break;
       case RECD_COUNTER:
         num_matched++;
-        sprintf(&result[strlen(result)], "%s=%" PRId64 "\r\n", r->name, 
r->data.rec_int);
+        bytes_written = snprintf(result + total_bytes_written, bytes_avail, 
"%s=%" PRId64 "\r\n", r->name, r->data.rec_int);
         break;
       default:
         break;
       }
+
+      if(bytes_written <= 0 || bytes_written > bytes_avail) {
+        error = 1;
+        break;
+      } else
+        total_bytes_written += bytes_written;
+
       rec_mutex_release(&(r->lock));
     }
   }
 
+  if(error || total_bytes_written == result_size) {
+    RecLog(DL_Error, "Stat system was unable to fully generate stat list, size 
exceeded limit of %d", result_size);
+  }
+
   *buf = result;
   *buf_len = strlen(result);
 

Reply via email to