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

Side by Side Diff: ipc/ipc_channel_reader.cc

Issue 1345353004: Resize IPC input buffer to fit the next message. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix overflow test to actually overflow on 32-bit Created 5 years, 2 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ipc/ipc_channel_reader.h" 5 #include "ipc/ipc_channel_reader.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ipc/ipc_listener.h" 9 #include "ipc/ipc_listener.h"
10 #include "ipc/ipc_logging.h" 10 #include "ipc/ipc_logging.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 bool ChannelReader::TranslateInputData(const char* input_data, 71 bool ChannelReader::TranslateInputData(const char* input_data,
72 int input_data_len) { 72 int input_data_len) {
73 const char* p; 73 const char* p;
74 const char* end; 74 const char* end;
75 75
76 // Possibly combine with the overflow buffer to make a larger buffer. 76 // Possibly combine with the overflow buffer to make a larger buffer.
77 if (input_overflow_buf_.empty()) { 77 if (input_overflow_buf_.empty()) {
78 p = input_data; 78 p = input_data;
79 end = input_data + input_data_len; 79 end = input_data + input_data_len;
80 } else { 80 } else {
81 if (input_overflow_buf_.size() + input_data_len > 81 if (!CheckMessageSize(input_overflow_buf_.size() + input_data_len))
82 Channel::kMaximumMessageSize) {
83 input_overflow_buf_.clear();
84 LOG(ERROR) << "IPC message is too big";
85 return false; 82 return false;
86 }
87 input_overflow_buf_.append(input_data, input_data_len); 83 input_overflow_buf_.append(input_data, input_data_len);
88 p = input_overflow_buf_.data(); 84 p = input_overflow_buf_.data();
89 end = p + input_overflow_buf_.size(); 85 end = p + input_overflow_buf_.size();
90 } 86 }
91 87
88 size_t next_message_size = 0;
89
92 // Dispatch all complete messages in the data buffer. 90 // Dispatch all complete messages in the data buffer.
93 while (p < end) { 91 while (p < end) {
94 Message::NextMessageInfo info; 92 Message::NextMessageInfo info;
95 Message::FindNext(p, end, &info); 93 Message::FindNext(p, end, &info);
96 if (info.message_found) { 94 if (info.message_found) {
97 int pickle_len = static_cast<int>(info.pickle_end - p); 95 int pickle_len = static_cast<int>(info.pickle_end - p);
98 Message translated_message(p, pickle_len); 96 Message translated_message(p, pickle_len);
99 97
100 for (const auto& id : info.attachment_ids) 98 for (const auto& id : info.attachment_ids)
101 translated_message.AddPlaceholderBrokerableAttachmentWithId(id); 99 translated_message.AddPlaceholderBrokerableAttachmentWithId(id);
(...skipping 18 matching lines...) Expand all
120 blocked_ids_.swap(blocked_ids); 118 blocked_ids_.swap(blocked_ids);
121 StartObservingAttachmentBroker(); 119 StartObservingAttachmentBroker();
122 } 120 }
123 121
124 // Make a deep copy of |translated_message| to add to the queue. 122 // Make a deep copy of |translated_message| to add to the queue.
125 scoped_ptr<Message> m(new Message(translated_message)); 123 scoped_ptr<Message> m(new Message(translated_message));
126 queued_messages_.push_back(m.release()); 124 queued_messages_.push_back(m.release());
127 p = info.message_end; 125 p = info.message_end;
128 } else { 126 } else {
129 // Last message is partial. 127 // Last message is partial.
128 next_message_size = info.message_size;
129 if (!CheckMessageSize(next_message_size))
130 return false;
130 break; 131 break;
131 } 132 }
132 } 133 }
133 134
134 // Save any partial data in the overflow buffer. 135 // Save any partial data in the overflow buffer.
135 input_overflow_buf_.assign(p, end - p); 136 input_overflow_buf_.assign(p, end - p);
136 137
138 if (!input_overflow_buf_.empty()) {
139 // We have something in the overflow buffer, which means that we will
140 // append the next data chunk (instead of parsing it directly). So we
141 // resize the buffer to fit the next message, to avoid repeatedly
142 // growing the buffer as we receive all message' data chunks.
143 next_message_size += Channel::kReadBufferSize - 1;
144 if (next_message_size > input_overflow_buf_.capacity()) {
145 input_overflow_buf_.reserve(next_message_size);
146 }
147 }
148
137 if (input_overflow_buf_.empty() && !DidEmptyInputBuffers()) 149 if (input_overflow_buf_.empty() && !DidEmptyInputBuffers())
138 return false; 150 return false;
139 return true; 151 return true;
140 } 152 }
141 153
154 bool ChannelReader::CheckMessageSize(size_t size) {
Maria 2015/09/25 22:23:00 order of declarations in cc should match order of
Dmitry Skiba 2015/09/28 17:37:17 Done.
155 if (size <= Channel::kMaximumMessageSize) {
156 return true;
157 }
158 input_overflow_buf_.clear();
159 LOG(ERROR) << "IPC message is too big: " << size;
160 return false;
161 }
162
142 ChannelReader::DispatchState ChannelReader::DispatchMessages() { 163 ChannelReader::DispatchState ChannelReader::DispatchMessages() {
143 while (!queued_messages_.empty()) { 164 while (!queued_messages_.empty()) {
144 if (!blocked_ids_.empty()) 165 if (!blocked_ids_.empty())
145 return DISPATCH_WAITING_ON_BROKER; 166 return DISPATCH_WAITING_ON_BROKER;
146 167
147 Message* m = queued_messages_.front(); 168 Message* m = queued_messages_.front();
148 169
149 AttachmentIdSet blocked_ids = GetBrokeredAttachments(m); 170 AttachmentIdSet blocked_ids = GetBrokeredAttachments(m);
150 if (!blocked_ids.empty()) { 171 if (!blocked_ids.empty()) {
151 blocked_ids_.swap(blocked_ids); 172 blocked_ids_.swap(blocked_ids);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 } 265 }
245 266
246 void ChannelReader::StopObservingAttachmentBroker() { 267 void ChannelReader::StopObservingAttachmentBroker() {
247 #if USE_ATTACHMENT_BROKER 268 #if USE_ATTACHMENT_BROKER
248 GetAttachmentBroker()->RemoveObserver(this); 269 GetAttachmentBroker()->RemoveObserver(this);
249 #endif // USE_ATTACHMENT_BROKER 270 #endif // USE_ATTACHMENT_BROKER
250 } 271 }
251 272
252 } // namespace internal 273 } // namespace internal
253 } // namespace IPC 274 } // namespace IPC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698