Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: chrome/common/partial_circular_buffer.cc

Issue 1061053002: Fix PartialCircularBuffer OOB memcpy(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CHECK to DCHECK Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/partial_circular_buffer.h" 5 #include "chrome/common/partial_circular_buffer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 10
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 DCHECK_LT(buffer_data_->wrap_position, data_size_); 54 DCHECK_LT(buffer_data_->wrap_position, data_size_);
55 position_ = buffer_data_->end_position; 55 position_ = buffer_data_->end_position;
56 } else { 56 } else {
57 DCHECK_LT(wrap_position, data_size_); 57 DCHECK_LT(wrap_position, data_size_);
58 buffer_data_->total_written = 0; 58 buffer_data_->total_written = 0;
59 buffer_data_->wrap_position = wrap_position; 59 buffer_data_->wrap_position = wrap_position;
60 buffer_data_->end_position = 0; 60 buffer_data_->end_position = 0;
61 } 61 }
62 } 62 }
63 63
64 uint32 PartialCircularBuffer::Read(void* buffer, uint32 buffer_size) { 64 uint32 PartialCircularBuffer::Read(void* buffer, uint32 buffer_size) {
Nico 2015/04/07 16:42:16 Doesn't this have the same problem?
gzobqq 2015/04/08 12:59:02 It is a complicated function. I spent some time th
65 DCHECK(buffer_data_); 65 DCHECK(buffer_data_);
66 if (total_read_ >= buffer_data_->total_written) 66 if (total_read_ >= buffer_data_->total_written)
67 return 0; 67 return 0;
68 68
69 uint8* buffer_uint8 = reinterpret_cast<uint8*>(buffer); 69 uint8* buffer_uint8 = reinterpret_cast<uint8*>(buffer);
70 uint32 read = 0; 70 uint32 read = 0;
71 71
72 // Read from beginning part. 72 // Read from beginning part.
73 if (position_ < buffer_data_->wrap_position) { 73 if (position_ < buffer_data_->wrap_position) {
74 uint32 to_wrap_pos = buffer_data_->wrap_position - position_; 74 uint32 to_wrap_pos = buffer_data_->wrap_position - position_;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 position_ += to_read; 132 position_ += to_read;
133 total_read_ += to_read; 133 total_read_ += to_read;
134 read += to_read; 134 read += to_read;
135 DCHECK_LE(read, buffer_size); 135 DCHECK_LE(read, buffer_size);
136 DCHECK_LE(total_read_, buffer_data_->total_written); 136 DCHECK_LE(total_read_, buffer_data_->total_written);
137 return read; 137 return read;
138 } 138 }
139 139
140 void PartialCircularBuffer::Write(const void* buffer, uint32 buffer_size) { 140 void PartialCircularBuffer::Write(const void* buffer, uint32 buffer_size) {
141 DCHECK(buffer_data_); 141 DCHECK(buffer_data_);
142 uint32 position_before_write = position_; 142 const uint8* input = static_cast<const uint8*>(buffer);
Nico 2015/04/07 16:42:16 I can't see the bug, but if writing a buffer sever
gzobqq 2015/04/08 12:59:03 The second DoWrite() lacks a bounds check and can
143 143 while (buffer_size > 0) {
144 uint32 to_eof = data_size_ - position_; 144 uint32 space_left = data_size_ - position_;
145 uint32 to_write = std::min(buffer_size, to_eof); 145 uint32 write_size = std::min(buffer_size, space_left);
146 DoWrite(buffer_data_->data + position_, buffer, to_write); 146 DoWrite(buffer_data_->data + position_, input, write_size);
147 if (position_ >= data_size_) { 147 if (position_ >= data_size_) {
148 DCHECK_EQ(position_, data_size_); 148 DCHECK_EQ(position_, data_size_);
149 position_ = buffer_data_->wrap_position; 149 position_ = buffer_data_->wrap_position;
150 } 150 }
151 151 input += write_size;
152 if (to_write < buffer_size) { 152 buffer_size -= write_size;
153 uint32 remainder_to_write = buffer_size - to_write;
154 DCHECK_LT(position_, position_before_write);
155 DCHECK_LE(position_ + remainder_to_write, position_before_write);
156 DoWrite(buffer_data_->data + position_,
157 reinterpret_cast<const uint8*>(buffer) + to_write,
158 remainder_to_write);
159 } 153 }
160 } 154 }
161 155
162 void PartialCircularBuffer::DoWrite(void* dest, const void* src, uint32 num) { 156 void PartialCircularBuffer::DoWrite(void* dest, const void* src, uint32 num) {
163 memcpy(dest, src, num); 157 memcpy(dest, src, num);
164 position_ += num; 158 position_ += num;
165 buffer_data_->total_written = 159 buffer_data_->total_written =
166 std::min(buffer_data_->total_written + num, data_size_); 160 std::min(buffer_data_->total_written + num, data_size_);
167 buffer_data_->end_position = position_; 161 buffer_data_->end_position = position_;
168 } 162 }
OLDNEW
« no previous file with comments | « no previous file | chrome/common/partial_circular_buffer_unittest.cc » ('j') | chrome/common/partial_circular_buffer_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698