Bug Summary

File:tools/lldb/source/Plugins/Platform/Android/AdbClient.cpp
Location:line 378, column 21
Description:Function call argument is an uninitialized value

Annotated Source Code

1//===-- AdbClient.cpp -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// Other libraries and framework includes
11#include "lldb/Core/DataBuffer.h"
12#include "lldb/Core/DataBufferHeap.h"
13#include "lldb/Core/DataEncoder.h"
14#include "lldb/Core/DataExtractor.h"
15#include "lldb/Core/StreamString.h"
16#include "lldb/Host/FileSpec.h"
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/STLExtras.h"
20#include "llvm/Support/FileUtilities.h"
21
22// Project includes
23#include "AdbClient.h"
24
25#include <limits.h>
26
27#include <algorithm>
28#include <fstream>
29#include <sstream>
30
31using namespace lldb;
32using namespace lldb_private;
33using namespace lldb_private::platform_android;
34
35namespace {
36
37const std::chrono::seconds kReadTimeout(8);
38const char * kOKAY = "OKAY";
39const char * kFAIL = "FAIL";
40const char * kDATA = "DATA";
41const char * kDONE = "DONE";
42
43const char * kSEND = "SEND";
44const char * kRECV = "RECV";
45const char * kSTAT = "STAT";
46
47const size_t kSyncPacketLen = 8;
48// Maximum size of a filesync DATA packet.
49const size_t kMaxPushData = 2*1024;
50// Default mode for pushed files.
51const uint32_t kDefaultMode = 0100770; // S_IFREG | S_IRWXU | S_IRWXG
52
53const char * kSocketNamespaceAbstract = "localabstract";
54const char * kSocketNamespaceFileSystem = "localfilesystem";
55
56} // namespace
57
58Error
59AdbClient::CreateByDeviceID(const std::string &device_id, AdbClient &adb)
60{
61 DeviceIDList connect_devices;
62 auto error = adb.GetDevices(connect_devices);
63 if (error.Fail())
64 return error;
65
66 if (device_id.empty())
67 {
68 if (connect_devices.size() != 1)
69 return Error("Expected a single connected device, got instead %" PRIu64"l" "u",
70 static_cast<uint64_t>(connect_devices.size()));
71
72 adb.SetDeviceID(connect_devices.front());
73 }
74 else
75 {
76 auto find_it = std::find(connect_devices.begin(), connect_devices.end(), device_id);
77 if (find_it == connect_devices.end())
78 return Error("Device \"%s\" not found", device_id.c_str());
79
80 adb.SetDeviceID(*find_it);
81 }
82 return error;
83}
84
85AdbClient::AdbClient (const std::string &device_id)
86 : m_device_id (device_id)
87{
88}
89
90void
91AdbClient::SetDeviceID (const std::string &device_id)
92{
93 m_device_id = device_id;
94}
95
96const std::string&
97AdbClient::GetDeviceID() const
98{
99 return m_device_id;
100}
101
102Error
103AdbClient::Connect ()
104{
105 Error error;
106 m_conn.Connect ("connect://localhost:5037", &error);
107
108 return error;
109}
110
111Error
112AdbClient::GetDevices (DeviceIDList &device_list)
113{
114 device_list.clear ();
115
116 auto error = SendMessage ("host:devices");
117 if (error.Fail ())
118 return error;
119
120 error = ReadResponseStatus ();
121 if (error.Fail ())
122 return error;
123
124 std::vector<char> in_buffer;
125 error = ReadMessage (in_buffer);
126
127 llvm::StringRef response (&in_buffer[0], in_buffer.size ());
128 llvm::SmallVector<llvm::StringRef, 4> devices;
129 response.split (devices, "\n", -1, false);
130
131 for (const auto device: devices)
132 device_list.push_back (device.split ('\t').first);
133
134 return error;
135}
136
137Error
138AdbClient::SetPortForwarding (const uint16_t local_port, const uint16_t remote_port)
139{
140 char message[48];
141 snprintf (message, sizeof (message), "forward:tcp:%d;tcp:%d", local_port, remote_port);
142
143 const auto error = SendDeviceMessage (message);
144 if (error.Fail ())
145 return error;
146
147 return ReadResponseStatus ();
148}
149
150Error
151AdbClient::SetPortForwarding (const uint16_t local_port,
152 const char* remote_socket_name,
153 const UnixSocketNamespace socket_namespace)
154{
155 char message[PATH_MAX4096];
156 const char * sock_namespace_str = (socket_namespace == UnixSocketNamespaceAbstract) ?
157 kSocketNamespaceAbstract : kSocketNamespaceFileSystem;
158 snprintf (message, sizeof (message), "forward:tcp:%d;%s:%s",
159 local_port,
160 sock_namespace_str,
161 remote_socket_name);
162
163 const auto error = SendDeviceMessage (message);
164 if (error.Fail ())
165 return error;
166
167 return ReadResponseStatus ();
168}
169
170Error
171AdbClient::DeletePortForwarding (const uint16_t local_port)
172{
173 char message[32];
174 snprintf (message, sizeof (message), "killforward:tcp:%d", local_port);
175
176 const auto error = SendDeviceMessage (message);
177 if (error.Fail ())
178 return error;
179
180 return ReadResponseStatus ();
181}
182
183Error
184AdbClient::SendMessage (const std::string &packet, const bool reconnect)
185{
186 Error error;
187 if (reconnect)
188 {
189 error = Connect ();
190 if (error.Fail ())
191 return error;
192 }
193
194 char length_buffer[5];
195 snprintf (length_buffer, sizeof (length_buffer), "%04x", static_cast<int>(packet.size ()));
196
197 ConnectionStatus status;
198
199 m_conn.Write (length_buffer, 4, status, &error);
200 if (error.Fail ())
201 return error;
202
203 m_conn.Write (packet.c_str (), packet.size (), status, &error);
204 return error;
205}
206
207Error
208AdbClient::SendDeviceMessage (const std::string &packet)
209{
210 std::ostringstream msg;
211 msg << "host-serial:" << m_device_id << ":" << packet;
212 return SendMessage (msg.str ());
213}
214
215Error
216AdbClient::ReadMessage (std::vector<char> &message)
217{
218 message.clear ();
219
220 char buffer[5];
221 buffer[4] = 0;
222
223 auto error = ReadAllBytes (buffer, 4);
224 if (error.Fail ())
225 return error;
226
227 unsigned int packet_len = 0;
228 sscanf (buffer, "%x", &packet_len);
229
230 message.resize (packet_len, 0);
231 error = ReadAllBytes (&message[0], packet_len);
232 if (error.Fail ())
233 message.clear ();
234
235 return error;
236}
237
238Error
239AdbClient::ReadMessageStream (std::vector<char>& message, uint32_t timeout_ms)
240{
241 auto start = std::chrono::steady_clock::now();
242 message.clear();
243
244 Error error;
245 lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess;
246 char buffer[1024];
247 while (error.Success() && status == lldb::eConnectionStatusSuccess)
248 {
249 auto end = std::chrono::steady_clock::now();
250 uint32_t elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
251 if (elapsed_time >= timeout_ms)
252 return Error("Timed out");
253
254 size_t n = m_conn.Read(buffer, sizeof(buffer), 1000 * (timeout_ms - elapsed_time), status, &error);
255 if (n > 0)
256 message.insert(message.end(), &buffer[0], &buffer[n]);
257 }
258 return error;
259}
260
261Error
262AdbClient::ReadResponseStatus()
263{
264 char response_id[5];
265
266 static const size_t packet_len = 4;
267 response_id[packet_len] = 0;
268
269 auto error = ReadAllBytes (response_id, packet_len);
270 if (error.Fail ())
271 return error;
272
273 if (strncmp (response_id, kOKAY, packet_len) != 0)
274 return GetResponseError (response_id);
275
276 return error;
277}
278
279Error
280AdbClient::GetResponseError (const char *response_id)
281{
282 if (strcmp (response_id, kFAIL) != 0)
283 return Error ("Got unexpected response id from adb: \"%s\"", response_id);
284
285 std::vector<char> error_message;
286 auto error = ReadMessage (error_message);
287 if (error.Success ())
288 error.SetErrorString (std::string (&error_message[0], error_message.size ()).c_str ());
289
290 return error;
291}
292
293Error
294AdbClient::SwitchDeviceTransport ()
295{
296 std::ostringstream msg;
297 msg << "host:transport:" << m_device_id;
298
299 auto error = SendMessage (msg.str ());
300 if (error.Fail ())
301 return error;
302
303 return ReadResponseStatus ();
304}
305
306Error
307AdbClient::PullFile (const FileSpec &remote_file, const FileSpec &local_file)
308{
309 auto error = StartSync ();
310 if (error.Fail ())
311 return error;
312
313 const auto local_file_path = local_file.GetPath ();
314 llvm::FileRemover local_file_remover (local_file_path.c_str ());
315
316 std::ofstream dst (local_file_path, std::ios::out | std::ios::binary);
317 if (!dst.is_open ())
318 return Error ("Unable to open local file %s", local_file_path.c_str());
319
320 const auto remote_file_path = remote_file.GetPath (false);
321 error = SendSyncRequest (kRECV, remote_file_path.length (), remote_file_path.c_str ());
322 if (error.Fail ())
323 return error;
324
325 std::vector<char> chunk;
326 bool eof = false;
327 while (!eof)
328 {
329 error = PullFileChunk (chunk, eof);
330 if (error.Fail ())
331 return error;
332 if (!eof)
333 dst.write (&chunk[0], chunk.size ());
334 }
335
336 local_file_remover.releaseFile ();
337 return error;
338}
339
340Error
341AdbClient::PushFile (const FileSpec &local_file, const FileSpec &remote_file)
342{
343 auto error = StartSync ();
344 if (error.Fail ())
1
Taking false branch
345 return error;
346
347 const auto local_file_path (local_file.GetPath ());
348 std::ifstream src (local_file_path.c_str(), std::ios::in | std::ios::binary);
349 if (!src.is_open ())
2
Taking false branch
350 return Error ("Unable to open local file %s", local_file_path.c_str());
351
352 std::stringstream file_description;
353 file_description << remote_file.GetPath(false).c_str() << "," << kDefaultMode;
354 std::string file_description_str = file_description.str();
355 error = SendSyncRequest (kSEND, file_description_str.length(), file_description_str.c_str());
356 if (error.Fail ())
3
Taking false branch
357 return error;
358
359 char chunk[kMaxPushData];
360 while (!src.eof() && !src.read(chunk, kMaxPushData).bad())
361 {
362 size_t chunk_size = src.gcount();
363 error = SendSyncRequest(kDATA, chunk_size, chunk);
364 if (error.Fail ())
365 return Error ("Failed to send file chunk: %s", error.AsCString ());
366 }
367 error = SendSyncRequest(kDONE, local_file.GetModificationTime().seconds(), nullptr);
368 if (error.Fail ())
4
Taking false branch
369 return error;
370
371 std::string response_id;
372 uint32_t data_len;
5
'data_len' declared without an initial value
373 error = ReadSyncHeader (response_id, data_len);
6
Calling 'AdbClient::ReadSyncHeader'
8
Returning from 'AdbClient::ReadSyncHeader'
374 if (error.Fail ())
9
Taking false branch
375 return Error ("Failed to read DONE response: %s", error.AsCString ());
376 if (response_id == kFAIL)
10
Taking true branch
377 {
378 std::string error_message (data_len, 0);
11
Function call argument is an uninitialized value
379 error = ReadAllBytes (&error_message[0], data_len);
380 if (error.Fail ())
381 return Error ("Failed to read DONE error message: %s", error.AsCString ());
382 return Error ("Failed to push file: %s", error_message.c_str ());
383 }
384 else if (response_id != kOKAY)
385 return Error ("Got unexpected DONE response: %s", response_id.c_str ());
386
387 // If there was an error reading the source file, finish the adb file
388 // transfer first so that adb isn't expecting any more data.
389 if (src.bad())
390 return Error ("Failed read on %s", local_file_path.c_str());
391 return error;
392}
393
394Error
395AdbClient::StartSync ()
396{
397 auto error = SwitchDeviceTransport ();
398 if (error.Fail ())
399 return Error ("Failed to switch to device transport: %s", error.AsCString ());
400
401 error = Sync ();
402 if (error.Fail ())
403 return Error ("Sync failed: %s", error.AsCString ());
404
405 return error;
406}
407
408Error
409AdbClient::Sync ()
410{
411 auto error = SendMessage ("sync:", false);
412 if (error.Fail ())
413 return error;
414
415 return ReadResponseStatus ();
416}
417
418Error
419AdbClient::PullFileChunk (std::vector<char> &buffer, bool &eof)
420{
421 buffer.clear ();
422
423 std::string response_id;
424 uint32_t data_len;
425 auto error = ReadSyncHeader (response_id, data_len);
426 if (error.Fail ())
427 return error;
428
429 if (response_id == kDATA)
430 {
431 buffer.resize (data_len, 0);
432 error = ReadAllBytes (&buffer[0], data_len);
433 if (error.Fail ())
434 buffer.clear ();
435 }
436 else if (response_id == kDONE)
437 {
438 eof = true;
439 }
440 else if (response_id == kFAIL)
441 {
442 std::string error_message (data_len, 0);
443 error = ReadAllBytes (&error_message[0], data_len);
444 if (error.Fail ())
445 return Error ("Failed to read pull error message: %s", error.AsCString ());
446 return Error ("Failed to pull file: %s", error_message.c_str ());
447 }
448 else
449 return Error ("Pull failed with unknown response: %s", response_id.c_str ());
450
451 return Error ();
452}
453
454Error
455AdbClient::SendSyncRequest (const char *request_id, const uint32_t data_len, const void *data)
456{
457 const DataBufferSP data_sp (new DataBufferHeap (kSyncPacketLen, 0));
458 DataEncoder encoder (data_sp, eByteOrderLittle, sizeof (void*));
459 auto offset = encoder.PutData (0, request_id, strlen(request_id));
460 encoder.PutU32 (offset, data_len);
461
462 Error error;
463 ConnectionStatus status;
464 m_conn.Write (data_sp->GetBytes (), kSyncPacketLen, status, &error);
465 if (error.Fail ())
466 return error;
467
468 if (data)
469 m_conn.Write (data, data_len, status, &error);
470 return error;
471}
472
473Error
474AdbClient::ReadSyncHeader (std::string &response_id, uint32_t &data_len)
475{
476 char buffer[kSyncPacketLen];
477
478 auto error = ReadAllBytes (buffer, kSyncPacketLen);
479 if (error.Success ())
7
Taking false branch
480 {
481 response_id.assign (&buffer[0], 4);
482 DataExtractor extractor (&buffer[4], 4, eByteOrderLittle, sizeof (void*));
483 offset_t offset = 0;
484 data_len = extractor.GetU32 (&offset);
485 }
486
487 return error;
488}
489
490Error
491AdbClient::ReadAllBytes (void *buffer, size_t size)
492{
493 using namespace std::chrono;
494
495 Error error;
496 ConnectionStatus status;
497 char *read_buffer = static_cast<char*>(buffer);
498
499 auto now = steady_clock::now();
500 const auto deadline = now + kReadTimeout;
501 size_t total_read_bytes = 0;
502 while (total_read_bytes < size && now < deadline)
503 {
504 uint32_t timeout_usec = duration_cast<microseconds>(deadline - now).count();
505 auto read_bytes =
506 m_conn.Read(read_buffer + total_read_bytes, size - total_read_bytes, timeout_usec, status, &error);
507 if (error.Fail ())
508 return error;
509 total_read_bytes += read_bytes;
510 if (status != eConnectionStatusSuccess)
511 break;
512 now = steady_clock::now();
513 }
514 if (total_read_bytes < size)
515 error = Error("Unable to read requested number of bytes. Connection status: %d.", status);
516 return error;
517}
518
519Error
520AdbClient::Stat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime)
521{
522 auto error = StartSync ();
523 if (error.Fail ())
524 return error;
525
526 const std::string remote_file_path (remote_file.GetPath (false));
527 error = SendSyncRequest (kSTAT, remote_file_path.length (), remote_file_path.c_str ());
528 if (error.Fail ())
529 return Error ("Failed to send request: %s", error.AsCString ());
530
531 static const size_t stat_len = strlen (kSTAT);
532 static const size_t response_len = stat_len + (sizeof (uint32_t) * 3);
533
534 std::vector<char> buffer (response_len);
535 error = ReadAllBytes (&buffer[0], buffer.size ());
536 if (error.Fail ())
537 return Error ("Failed to read response: %s", error.AsCString ());
538
539 DataExtractor extractor (&buffer[0], buffer.size (), eByteOrderLittle, sizeof (void*));
540 offset_t offset = 0;
541
542 const void* command = extractor.GetData (&offset, stat_len);
543 if (!command)
544 return Error ("Failed to get response command");
545 const char* command_str = static_cast<const char*> (command);
546 if (strncmp (command_str, kSTAT, stat_len))
547 return Error ("Got invalid stat command: %s", command_str);
548
549 mode = extractor.GetU32 (&offset);
550 size = extractor.GetU32 (&offset);
551 mtime = extractor.GetU32 (&offset);
552 return Error ();
553}
554
555Error
556AdbClient::Shell (const char* command, uint32_t timeout_ms, std::string* output)
557{
558 auto error = SwitchDeviceTransport ();
559 if (error.Fail ())
560 return Error ("Failed to switch to device transport: %s", error.AsCString ());
561
562 StreamString adb_command;
563 adb_command.Printf("shell:%s", command);
564 error = SendMessage (adb_command.GetData(), false);
565 if (error.Fail ())
566 return error;
567
568 error = ReadResponseStatus ();
569 if (error.Fail ())
570 return error;
571
572 std::vector<char> in_buffer;
573 error = ReadMessageStream (in_buffer, timeout_ms);
574 if (error.Fail())
575 return error;
576
577 if (output)
578 output->assign(in_buffer.begin(), in_buffer.end());
579 return error;
580}