Add static assert to check if FuseBuffer is standard layout union.
Bug: 32260320 Test: libappfuse_test Change-Id: I6430c11fdeb2405996410c97044b4260c25209b8
This commit is contained in:
parent
a0aecda12b
commit
0d97be4d7d
2 changed files with 26 additions and 16 deletions
|
@ -21,6 +21,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
|
@ -28,9 +29,14 @@
|
|||
namespace android {
|
||||
namespace fuse {
|
||||
|
||||
template <typename T, typename Header>
|
||||
bool FuseMessage<T, Header>::CheckHeaderLength() const {
|
||||
if (sizeof(Header) <= header.len && header.len <= sizeof(T)) {
|
||||
static_assert(
|
||||
std::is_standard_layout<FuseBuffer>::value,
|
||||
"FuseBuffer must be standard layout union.");
|
||||
|
||||
template <typename T>
|
||||
bool FuseMessage<T>::CheckHeaderLength() const {
|
||||
const auto& header = static_cast<const T*>(this)->header;
|
||||
if (sizeof(header) <= header.len && header.len <= sizeof(T)) {
|
||||
return true;
|
||||
} else {
|
||||
LOG(ERROR) << "Packet size is invalid=" << header.len;
|
||||
|
@ -38,9 +44,10 @@ bool FuseMessage<T, Header>::CheckHeaderLength() const {
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Header>
|
||||
bool FuseMessage<T, Header>::CheckResult(
|
||||
template <typename T>
|
||||
bool FuseMessage<T>::CheckResult(
|
||||
int result, const char* operation_name) const {
|
||||
const auto& header = static_cast<const T*>(this)->header;
|
||||
if (result >= 0 && static_cast<uint32_t>(result) == header.len) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -51,14 +58,15 @@ bool FuseMessage<T, Header>::CheckResult(
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Header>
|
||||
bool FuseMessage<T, Header>::Read(int fd) {
|
||||
template <typename T>
|
||||
bool FuseMessage<T>::Read(int fd) {
|
||||
const ssize_t result = TEMP_FAILURE_RETRY(::read(fd, this, sizeof(T)));
|
||||
return CheckHeaderLength() && CheckResult(result, "read");
|
||||
}
|
||||
|
||||
template <typename T, typename Header>
|
||||
bool FuseMessage<T, Header>::Write(int fd) const {
|
||||
template <typename T>
|
||||
bool FuseMessage<T>::Write(int fd) const {
|
||||
const auto& header = static_cast<const T*>(this)->header;
|
||||
if (!CheckHeaderLength()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -66,8 +74,8 @@ bool FuseMessage<T, Header>::Write(int fd) const {
|
|||
return CheckResult(result, "write");
|
||||
}
|
||||
|
||||
template struct FuseMessage<FuseRequest, fuse_in_header>;
|
||||
template struct FuseMessage<FuseResponse, fuse_out_header>;
|
||||
template class FuseMessage<FuseRequest>;
|
||||
template class FuseMessage<FuseResponse>;
|
||||
|
||||
void FuseRequest::Reset(
|
||||
uint32_t data_length, uint32_t opcode, uint64_t unique) {
|
||||
|
|
|
@ -28,9 +28,9 @@ constexpr size_t kFuseMaxWrite = 256 * 1024;
|
|||
constexpr size_t kFuseMaxRead = 128 * 1024;
|
||||
constexpr int32_t kFuseSuccess = 0;
|
||||
|
||||
template<typename T, typename Header>
|
||||
struct FuseMessage {
|
||||
Header header;
|
||||
template<typename T>
|
||||
class FuseMessage {
|
||||
public:
|
||||
bool Read(int fd);
|
||||
bool Write(int fd) const;
|
||||
private:
|
||||
|
@ -40,7 +40,8 @@ struct FuseMessage {
|
|||
|
||||
// FuseRequest represents file operation requests from /dev/fuse. It starts
|
||||
// from fuse_in_header. The body layout depends on the operation code.
|
||||
struct FuseRequest final : public FuseMessage<FuseRequest, fuse_in_header> {
|
||||
struct FuseRequest : public FuseMessage<FuseRequest> {
|
||||
fuse_in_header header;
|
||||
union {
|
||||
// for FUSE_WRITE
|
||||
struct {
|
||||
|
@ -61,7 +62,8 @@ struct FuseRequest final : public FuseMessage<FuseRequest, fuse_in_header> {
|
|||
|
||||
// FuseResponse represents file operation responses to /dev/fuse. It starts
|
||||
// from fuse_out_header. The body layout depends on the operation code.
|
||||
struct FuseResponse final : public FuseMessage<FuseResponse, fuse_out_header> {
|
||||
struct FuseResponse : public FuseMessage<FuseResponse> {
|
||||
fuse_out_header header;
|
||||
union {
|
||||
// for FUSE_INIT
|
||||
fuse_init_out init_out;
|
||||
|
|
Loading…
Reference in a new issue