Skip to content

Commit

Permalink
feat: Add a test verifying UDF has no Linux capabilities
Browse files Browse the repository at this point in the history
https://man7.org/linux/man-pages/man7/capabilities.7.html

Bug: b/365984931
Change-Id: Ib5639226dcd94f461991dd3726eea1f05366f951
GitOrigin-RevId: 4e378be60a83bf61ebd3a9384145fdd9d8ec19d2
  • Loading branch information
Privacy Sandbox Team authored and copybara-github committed Nov 27, 2024
1 parent 26d30e1 commit c9d7c29
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/roma/byob/sample_udf/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,19 @@ cc_binary(
],
)

cc_binary(
name = "cap_udf",
srcs = ["cap_udf.cc"],
visibility = ["//visibility:public"],
deps = [
":sample_byob_sdk_cc_proto",
"@com_google_absl//absl/cleanup",
"@com_google_absl//absl/strings",
"@com_google_protobuf//:protobuf",
"@libcap",
],
)

cc_binary(
name = "pause_udf",
srcs = ["pause_udf.cc"],
Expand Down Expand Up @@ -327,6 +340,7 @@ filegroup(
srcs = [
":abort_early_udf",
":abort_late_udf",
":cap_udf",
":log_benchmark_udf",
":log_udf",
":new_udf",
Expand Down
64 changes: 64 additions & 0 deletions src/roma/byob/sample_udf/cap_udf.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <sys/capability.h>

#include <iostream>

#include "absl/cleanup/cleanup.h"
#include "absl/strings/str_cat.h"
#include "google/protobuf/util/delimited_message_util.h"
#include "src/roma/byob/sample_udf/sample_udf_interface.pb.h"

using ::google::protobuf::io::FileInputStream;
using ::google::protobuf::util::ParseDelimitedFromZeroCopyStream;
using ::google::protobuf::util::SerializeDelimitedToFileDescriptor;
using ::privacy_sandbox::roma_byob::example::SampleRequest;
using ::privacy_sandbox::roma_byob::example::SampleResponse;

void ReadRequestFromFd(int fd) {
SampleRequest bin_request;
FileInputStream input(fd);
ParseDelimitedFromZeroCopyStream(&bin_request, &input, nullptr);
}

void WriteResponseToFd(int fd, SampleResponse resp) {
google::protobuf::util::SerializeDelimitedToFileDescriptor(resp, fd);
}

int main(int argc, char* argv[]) {
if (argc < 2) {
std::cerr << "Not enough arguments!" << std::endl;
return -1;
}
int fd = std::stoi(argv[1]);
ReadRequestFromFd(fd);
SampleResponse bin_response;
cap_t caps = cap_get_proc();
absl::Cleanup caps_cleaner = [caps] { cap_free(caps); };
if (caps == nullptr) {
bin_response.set_greeting("Failed to get capabilites.");
} else if (cap_t empty_caps = cap_init();
cap_compare(caps, empty_caps) == 0) {
// All good.
cap_free(empty_caps);
bin_response.set_greeting("Empty capabilities' set as expected.");
} else {
char* cap_str = cap_to_text(caps, nullptr);
bin_response.set_greeting(
absl::StrCat("Non-empty capability set: ", cap_str));
}
WriteResponseToFd(fd, std::move(bin_response));
return 0;
}
11 changes: 11 additions & 0 deletions src/roma/byob/test/roma_byob_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ using ::privacy_sandbox::server_common::byob::Mode;
const std::filesystem::path kUdfPath = "/udf";
const std::filesystem::path kGoLangBinaryFilename = "sample_go_udf";
const std::filesystem::path kCPlusPlusBinaryFilename = "sample_udf";
const std::filesystem::path kCPlusPlusCapBinaryFilename = "cap_udf";
const std::filesystem::path kCPlusPlusNewBinaryFilename = "new_udf";
const std::filesystem::path kCPlusPlusLogBinaryFilename = "log_udf";
const std::filesystem::path kCPlusPlusPauseBinaryFilename = "pause_udf";
Expand Down Expand Up @@ -424,5 +425,15 @@ TEST(RomaByobTest, VerifyHardLinkExecuteWorksAfterDeleteOriginal) {
EXPECT_THAT(response_and_logs.second,
::testing::StrEq("I am a stderr log.\n"));
}

TEST(RomaByobTest, VerifyNoCapabilities) {
ByobSampleService<> roma_service = GetRomaService(Mode::kModeSandbox);

std::string code_token =
LoadCode(roma_service, kUdfPath / kCPlusPlusCapBinaryFilename);

EXPECT_THAT(SendRequestAndGetResponse(roma_service, code_token).greeting(),
::testing::StrEq("Empty capabilities' set as expected."));
}
} // namespace
} // namespace privacy_sandbox::server_common::byob::test

0 comments on commit c9d7c29

Please sign in to comment.