1 // Copyright 2019 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef SANDBOXED_API_VAR_PTR_H_ 16 #define SANDBOXED_API_VAR_PTR_H_ 17 18 #include <algorithm> 19 #include <cstring> 20 #include <memory> 21 #include <string> 22 23 #include "absl/base/attributes.h" 24 #include "absl/base/macros.h" 25 #include "absl/log/log.h" 26 #include "absl/strings/str_format.h" 27 #include "sandboxed_api/var_abstract.h" 28 #include "sandboxed_api/var_reg.h" 29 30 namespace sapi::v { 31 32 // Class representing a pointer. Takes both Var* and regular pointers in the 33 // initializers. 34 class Ptr : public Reg<Var*> { 35 public: 36 Ptr() = delete; 37 Ptr(Var * value,SyncType sync_type)38 explicit Ptr(Var* value, SyncType sync_type) : sync_type_(sync_type) { 39 Reg<Var*>::SetValue(value); 40 } 41 GetPointedVar()42 Var* GetPointedVar() const { return Reg<Var*>::GetValue(); } 43 SetValue(Var * ptr)44 void SetValue(Var* ptr) final { value_->SetRemote(ptr); } 45 GetValue()46 Var* GetValue() const final { 47 return reinterpret_cast<Var*>(value_->GetRemote()); 48 } 49 GetDataPtr()50 const void* GetDataPtr() final { 51 remote_ptr_cache_ = GetValue(); 52 return &remote_ptr_cache_; 53 } 54 SetDataFromPtr(const void * ptr,size_t max_sz)55 void SetDataFromPtr(const void* ptr, size_t max_sz) final { 56 void* tmp; 57 memcpy(&tmp, ptr, std::min(sizeof(tmp), max_sz)); 58 SetValue(reinterpret_cast<Var*>(tmp)); 59 } 60 61 // Getter/Setter for the sync_type_ field. GetSyncType()62 SyncType GetSyncType() { return sync_type_; } SetSyncType(SyncType sync_type)63 void SetSyncType(SyncType sync_type) { sync_type_ = sync_type; } 64 ToString()65 std::string ToString() const final { 66 Var* var = GetPointedVar(); 67 return absl::StrFormat( 68 "Ptr to obj:%p (type:'%s' val:'%s'), local:%p, remote:%p, size:%tx", 69 var, var->GetTypeString(), var->ToString(), var->GetLocal(), 70 var->GetRemote(), var->GetSize()); 71 } 72 73 private: 74 // GetDataPtr() interface requires of us to return a pointer to the data 75 // (variable) that can be copied. We cannot get pointer to pointer with 76 // Var::GetRemote(), hence we cache it, and return pointer to it. 77 void* remote_ptr_cache_; 78 79 // Shall we synchronize the underlying object before/after call. 80 SyncType sync_type_; 81 }; 82 83 // Good, old nullptr 84 class ABSL_DEPRECATED( 85 "Use regular `nullptr` or `NULL` instead. This class will eventually get " 86 "removed") NullPtr : public Ptr { 87 public: NullPtr()88 NullPtr() : Ptr(&void_obj_, SyncType::kSyncNone) {} 89 90 private: 91 Reg<void*> void_obj_; 92 }; 93 94 // Pointer, which can only point to remote memory, and is never synchronized. 95 class RemotePtr : public Ptr { 96 public: RemotePtr(void * remote_addr)97 explicit RemotePtr(void* remote_addr) 98 : Ptr(&pointed_obj_, SyncType::kSyncNone) { 99 pointed_obj_.SetRemote(remote_addr); 100 } 101 SetRemote(void *)102 void SetRemote(void* /* remote */) override { 103 LOG(FATAL) << "SetRemote not supported on RemotePtr"; 104 } 105 106 private: 107 Reg<void*> pointed_obj_; 108 }; 109 110 } // namespace sapi::v 111 112 #endif // SANDBOXED_API_VAR_PTR_H_ 113