FileSystemSecurity.cpp (2873B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "FileSystemSecurity.h" 8 9 #include "FileSystemUtils.h" 10 #include "mozilla/ClearOnShutdown.h" 11 #include "mozilla/StaticPtr.h" 12 #include "mozilla/ipc/BackgroundParent.h" 13 14 namespace mozilla::dom { 15 16 namespace { 17 18 StaticRefPtr<FileSystemSecurity> gFileSystemSecurity; 19 20 } // namespace 21 22 /* static */ 23 already_AddRefed<FileSystemSecurity> FileSystemSecurity::Get() { 24 MOZ_ASSERT(NS_IsMainThread()); 25 mozilla::ipc::AssertIsInMainProcess(); 26 27 RefPtr<FileSystemSecurity> service = gFileSystemSecurity.get(); 28 return service.forget(); 29 } 30 31 /* static */ 32 already_AddRefed<FileSystemSecurity> FileSystemSecurity::GetOrCreate() { 33 MOZ_ASSERT(NS_IsMainThread()); 34 mozilla::ipc::AssertIsInMainProcess(); 35 36 if (!gFileSystemSecurity) { 37 gFileSystemSecurity = new FileSystemSecurity(); 38 ClearOnShutdown(&gFileSystemSecurity); 39 } 40 41 RefPtr<FileSystemSecurity> service = gFileSystemSecurity.get(); 42 return service.forget(); 43 } 44 45 FileSystemSecurity::FileSystemSecurity() { 46 MOZ_ASSERT(NS_IsMainThread()); 47 mozilla::ipc::AssertIsInMainProcess(); 48 } 49 50 FileSystemSecurity::~FileSystemSecurity() { 51 MOZ_ASSERT(NS_IsMainThread()); 52 mozilla::ipc::AssertIsInMainProcess(); 53 } 54 55 void FileSystemSecurity::GrantAccessToContentProcess( 56 ContentParentId aId, const nsAString& aDirectoryPath) { 57 MOZ_ASSERT(NS_IsMainThread()); 58 mozilla::ipc::AssertIsInMainProcess(); 59 60 mPaths.WithEntryHandle(aId, [&](auto&& entry) { 61 if (entry && entry.Data()->Contains(aDirectoryPath)) { 62 return; 63 } 64 65 entry.OrInsertWith([] { return MakeUnique<nsTArray<nsString>>(); }) 66 ->AppendElement(aDirectoryPath); 67 }); 68 } 69 70 void FileSystemSecurity::Forget(ContentParentId aId) { 71 MOZ_ASSERT(NS_IsMainThread()); 72 mozilla::ipc::AssertIsInMainProcess(); 73 74 mPaths.Remove(aId); 75 } 76 77 bool FileSystemSecurity::ContentProcessHasAccessTo(ContentParentId aId, 78 const nsAString& aPath) { 79 MOZ_ASSERT(NS_IsMainThread()); 80 mozilla::ipc::AssertIsInMainProcess(); 81 82 #if defined(XP_WIN) 83 if (StringBeginsWith(aPath, u"..\\"_ns) || 84 FindInReadable(u"\\..\\"_ns, aPath)) { 85 return false; 86 } 87 #elif defined(XP_UNIX) 88 if (StringBeginsWith(aPath, u"../"_ns) || FindInReadable(u"/../"_ns, aPath)) { 89 return false; 90 } 91 #endif 92 93 nsTArray<nsString>* paths; 94 if (!mPaths.Get(aId, &paths)) { 95 return false; 96 } 97 98 for (uint32_t i = 0, len = paths->Length(); i < len; ++i) { 99 if (FileSystemUtils::IsDescendantPath(paths->ElementAt(i), aPath)) { 100 return true; 101 } 102 } 103 104 return false; 105 } 106 107 } // namespace mozilla::dom