Merge "Fix adb flakiness on reboot"
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 89a20f0..29d6e65 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -94,6 +94,18 @@
abort();
}
+uint32_t calculate_apacket_checksum(const apacket* p) {
+ const unsigned char* x = reinterpret_cast<const unsigned char*>(p->data);
+ uint32_t sum = 0;
+ size_t count = p->msg.data_length;
+
+ while (count-- > 0) {
+ sum += *x++;
+ }
+
+ return sum;
+}
+
apacket* get_apacket(void)
{
apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
diff --git a/adb/adb.h b/adb/adb.h
index 4db5589..faeab8d 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -18,6 +18,7 @@
#define __ADB_H
#include <limits.h>
+#include <stdint.h>
#include <sys/types.h>
#include <string>
@@ -56,25 +57,27 @@
struct usb_handle;
struct amessage {
- unsigned command; /* command identifier constant */
- unsigned arg0; /* first argument */
- unsigned arg1; /* second argument */
- unsigned data_length; /* length of payload (0 is allowed) */
- unsigned data_check; /* checksum of data payload */
- unsigned magic; /* command ^ 0xffffffff */
+ uint32_t command; /* command identifier constant */
+ uint32_t arg0; /* first argument */
+ uint32_t arg1; /* second argument */
+ uint32_t data_length; /* length of payload (0 is allowed) */
+ uint32_t data_check; /* checksum of data payload */
+ uint32_t magic; /* command ^ 0xffffffff */
};
struct apacket
{
apacket *next;
- unsigned len;
- unsigned char *ptr;
+ size_t len;
+ char* ptr;
amessage msg;
- unsigned char data[MAX_PAYLOAD];
+ char data[MAX_PAYLOAD];
};
+uint32_t calculate_apacket_checksum(const apacket* packet);
+
/* the adisconnect structure is used to record a callback that
** will be called whenever a transport is disconnected (e.g. by the user)
** this should be used to cleanup objects that depend on the
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index 4db83a4..a6f224f 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -36,11 +36,10 @@
void adb_auth_init();
int adb_auth_keygen(const char* filename);
-int adb_auth_sign(RSA* key, const unsigned char* token, size_t token_size, unsigned char* sig);
std::string adb_auth_get_userkey();
std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys();
-void send_auth_response(uint8_t *token, size_t token_size, atransport *t);
+void send_auth_response(const char* token, size_t token_size, atransport* t);
#else // !ADB_HOST
@@ -50,8 +49,8 @@
void adbd_auth_verified(atransport *t);
void adbd_cloexec_auth_socket();
-bool adbd_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_len);
-void adbd_auth_confirm_key(unsigned char *data, size_t len, atransport *t);
+bool adbd_auth_verify(const char* token, size_t token_size, const char* sig, int sig_len);
+void adbd_auth_confirm_key(const char* data, size_t len, atransport* t);
void send_auth_request(atransport *t);
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index b5b9b97..ff2d76d 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -298,14 +298,15 @@
return result;
}
-int adb_auth_sign(RSA* key, const unsigned char* token, size_t token_size, unsigned char* sig) {
+static int adb_auth_sign(RSA* key, const char* token, size_t token_size, char* sig) {
if (token_size != TOKEN_SIZE) {
D("Unexpected token size %zd", token_size);
return 0;
}
unsigned int len;
- if (!RSA_sign(NID_sha1, token, token_size, sig, &len, key)) {
+ if (!RSA_sign(NID_sha1, reinterpret_cast<const uint8_t*>(token), token_size,
+ reinterpret_cast<uint8_t*>(sig), &len, key)) {
return 0;
}
@@ -448,7 +449,7 @@
send_packet(p, t);
}
-void send_auth_response(uint8_t* token, size_t token_size, atransport* t) {
+void send_auth_response(const char* token, size_t token_size, atransport* t) {
std::shared_ptr<RSA> key = t->NextKey();
if (key == nullptr) {
// No more private keys to try, send the public key.
diff --git a/adb/adbd_auth.cpp b/adb/adbd_auth.cpp
index fa76c8d..b5f87be 100644
--- a/adb/adbd_auth.cpp
+++ b/adb/adbd_auth.cpp
@@ -46,7 +46,7 @@
bool auth_required = true;
-bool adbd_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_len) {
+bool adbd_auth_verify(const char* token, size_t token_size, const char* sig, int sig_len) {
static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr };
for (const auto& path : key_paths) {
@@ -78,7 +78,9 @@
continue;
}
- bool verified = (RSA_verify(NID_sha1, token, token_size, sig, sig_len, key) == 1);
+ bool verified =
+ (RSA_verify(NID_sha1, reinterpret_cast<const uint8_t*>(token), token_size,
+ reinterpret_cast<const uint8_t*>(sig), sig_len, key) == 1);
RSA_free(key);
if (verified) return true;
}
@@ -121,7 +123,7 @@
}
}
-void adbd_auth_confirm_key(unsigned char* key, size_t len, atransport* t) {
+void adbd_auth_confirm_key(const char* key, size_t len, atransport* t) {
if (!usb_transport) {
usb_transport = t;
t->AddDisconnect(&usb_disconnect);
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index b809c4f..fff6049 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -122,7 +122,7 @@
}
static int local_socket_enqueue(asocket* s, apacket* p) {
- D("LS(%d): enqueue %d", s->id, p->len);
+ D("LS(%d): enqueue %zu", s->id, p->len);
p->ptr = p->data;
@@ -195,7 +195,7 @@
/* dispose of any unwritten data */
for (p = s->pkt_first; p; p = n) {
- D("LS(%d): discarding %d bytes", s->id, p->len);
+ D("LS(%d): discarding %zu bytes", s->id, p->len);
n = p->next;
put_apacket(p);
}
@@ -305,7 +305,7 @@
if (ev & FDE_READ) {
apacket* p = get_apacket();
- unsigned char* x = p->data;
+ char* x = p->data;
const size_t max_payload = s->get_max_payload();
size_t avail = max_payload;
int r = 0;
@@ -553,7 +553,7 @@
s->close(s);
}
-static unsigned unhex(unsigned char* s, int len) {
+static unsigned unhex(char* s, int len) {
unsigned n = 0, c;
while (len-- > 0) {
@@ -665,7 +665,7 @@
TransportType type = kTransportAny;
#endif
- D("SS(%d): enqueue %d", s->id, p->len);
+ D("SS(%d): enqueue %zu", s->id, p->len);
if (s->pkt_first == 0) {
s->pkt_first = p;
@@ -698,7 +698,7 @@
D("SS(%d): len is %d", s->id, len);
/* can't do anything until we have the full header */
if ((len + 4) > p->len) {
- D("SS(%d): waiting for %d more bytes", s->id, len + 4 - p->len);
+ D("SS(%d): waiting for %zu more bytes", s->id, len + 4 - p->len);
return 0;
}
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 9880902..7b4bb1c 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -150,32 +150,17 @@
}
}
-void send_packet(apacket *p, atransport *t)
-{
- unsigned char *x;
- unsigned sum;
- unsigned count;
-
+void send_packet(apacket* p, atransport* t) {
p->msg.magic = p->msg.command ^ 0xffffffff;
-
- count = p->msg.data_length;
- x = (unsigned char *) p->data;
- sum = 0;
- while(count-- > 0){
- sum += *x++;
- }
- p->msg.data_check = sum;
+ p->msg.data_check = calculate_apacket_checksum(p);
print_packet("send", p);
if (t == NULL) {
- D("Transport is null");
- // Zap errno because print_packet() and other stuff have errno effect.
- errno = 0;
- fatal_errno("Transport is null");
+ fatal("Transport is null");
}
- if(write_packet(t->transport_socket, t->serial, &p)){
+ if (write_packet(t->transport_socket, t->serial, &p)) {
fatal_errno("cannot enqueue packet on transport socket");
}
}
@@ -1052,23 +1037,11 @@
return 0;
}
-int check_data(apacket *p)
-{
- unsigned count, sum;
- unsigned char *x;
-
- count = p->msg.data_length;
- x = p->data;
- sum = 0;
- while(count-- > 0) {
- sum += *x++;
- }
-
- if(sum != p->msg.data_check) {
+int check_data(apacket* p) {
+ if (calculate_apacket_checksum(p) != p->msg.data_check) {
return -1;
- } else {
- return 0;
}
+ return 0;
}
#if ADB_HOST
diff --git a/adb/transport.h b/adb/transport.h
index aaa8be4..621516c 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -112,7 +112,7 @@
std::shared_ptr<RSA> NextKey();
#endif
- unsigned char token[TOKEN_SIZE] = {};
+ char token[TOKEN_SIZE] = {};
size_t failed_auth_attempts = 0;
const std::string connection_state_name() const;
diff --git a/base/include/android-base/parseint.h b/base/include/android-base/parseint.h
index ed75e2d..7415409 100644
--- a/base/include/android-base/parseint.h
+++ b/base/include/android-base/parseint.h
@@ -31,7 +31,7 @@
template <typename T>
bool ParseUint(const char* s, T* out,
T max = std::numeric_limits<T>::max()) {
- int base = (s[0] == '0' && s[1] == 'x') ? 16 : 10;
+ int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10;
errno = 0;
char* end;
unsigned long long int result = strtoull(s, &end, base);
@@ -53,7 +53,7 @@
bool ParseInt(const char* s, T* out,
T min = std::numeric_limits<T>::min(),
T max = std::numeric_limits<T>::max()) {
- int base = (s[0] == '0' && s[1] == 'x') ? 16 : 10;
+ int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10;
errno = 0;
char* end;
long long int result = strtoll(s, &end, base);
diff --git a/cpio/mkbootfs.c b/cpio/mkbootfs.c
index 0e35323..b89c395 100644
--- a/cpio/mkbootfs.c
+++ b/cpio/mkbootfs.c
@@ -51,6 +51,8 @@
#define CANNED_LINE_LENGTH (1024)
#endif
+#define TRAILER "TRAILER!!!"
+
static int verbose = 0;
static int total_size = 0;
@@ -80,8 +82,8 @@
} else {
// Use the compiled-in fs_config() function.
unsigned st_mode = s->st_mode;
- fs_config(path, S_ISDIR(s->st_mode), target_out_path,
- &s->st_uid, &s->st_gid, &st_mode, &capabilities);
+ int is_dir = S_ISDIR(s->st_mode) || strcmp(path, TRAILER) == 0;
+ fs_config(path, is_dir, target_out_path, &s->st_uid, &s->st_gid, &st_mode, &capabilities);
s->st_mode = (typeof(s->st_mode)) st_mode;
}
}
@@ -140,7 +142,7 @@
{
struct stat s;
memset(&s, 0, sizeof(s));
- _eject(&s, "TRAILER!!!", 10, 0, 0);
+ _eject(&s, TRAILER, 10, 0, 0);
while(total_size & 0xff) {
total_size++;
diff --git a/include/cutils/native_handle.h b/include/cutils/native_handle.h
index 31695cb..813dadc 100644
--- a/include/cutils/native_handle.h
+++ b/include/cutils/native_handle.h
@@ -57,6 +57,15 @@
native_handle_t* native_handle_create(int numFds, int numInts);
/*
+ * native_handle_clone
+ *
+ * creates a native_handle_t and initializes it from another native_handle_t.
+ * Must be destroyed with native_handle_delete().
+ *
+ */
+native_handle_t* native_handle_clone(const native_handle_t* handle);
+
+/*
* native_handle_delete
*
* frees a native_handle_t allocated with native_handle_create().
diff --git a/libcutils/native_handle.c b/libcutils/native_handle.c
index 7f3479d..cae146d 100644
--- a/libcutils/native_handle.c
+++ b/libcutils/native_handle.c
@@ -44,6 +44,27 @@
return h;
}
+native_handle_t* native_handle_clone(const native_handle_t* handle)
+{
+ native_handle_t* clone = native_handle_create(handle->numFds, handle->numInts);
+ int i;
+
+ for (i = 0; i < handle->numFds; i++) {
+ clone->data[i] = dup(handle->data[i]);
+ if (clone->data[i] < 0) {
+ clone->numFds = i;
+ native_handle_close(clone);
+ native_handle_delete(clone);
+ return NULL;
+ }
+ }
+
+ memcpy(&clone->data[handle->numFds], &handle->data[handle->numFds],
+ sizeof(int) * handle->numInts);
+
+ return clone;
+}
+
int native_handle_delete(native_handle_t* h)
{
if (h) {
diff --git a/libsparse/output_file.c b/libsparse/output_file.c
index 6578d99..2115998 100644
--- a/libsparse/output_file.c
+++ b/libsparse/output_file.c
@@ -63,7 +63,7 @@
int (*open)(struct output_file *, int fd);
int (*skip)(struct output_file *, int64_t);
int (*pad)(struct output_file *, int64_t);
- int (*write)(struct output_file *, void *, int);
+ int (*write)(struct output_file *, void *, size_t);
void (*close)(struct output_file *);
};
@@ -149,18 +149,23 @@
return 0;
}
-static int file_write(struct output_file *out, void *data, int len)
+static int file_write(struct output_file *out, void *data, size_t len)
{
- int ret;
+ ssize_t ret;
struct output_file_normal *outn = to_output_file_normal(out);
- ret = write(outn->fd, data, len);
- if (ret < 0) {
- error_errno("write");
- return -1;
- } else if (ret < len) {
- error("incomplete write");
- return -1;
+ while (len > 0) {
+ ret = write(outn->fd, data, len);
+ if (ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ error_errno("write");
+ return -1;
+ }
+
+ data = (char *)data + ret;
+ len -= ret;
}
return 0;
@@ -232,18 +237,20 @@
return 0;
}
-static int gz_file_write(struct output_file *out, void *data, int len)
+static int gz_file_write(struct output_file *out, void *data, size_t len)
{
int ret;
struct output_file_gz *outgz = to_output_file_gz(out);
- ret = gzwrite(outgz->gz_fd, data, len);
- if (ret < 0) {
- error_errno("gzwrite");
- return -1;
- } else if (ret < len) {
- error("incomplete gzwrite");
- return -1;
+ while (len > 0) {
+ ret = gzwrite(outgz->gz_fd, data,
+ min(len, (unsigned int)INT_MAX));
+ if (ret == 0) {
+ error("gzwrite %s", gzerror(outgz->gz_fd, NULL));
+ return -1;
+ }
+ len -= ret;
+ data = (char *)data + ret;
}
return 0;
@@ -293,7 +300,7 @@
return -1;
}
-static int callback_file_write(struct output_file *out, void *data, int len)
+static int callback_file_write(struct output_file *out, void *data, size_t len)
{
struct output_file_callback *outc = to_output_file_callback(out);
@@ -698,14 +705,16 @@
int ret;
int64_t aligned_offset;
int aligned_diff;
- int buffer_size;
+ uint64_t buffer_size;
char *ptr;
aligned_offset = offset & ~(4096 - 1);
aligned_diff = offset - aligned_offset;
- buffer_size = len + aligned_diff;
+ buffer_size = (uint64_t)len + (uint64_t)aligned_diff;
#ifndef _WIN32
+ if (buffer_size > SIZE_MAX)
+ return -E2BIG;
char *data = mmap64(NULL, buffer_size, PROT_READ, MAP_SHARED, fd,
aligned_offset);
if (data == MAP_FAILED) {