Add uid to OnTransactCb argument (#27328)

* Add uid to OnTransactCb argument

This will allow callback functions to check if current RPC call conforms
to the security policy.
pull/27367/head
Ming-Chuan 3 years ago committed by GitHub
parent 49f1f43418
commit 8c425189f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      src/core/ext/transport/binder/server/binder_server.cc
  2. 2
      src/core/ext/transport/binder/wire_format/binder.h
  3. 3
      src/core/ext/transport/binder/wire_format/binder_android.cc
  4. 11
      src/core/ext/transport/binder/wire_format/wire_reader_impl.cc
  5. 2
      src/core/ext/transport/binder/wire_format/wire_reader_impl.h
  6. 3
      test/core/transport/binder/end2end/fake_binder.h
  7. 34
      test/core/transport/binder/end2end/fake_binder_test.cc
  8. 4
      test/core/transport/binder/end2end/fuzzers/client_fuzzer.cc
  9. 4
      test/core/transport/binder/end2end/testing_channel_create.cc
  10. 3
      test/core/transport/binder/mock_objects.h
  11. 3
      test/core/transport/binder/wire_reader_test.cc

@ -99,9 +99,8 @@ class BinderServerListener : public Server::ListenerInterface {
void Start(Server* /*server*/,
const std::vector<grpc_pollset*>* /*pollsets*/) override {
tx_receiver_ = factory_(
[this](transaction_code_t code, grpc_binder::ReadableParcel* parcel) {
return OnSetupTransport(code, parcel);
});
[this](transaction_code_t code, grpc_binder::ReadableParcel* parcel,
int uid) { return OnSetupTransport(code, parcel, uid); });
endpoint_binder_ = tx_receiver_->GetRawBinder();
grpc_add_endpoint_binder(addr_, endpoint_binder_);
}
@ -127,12 +126,14 @@ class BinderServerListener : public Server::ListenerInterface {
private:
absl::Status OnSetupTransport(transaction_code_t code,
grpc_binder::ReadableParcel* parcel) {
grpc_binder::ReadableParcel* parcel, int uid) {
grpc_core::ExecCtx exec_ctx;
if (grpc_binder::BinderTransportTxCode(code) !=
grpc_binder::BinderTransportTxCode::SETUP_TRANSPORT) {
return absl::InvalidArgumentError("Not a SETUP_TRANSPORT request");
}
// TODO(mingcl): Verify security policy here
gpr_log(GPR_ERROR, "calling uid = %d", uid);
int version;
absl::Status status = parcel->ReadInt32(&version);
if (!status.ok()) {

@ -77,7 +77,7 @@ class ReadableParcel {
class TransactionReceiver : public HasRawBinder {
public:
using OnTransactCb =
std::function<absl::Status(transaction_code_t, ReadableParcel*)>;
std::function<absl::Status(transaction_code_t, ReadableParcel*, int uid)>;
~TransactionReceiver() override = default;
};

@ -78,7 +78,8 @@ binder_status_t f_onTransact(AIBinder* binder, transaction_code_t code,
std::unique_ptr<ReadableParcel> output =
absl::make_unique<ReadableParcelAndroid>(in);
// The lock should be released "after" the callback finishes.
absl::Status status = (*callback)(code, output.get());
absl::Status status =
(*callback)(code, output.get(), AIBinder_getCallingUid());
if (status.ok()) {
return STATUS_OK;
} else {

@ -120,8 +120,9 @@ void WireReaderImpl::SendSetupTransport(Binder* binder) {
// callback owns a Ref() when it's being invoked.
tx_receiver_ = binder->ConstructTxReceiver(
/*wire_reader_ref=*/Ref(),
[this](transaction_code_t code, ReadableParcel* readable_parcel) {
return this->ProcessTransaction(code, readable_parcel);
[this](transaction_code_t code, ReadableParcel* readable_parcel,
int uid) {
return this->ProcessTransaction(code, readable_parcel, uid);
});
gpr_log(GPR_INFO, "tx_receiver = %p", tx_receiver_->GetRawBinder());
@ -141,7 +142,8 @@ std::unique_ptr<Binder> WireReaderImpl::RecvSetupTransport() {
}
absl::Status WireReaderImpl::ProcessTransaction(transaction_code_t code,
ReadableParcel* parcel) {
ReadableParcel* parcel,
int uid) {
gpr_log(GPR_INFO, __func__);
gpr_log(GPR_INFO, "tx code = %u", code);
if (code >= static_cast<unsigned>(kFirstCallId)) {
@ -166,12 +168,15 @@ absl::Status WireReaderImpl::ProcessTransaction(transaction_code_t code,
return absl::InvalidArgumentError("Transports not connected yet");
}
// TODO(mingcl): Verify security policy for every incoming call
switch (BinderTransportTxCode(code)) {
case BinderTransportTxCode::SETUP_TRANSPORT: {
if (recvd_setup_transport_) {
return absl::InvalidArgumentError(
"Already received a SETUP_TRANSPORT request");
}
gpr_log(GPR_ERROR, "calling uid = %d", uid);
recvd_setup_transport_ = true;
int version;
RETURN_IF_ERROR(parcel->ReadInt32(&version));

@ -67,7 +67,7 @@ class WireReaderImpl : public WireReader {
std::unique_ptr<Binder> binder) override;
absl::Status ProcessTransaction(transaction_code_t code,
ReadableParcel* parcel);
ReadableParcel* parcel, int uid);
/// Send SETUP_TRANSPORT request through \p binder.
///

@ -183,7 +183,8 @@ class PersistentFakeTransactionReceiver {
std::unique_ptr<FakeBinderTunnel> tunnel);
absl::Status Receive(BinderTransportTxCode tx_code, ReadableParcel* parcel) {
return callback_(static_cast<transaction_code_t>(tx_code), parcel);
return callback_(static_cast<transaction_code_t>(tx_code), parcel,
/*uid=*/0);
}
private:

@ -47,8 +47,8 @@ TEST_P(FakeBinderTest, SendInt32) {
int called = 0;
std::unique_ptr<Binder> sender;
std::unique_ptr<TransactionReceiver> tx_receiver;
std::tie(sender, tx_receiver) =
NewBinderPair([&](transaction_code_t tx_code, ReadableParcel* parcel) {
std::tie(sender, tx_receiver) = NewBinderPair(
[&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
EXPECT_EQ(tx_code, kTxCode);
int value = 0;
EXPECT_TRUE(parcel->ReadInt32(&value).ok());
@ -72,8 +72,8 @@ TEST_P(FakeBinderTest, SendString) {
int called = 0;
std::unique_ptr<Binder> sender;
std::unique_ptr<TransactionReceiver> tx_receiver;
std::tie(sender, tx_receiver) =
NewBinderPair([&](transaction_code_t tx_code, ReadableParcel* parcel) {
std::tie(sender, tx_receiver) = NewBinderPair(
[&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
EXPECT_EQ(tx_code, kTxCode);
std::string value;
EXPECT_TRUE(parcel->ReadString(&value).ok());
@ -97,8 +97,8 @@ TEST_P(FakeBinderTest, SendByteArray) {
int called = 0;
std::unique_ptr<Binder> sender;
std::unique_ptr<TransactionReceiver> tx_receiver;
std::tie(sender, tx_receiver) =
NewBinderPair([&](transaction_code_t tx_code, ReadableParcel* parcel) {
std::tie(sender, tx_receiver) = NewBinderPair(
[&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
EXPECT_EQ(tx_code, kTxCode);
std::string value;
EXPECT_TRUE(parcel->ReadByteArray(&value).ok());
@ -127,8 +127,8 @@ TEST_P(FakeBinderTest, SendMultipleItems) {
int called = 0;
std::unique_ptr<Binder> sender;
std::unique_ptr<TransactionReceiver> tx_receiver;
std::tie(sender, tx_receiver) =
NewBinderPair([&](transaction_code_t tx_code, ReadableParcel* parcel) {
std::tie(sender, tx_receiver) = NewBinderPair(
[&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
int value_result;
EXPECT_EQ(tx_code, kTxCode);
EXPECT_TRUE(parcel->ReadInt32(&value_result).ok());
@ -163,8 +163,8 @@ TEST_P(FakeBinderTest, SendBinder) {
int called = 0;
std::unique_ptr<Binder> sender;
std::unique_ptr<TransactionReceiver> tx_receiver;
std::tie(sender, tx_receiver) =
NewBinderPair([&](transaction_code_t tx_code, ReadableParcel* parcel) {
std::tie(sender, tx_receiver) = NewBinderPair(
[&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
EXPECT_EQ(tx_code, kTxCode);
std::unique_ptr<Binder> binder;
EXPECT_TRUE(parcel->ReadBinder(&binder).ok());
@ -179,7 +179,8 @@ TEST_P(FakeBinderTest, SendBinder) {
int called2 = 0;
std::unique_ptr<TransactionReceiver> tx_receiver2 =
absl::make_unique<FakeTransactionReceiver>(
nullptr, [&](transaction_code_t tx_code, ReadableParcel* parcel) {
nullptr,
[&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
int value;
EXPECT_TRUE(parcel->ReadInt32(&value).ok());
EXPECT_EQ(value, kValue);
@ -204,8 +205,8 @@ TEST_P(FakeBinderTest, SendTransactionAfterDestruction) {
int called = 0;
{
std::unique_ptr<TransactionReceiver> tx_receiver;
std::tie(sender, tx_receiver) =
NewBinderPair([&](transaction_code_t tx_code, ReadableParcel* parcel) {
std::tie(sender, tx_receiver) = NewBinderPair(
[&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
EXPECT_EQ(tx_code, kTxCode);
int value;
EXPECT_TRUE(parcel->ReadInt32(&value).ok());
@ -275,9 +276,10 @@ TEST_P(FakeBinderTest, StressTest) {
std::unique_ptr<TransactionReceiver> tx_receiver;
int expected_tx_code = th_arg->tx_code;
std::vector<std::vector<int>>* cnt = th_arg->global_cnts;
std::tie(binder, tx_receiver) = NewBinderPair(
[tid, p, cnt, expected_tx_code](transaction_code_t tx_code,
ReadableParcel* parcel) mutable {
std::tie(binder, tx_receiver) =
NewBinderPair([tid, p, cnt, expected_tx_code](
transaction_code_t tx_code, ReadableParcel* parcel,
int /*uid*/) mutable {
EXPECT_EQ(tx_code, expected_tx_code);
int value;
EXPECT_TRUE(parcel->ReadInt32(&value).ok());

@ -187,7 +187,7 @@ void FuzzingLoop(
/*is_setup_transport=*/true);
callback(static_cast<transaction_code_t>(
grpc_binder::BinderTransportTxCode::SETUP_TRANSPORT),
parcel.get())
parcel.get(), /*uid=*/0)
.IgnoreError();
}
while (data_provider.remaining_bytes() > 0) {
@ -198,7 +198,7 @@ void FuzzingLoop(
absl::make_unique<ReadableParcelForFuzzing>(
&data_provider,
/*is_setup_transport=*/false);
callback(tx_code, parcel.get()).IgnoreError();
callback(tx_code, parcel.get(), /*uid=*/0).IgnoreError();
}
wire_reader_ref = nullptr;
}

@ -35,8 +35,8 @@ class ServerSetupTransportHelper {
: wire_reader_(absl::make_unique<WireReaderImpl>(
/*transport_stream_receiver=*/nullptr, /*is_client=*/false)) {
std::tie(endpoint_binder_, tx_receiver_) = NewBinderPair(
[this](transaction_code_t tx_code, ReadableParcel* parcel) {
return this->wire_reader_->ProcessTransaction(tx_code, parcel);
[this](transaction_code_t tx_code, ReadableParcel* parcel, int uid) {
return this->wire_reader_->ProcessTransaction(tx_code, parcel, uid);
});
}
std::unique_ptr<Binder> WaitForClientBinder() {

@ -77,7 +77,8 @@ class MockTransactionReceiver : public TransactionReceiver {
explicit MockTransactionReceiver(OnTransactCb transact_cb,
BinderTransportTxCode code,
ReadableParcel* output) {
transact_cb(static_cast<transaction_code_t>(code), output).IgnoreError();
transact_cb(static_cast<transaction_code_t>(code), output, /*uid=*/0)
.IgnoreError();
}
MOCK_METHOD(void*, GetRawBinder, (), (override));

@ -75,7 +75,8 @@ class WireReaderTest : public ::testing::Test {
template <typename T>
absl::Status CallProcessTransaction(T tx_code) {
return wire_reader_.ProcessTransaction(
static_cast<transaction_code_t>(tx_code), &mock_readable_parcel_);
static_cast<transaction_code_t>(tx_code), &mock_readable_parcel_,
/*uid=*/0);
}
std::shared_ptr<StrictMock<MockTransportStreamReceiver>>

Loading…
Cancel
Save