summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaichi Hirono2016-11-09 18:17:17 -0600
committerDaichi Hirono2016-11-14 19:18:37 -0600
commit0d97be4d7db1baa831d0432229dec08c87193919 (patch)
tree7f0bd712b7e52ed12b56c89fb4e743073003d05c /libappfuse
parenta0aecda12b9a76aa15a8c5175e15538574a05af7 (diff)
downloadplatform-system-core-0d97be4d7db1baa831d0432229dec08c87193919.tar.gz
platform-system-core-0d97be4d7db1baa831d0432229dec08c87193919.tar.xz
platform-system-core-0d97be4d7db1baa831d0432229dec08c87193919.zip
Add static assert to check if FuseBuffer is standard layout union.
Bug: 32260320 Test: libappfuse_test Change-Id: I6430c11fdeb2405996410c97044b4260c25209b8
Diffstat (limited to 'libappfuse')
-rw-r--r--libappfuse/FuseBuffer.cc30
-rw-r--r--libappfuse/include/libappfuse/FuseBuffer.h12
2 files changed, 26 insertions, 16 deletions
diff --git a/libappfuse/FuseBuffer.cc b/libappfuse/FuseBuffer.cc
index ca47aa8c7..74fe756a9 100644
--- a/libappfuse/FuseBuffer.cc
+++ b/libappfuse/FuseBuffer.cc
@@ -21,6 +21,7 @@
21#include <unistd.h> 21#include <unistd.h>
22 22
23#include <algorithm> 23#include <algorithm>
24#include <type_traits>
24 25
25#include <android-base/logging.h> 26#include <android-base/logging.h>
26#include <android-base/macros.h> 27#include <android-base/macros.h>
@@ -28,9 +29,14 @@
28namespace android { 29namespace android {
29namespace fuse { 30namespace fuse {
30 31
31template <typename T, typename Header> 32static_assert(
32bool FuseMessage<T, Header>::CheckHeaderLength() const { 33 std::is_standard_layout<FuseBuffer>::value,
33 if (sizeof(Header) <= header.len && header.len <= sizeof(T)) { 34 "FuseBuffer must be standard layout union.");
35
36template <typename T>
37bool FuseMessage<T>::CheckHeaderLength() const {
38 const auto& header = static_cast<const T*>(this)->header;
39 if (sizeof(header) <= header.len && header.len <= sizeof(T)) {
34 return true; 40 return true;
35 } else { 41 } else {
36 LOG(ERROR) << "Packet size is invalid=" << header.len; 42 LOG(ERROR) << "Packet size is invalid=" << header.len;
@@ -38,9 +44,10 @@ bool FuseMessage<T, Header>::CheckHeaderLength() const {
38 } 44 }
39} 45}
40 46
41template <typename T, typename Header> 47template <typename T>
42bool FuseMessage<T, Header>::CheckResult( 48bool FuseMessage<T>::CheckResult(
43 int result, const char* operation_name) const { 49 int result, const char* operation_name) const {
50 const auto& header = static_cast<const T*>(this)->header;
44 if (result >= 0 && static_cast<uint32_t>(result) == header.len) { 51 if (result >= 0 && static_cast<uint32_t>(result) == header.len) {
45 return true; 52 return true;
46 } else { 53 } else {
@@ -51,14 +58,15 @@ bool FuseMessage<T, Header>::CheckResult(
51 } 58 }
52} 59}
53 60
54template <typename T, typename Header> 61template <typename T>
55bool FuseMessage<T, Header>::Read(int fd) { 62bool FuseMessage<T>::Read(int fd) {
56 const ssize_t result = TEMP_FAILURE_RETRY(::read(fd, this, sizeof(T))); 63 const ssize_t result = TEMP_FAILURE_RETRY(::read(fd, this, sizeof(T)));
57 return CheckHeaderLength() && CheckResult(result, "read"); 64 return CheckHeaderLength() && CheckResult(result, "read");
58} 65}
59 66
60template <typename T, typename Header> 67template <typename T>
61bool FuseMessage<T, Header>::Write(int fd) const { 68bool FuseMessage<T>::Write(int fd) const {
69 const auto& header = static_cast<const T*>(this)->header;
62 if (!CheckHeaderLength()) { 70 if (!CheckHeaderLength()) {
63 return false; 71 return false;
64 } 72 }
@@ -66,8 +74,8 @@ bool FuseMessage<T, Header>::Write(int fd) const {
66 return CheckResult(result, "write"); 74 return CheckResult(result, "write");
67} 75}
68 76
69template struct FuseMessage<FuseRequest, fuse_in_header>; 77template class FuseMessage<FuseRequest>;
70template struct FuseMessage<FuseResponse, fuse_out_header>; 78template class FuseMessage<FuseResponse>;
71 79
72void FuseRequest::Reset( 80void FuseRequest::Reset(
73 uint32_t data_length, uint32_t opcode, uint64_t unique) { 81 uint32_t data_length, uint32_t opcode, uint64_t unique) {
diff --git a/libappfuse/include/libappfuse/FuseBuffer.h b/libappfuse/include/libappfuse/FuseBuffer.h
index 1464142c4..e7f620cb6 100644
--- a/libappfuse/include/libappfuse/FuseBuffer.h
+++ b/libappfuse/include/libappfuse/FuseBuffer.h
@@ -28,9 +28,9 @@ constexpr size_t kFuseMaxWrite = 256 * 1024;
28constexpr size_t kFuseMaxRead = 128 * 1024; 28constexpr size_t kFuseMaxRead = 128 * 1024;
29constexpr int32_t kFuseSuccess = 0; 29constexpr int32_t kFuseSuccess = 0;
30 30
31template<typename T, typename Header> 31template<typename T>
32struct FuseMessage { 32class FuseMessage {
33 Header header; 33 public:
34 bool Read(int fd); 34 bool Read(int fd);
35 bool Write(int fd) const; 35 bool Write(int fd) const;
36 private: 36 private:
@@ -40,7 +40,8 @@ struct FuseMessage {
40 40
41// FuseRequest represents file operation requests from /dev/fuse. It starts 41// FuseRequest represents file operation requests from /dev/fuse. It starts
42// from fuse_in_header. The body layout depends on the operation code. 42// from fuse_in_header. The body layout depends on the operation code.
43struct FuseRequest final : public FuseMessage<FuseRequest, fuse_in_header> { 43struct FuseRequest : public FuseMessage<FuseRequest> {
44 fuse_in_header header;
44 union { 45 union {
45 // for FUSE_WRITE 46 // for FUSE_WRITE
46 struct { 47 struct {
@@ -61,7 +62,8 @@ struct FuseRequest final : public FuseMessage<FuseRequest, fuse_in_header> {
61 62
62// FuseResponse represents file operation responses to /dev/fuse. It starts 63// FuseResponse represents file operation responses to /dev/fuse. It starts
63// from fuse_out_header. The body layout depends on the operation code. 64// from fuse_out_header. The body layout depends on the operation code.
64struct FuseResponse final : public FuseMessage<FuseResponse, fuse_out_header> { 65struct FuseResponse : public FuseMessage<FuseResponse> {
66 fuse_out_header header;
65 union { 67 union {
66 // for FUSE_INIT 68 // for FUSE_INIT
67 fuse_init_out init_out; 69 fuse_init_out init_out;