Skip to content

Commit

Permalink
Construct error messages for BinderService in native code
Browse files Browse the repository at this point in the history
The native side can describe better than the Java side what went wrong.
Needs adjustments on the Java side as well.
  • Loading branch information
rovo89 committed Mar 8, 2015
1 parent 5d02d5d commit f2e5529
Showing 1 changed file with 34 additions and 6 deletions.
40 changes: 34 additions & 6 deletions xposed_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <binder/ProcessState.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <sys/mman.h>

#define UID_SYSTEM 1000
Expand Down Expand Up @@ -399,7 +400,8 @@ class IXposedService: public IInterface {
int64_t* size,
int64_t* mtime,
uint8_t** buffer,
int32_t* bytesRead) const = 0;
int32_t* bytesRead,
String16* errormsg) const = 0;

enum {
TEST_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
Expand Down Expand Up @@ -470,7 +472,7 @@ class BpXposedService: public BpInterface<IXposedService> {
}

virtual status_t readFile(const String16& filename, int32_t offset, int32_t length,
int64_t* size, int64_t* mtime, uint8_t** buffer, int32_t* bytesRead) const {
int64_t* size, int64_t* mtime, uint8_t** buffer, int32_t* bytesRead, String16* errormsg) const {
Parcel data, reply;
data.writeInterfaceToken(IXposedService::getInterfaceDescriptor());
data.writeString16(filename);
Expand All @@ -487,12 +489,14 @@ class BpXposedService: public BpInterface<IXposedService> {
if (reply.readExceptionCode() != 0) return -1;

status_t err = reply.readInt32();
const String16& errormsg1(reply.readString16());
size1 = reply.readInt64();
mtime1 = reply.readInt64();
int32_t bytesRead1 = reply.readInt32();
if (size != NULL) *size = size1;
if (mtime != NULL) *mtime = mtime1;
if (bytesRead != NULL) *bytesRead = bytesRead1;
if (errormsg) *errormsg = errormsg1;

if (bytesRead1 > 0 && bytesRead1 <= (int32_t)reply.dataAvail()) {
*buffer = (uint8_t*) malloc(bytesRead1 + 1);
Expand Down Expand Up @@ -565,11 +569,13 @@ status_t BnXposedService::onTransact(uint32_t code, const Parcel& data, Parcel*
int64_t mtime = data.readInt64();
uint8_t* buffer = NULL;
int32_t bytesRead = -1;
String16 errormsg;

status_t err = readFile(filename, offset, length, &size, &mtime, &buffer, &bytesRead);
status_t err = readFile(filename, offset, length, &size, &mtime, &buffer, &bytesRead, &errormsg);

reply->writeNoException();
reply->writeInt32(err);
reply->writeString16(errormsg);
reply->writeInt64(size);
reply->writeInt64(mtime);
if (bytesRead > 0) {
Expand Down Expand Up @@ -610,12 +616,24 @@ class XposedService : public BnXposedService {
int64_t* size,
int64_t* mtime,
uint8_t** buffer,
int32_t* bytesRead) const;
int32_t* bytesRead,
String16* errormsg) const;

private:
bool isSystem;
};

static String16 formatToString16(const char* fmt, ...) {
char* message;
va_list args;
va_start(args, fmt);
int size = vasprintf(&message, fmt, args);
String16 result(message, size);
free(message);
va_end(args);
return result;
}

XposedService::XposedService(bool system)
: isSystem(system) {}

Expand Down Expand Up @@ -670,7 +688,7 @@ status_t XposedService::statFile(const String16& filename16, int64_t* size, int6
}

status_t XposedService::readFile(const String16& filename16, int32_t offset, int32_t length,
int64_t* size, int64_t* mtime, uint8_t** buffer, int32_t* bytesRead) const {
int64_t* size, int64_t* mtime, uint8_t** buffer, int32_t* bytesRead, String16* errormsg) const {

uid_t caller = IPCThreadState::self()->getCallingUid();
if (caller != UID_SYSTEM) {
Expand All @@ -685,10 +703,13 @@ status_t XposedService::readFile(const String16& filename16, int32_t offset, int
const char* filename = String8(filename16).string();
struct stat st;
if (stat(filename, &st) != 0) {
return errno;
status_t err = errno;
if (errormsg) *errormsg = formatToString16("%s during stat() on %s", strerror(err), filename);
return err;
}

if (S_ISDIR(st.st_mode)) {
if (errormsg) *errormsg = formatToString16("%s is a directory", filename);
return EISDIR;
}

Expand All @@ -702,12 +723,14 @@ status_t XposedService::readFile(const String16& filename16, int32_t offset, int

// Check range
if (offset > 0 && offset >= *size) {
if (errormsg) *errormsg = formatToString16("offset %d >= size %"PRId64" for %s", offset, *size, filename);
return EINVAL;
} else if (offset < 0) {
offset = 0;
}

if (length > 0 && (offset + length) > *size) {
if (errormsg) *errormsg = formatToString16("offset %d + length %d > size %"PRId64" for %s", offset, length, *size, filename);
return EINVAL;
} else if (*size == 0) {
*bytesRead = 0;
Expand All @@ -719,6 +742,7 @@ status_t XposedService::readFile(const String16& filename16, int32_t offset, int
// Allocate buffer
*buffer = (uint8_t*) malloc(length + 1);
if (*buffer == NULL) {
if (errormsg) *errormsg = formatToString16("allocating buffer with %d bytes failed", length + 1);
return ENOMEM;
}
(*buffer)[length] = 0;
Expand All @@ -729,13 +753,16 @@ status_t XposedService::readFile(const String16& filename16, int32_t offset, int
status_t err = errno;
free(*buffer);
*buffer = NULL;
if (errormsg) *errormsg = formatToString16("%s during fopen() on %s", strerror(err), filename);
return err;
}

// Seek to correct offset
if (offset > 0 && fseek(f, offset, SEEK_SET) != 0) {
free(*buffer);
*buffer = NULL;
status_t err = ferror(f);
if (errormsg) *errormsg = formatToString16("%s during fseek() to offset %d for %s", strerror(err), offset, filename);
return ferror(f);
}

Expand All @@ -746,6 +773,7 @@ status_t XposedService::readFile(const String16& filename16, int32_t offset, int
free(*buffer);
*buffer = NULL;
*bytesRead = -1;
if (errormsg) *errormsg = formatToString16("%s during fread(), read %d bytes for %s", strerror(err), *bytesRead, filename);
}

// Close the file
Expand Down

0 comments on commit f2e5529

Please sign in to comment.