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/strings/str_format.h" 26 #include "sandboxed_api/var_abstract.h" 27 #include "sandboxed_api/var_reg.h" 28 29 namespace sapi::v { 30 31 // Class representing a pointer. Takes both Var* and regular pointers in the 32 // initializers. 33 class Ptr : public Reg<Var*> { 34 public: 35 Ptr() = delete; 36 Ptr(Var * value,SyncType sync_type)37 explicit Ptr(Var* value, SyncType sync_type) : sync_type_(sync_type) { 38 Reg<Var*>::SetValue(value); 39 } 40 GetPointedVar()41 Var* GetPointedVar() const { return Reg<Var*>::GetValue(); } 42 SetValue(Var * ptr)43 void SetValue(Var* ptr) final { value_->SetRemote(ptr); } 44 GetValue()45 Var* GetValue() const final { 46 return reinterpret_cast<Var*>(value_->GetRemote()); 47 } 48 GetDataPtr()49 const void* GetDataPtr() final { 50 remote_ptr_cache_ = GetValue(); 51 return &remote_ptr_cache_; 52 } 53 SetDataFromPtr(const void * ptr,size_t max_sz)54 void SetDataFromPtr(const void* ptr, size_t max_sz) final { 55 void* tmp; 56 memcpy(&tmp, ptr, std::min(sizeof(tmp), max_sz)); 57 SetValue(reinterpret_cast<Var*>(tmp)); 58 } 59 60 // Getter/Setter for the sync_type_ field. GetSyncType()61 SyncType GetSyncType() { return sync_type_; } SetSyncType(SyncType sync_type)62 void SetSyncType(SyncType sync_type) { sync_type_ = sync_type; } 63 ToString()64 std::string ToString() const final { 65 Var* var = GetPointedVar(); 66 return absl::StrFormat( 67 "Ptr to obj:%p (type:'%s' val:'%s'), local:%p, remote:%p, size:%tx", 68 var, var->GetTypeString(), var->ToString(), var->GetLocal(), 69 var->GetRemote(), var->GetSize()); 70 } 71 72 private: 73 // GetDataPtr() interface requires of us to return a pointer to the data 74 // (variable) that can be copied. We cannot get pointer to pointer with 75 // Var::GetRemote(), hence we cache it, and return pointer to it. 76 void* remote_ptr_cache_; 77 78 // Shall we synchronize the underlying object before/after call. 79 SyncType sync_type_; 80 }; 81 82 // Good, old nullptr 83 class ABSL_DEPRECATED( 84 "Use regular `nullptr` or `NULL` instead. This class will eventually get " 85 "removed") NullPtr : public Ptr { 86 public: NullPtr()87 NullPtr() : Ptr(&void_obj_, SyncType::kSyncNone) {} 88 89 private: 90 Reg<void*> void_obj_; 91 }; 92 93 // Pointer, which can only point to remote memory, and is never synchronized. 94 class RemotePtr : public Ptr { 95 public: RemotePtr(void * remote_addr)96 explicit RemotePtr(void* remote_addr) 97 : Ptr(&pointed_obj_, SyncType::kSyncNone) { 98 pointed_obj_.SetRemote(remote_addr); 99 } 100 101 private: 102 Reg<void*> pointed_obj_; 103 }; 104 105 } // namespace sapi::v 106 107 #endif // SANDBOXED_API_VAR_PTR_H_ 108