ProcessExposed.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Function.h>
  8. #include <AK/RefCounted.h>
  9. #include <AK/RefPtr.h>
  10. #include <AK/String.h>
  11. #include <AK/Types.h>
  12. #include <Kernel/Arch/x86/CPU.h>
  13. #include <Kernel/FileSystem/File.h>
  14. #include <Kernel/FileSystem/FileSystem.h>
  15. #include <Kernel/KBufferBuilder.h>
  16. #include <Kernel/KResult.h>
  17. #include <Kernel/Process.h>
  18. #include <Kernel/UserOrKernelBuffer.h>
  19. namespace Kernel {
  20. class ProcFSComponentRegistry {
  21. public:
  22. static ProcFSComponentRegistry& the();
  23. static void initialize();
  24. InodeIndex allocate_inode_index() const;
  25. ProcFSComponentRegistry();
  26. void register_new_bus_folder(ProcFSExposedDirectory&);
  27. const ProcFSBusDirectory& buses_folder() const;
  28. void register_new_process(Process&);
  29. void unregister_process(Process&);
  30. ProcFSRootDirectory& root_folder() { return *m_root_folder; }
  31. Lock& get_lock() { return m_lock; }
  32. private:
  33. Lock m_lock;
  34. NonnullRefPtr<ProcFSRootDirectory> m_root_folder;
  35. };
  36. class ProcFSExposedComponent : public RefCounted<ProcFSExposedComponent> {
  37. public:
  38. virtual KResultOr<size_t> entries_count() const { VERIFY_NOT_REACHED(); };
  39. StringView name() const { return m_name->view(); }
  40. virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, FileDescription*) const { VERIFY_NOT_REACHED(); }
  41. virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); }
  42. virtual RefPtr<ProcFSExposedComponent> lookup(StringView) { VERIFY_NOT_REACHED(); };
  43. virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer&, FileDescription*) { return KResult(EROFS); }
  44. virtual size_t size() const { return 0; }
  45. virtual mode_t required_mode() const { return 0444; }
  46. virtual uid_t owner_user() const { return 0; }
  47. virtual gid_t owner_group() const { return 0; }
  48. time_t modified_time() const { return TimeManagement::now().to_timeval().tv_sec; }
  49. virtual void prepare_for_deletion() { }
  50. virtual KResult refresh_data(FileDescription&) const
  51. {
  52. return KSuccess;
  53. }
  54. virtual NonnullRefPtr<Inode> to_inode(const ProcFS& procfs_instance) const;
  55. InodeIndex component_index() const { return m_component_index; };
  56. virtual ~ProcFSExposedComponent() = default;
  57. protected:
  58. explicit ProcFSExposedComponent(StringView name);
  59. ProcFSExposedComponent(StringView name, InodeIndex preallocated_index);
  60. private:
  61. OwnPtr<KString> m_name;
  62. InodeIndex m_component_index {};
  63. };
  64. class ProcFSExposedDirectory
  65. : public ProcFSExposedComponent
  66. , public Weakable<ProcFSExposedDirectory> {
  67. friend class ProcFSProcessDirectory;
  68. friend class ProcFSComponentRegistry;
  69. public:
  70. virtual KResultOr<size_t> entries_count() const override { return m_components.size(); };
  71. virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
  72. virtual RefPtr<ProcFSExposedComponent> lookup(StringView name) override;
  73. void add_component(const ProcFSExposedComponent&);
  74. virtual void prepare_for_deletion() override
  75. {
  76. for (auto& component : m_components) {
  77. component.prepare_for_deletion();
  78. }
  79. }
  80. virtual mode_t required_mode() const override { return 0555; }
  81. virtual NonnullRefPtr<Inode> to_inode(const ProcFS& procfs_instance) const override final;
  82. protected:
  83. explicit ProcFSExposedDirectory(StringView name);
  84. ProcFSExposedDirectory(StringView name, const ProcFSExposedDirectory& parent_folder);
  85. NonnullRefPtrVector<ProcFSExposedComponent> m_components;
  86. WeakPtr<ProcFSExposedDirectory> m_parent_folder;
  87. };
  88. class ProcFSExposedLink : public ProcFSExposedComponent {
  89. public:
  90. virtual NonnullRefPtr<Inode> to_inode(const ProcFS& procfs_instance) const override final;
  91. virtual KResultOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription* description) const override;
  92. protected:
  93. virtual bool acquire_link(KBufferBuilder& builder) = 0;
  94. explicit ProcFSExposedLink(StringView name);
  95. ProcFSExposedLink(StringView name, InodeIndex preallocated_index);
  96. mutable Lock m_lock { "ProcFSLink" };
  97. };
  98. class ProcFSProcessDirectory final
  99. : public ProcFSExposedDirectory {
  100. friend class ProcFSComponentRegistry;
  101. friend class ProcFSRootDirectory;
  102. friend class ProcFSProcessInformation;
  103. friend class ProcFSProcessPledge;
  104. friend class ProcFSProcessUnveil;
  105. friend class ProcFSProcessPerformanceEvents;
  106. friend class ProcFSProcessFileDescription;
  107. friend class ProcFSProcessFileDescriptions;
  108. friend class ProcFSProcessOverallFileDescriptions;
  109. friend class ProcFSProcessRoot;
  110. friend class ProcFSProcessVirtualMemory;
  111. friend class ProcFSProcessCurrentWorkDirectory;
  112. friend class ProcFSProcessBinary;
  113. friend class ProcFSProcessStacks;
  114. public:
  115. static NonnullRefPtr<ProcFSProcessDirectory> create(const Process&);
  116. RefPtr<Process> associated_process() { return m_associated_process; }
  117. virtual uid_t owner_user() const override { return m_associated_process ? m_associated_process->uid() : 0; }
  118. virtual gid_t owner_group() const override { return m_associated_process ? m_associated_process->gid() : 0; }
  119. virtual KResult refresh_data(FileDescription&) const override;
  120. virtual RefPtr<ProcFSExposedComponent> lookup(StringView name) override;
  121. virtual void prepare_for_deletion() override;
  122. private:
  123. void on_attach();
  124. IntrusiveListNode<ProcFSProcessDirectory, RefPtr<ProcFSProcessDirectory>> m_list_node;
  125. explicit ProcFSProcessDirectory(const Process&);
  126. RefPtr<Process> m_associated_process;
  127. };
  128. class ProcFSBusDirectory : public ProcFSExposedDirectory {
  129. friend class ProcFSComponentRegistry;
  130. public:
  131. static NonnullRefPtr<ProcFSBusDirectory> must_create(const ProcFSRootDirectory& parent_folder);
  132. private:
  133. ProcFSBusDirectory(const ProcFSRootDirectory& parent_folder);
  134. };
  135. class ProcFSRootDirectory final : public ProcFSExposedDirectory {
  136. friend class ProcFSComponentRegistry;
  137. public:
  138. virtual RefPtr<ProcFSExposedComponent> lookup(StringView name) override;
  139. RefPtr<ProcFSProcessDirectory> process_folder_for(Process&);
  140. static NonnullRefPtr<ProcFSRootDirectory> must_create();
  141. virtual ~ProcFSRootDirectory();
  142. private:
  143. virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
  144. ProcFSRootDirectory();
  145. RefPtr<ProcFSBusDirectory> m_buses_folder;
  146. IntrusiveList<ProcFSProcessDirectory, RefPtr<ProcFSProcessDirectory>, &ProcFSProcessDirectory::m_list_node> m_process_folders;
  147. };
  148. class ProcFSGlobalInformation : public ProcFSExposedComponent {
  149. public:
  150. virtual ~ProcFSGlobalInformation() override {};
  151. virtual KResultOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription* description) const override;
  152. virtual mode_t required_mode() const override { return 0444; }
  153. protected:
  154. explicit ProcFSGlobalInformation(StringView name)
  155. : ProcFSExposedComponent(name)
  156. {
  157. }
  158. virtual KResult refresh_data(FileDescription&) const override;
  159. virtual bool output(KBufferBuilder& builder) = 0;
  160. mutable SpinLock<u8> m_refresh_lock;
  161. };
  162. class ProcFSSystemBoolean : public ProcFSGlobalInformation {
  163. public:
  164. virtual bool value() const = 0;
  165. virtual void set_value(bool new_value) = 0;
  166. protected:
  167. explicit ProcFSSystemBoolean(StringView name)
  168. : ProcFSGlobalInformation(name)
  169. {
  170. }
  171. virtual bool output(KBufferBuilder& builder) override
  172. {
  173. builder.appendff("{}\n", value());
  174. return true;
  175. }
  176. };
  177. class ProcFSProcessInformation : public ProcFSExposedComponent {
  178. public:
  179. virtual ~ProcFSProcessInformation() override {};
  180. virtual KResultOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription* description) const override;
  181. virtual uid_t owner_user() const override
  182. {
  183. auto parent_folder = m_parent_folder.strong_ref();
  184. if (!parent_folder)
  185. return false;
  186. auto process = parent_folder->associated_process();
  187. if (!process)
  188. return false;
  189. return process->uid();
  190. }
  191. virtual gid_t owner_group() const override
  192. {
  193. auto parent_folder = m_parent_folder.strong_ref();
  194. if (!parent_folder)
  195. return false;
  196. auto process = parent_folder->associated_process();
  197. if (!process)
  198. return false;
  199. return process->gid();
  200. }
  201. protected:
  202. ProcFSProcessInformation(StringView name, const ProcFSProcessDirectory& process_folder)
  203. : ProcFSExposedComponent(name)
  204. , m_parent_folder(process_folder)
  205. {
  206. }
  207. virtual KResult refresh_data(FileDescription&) const override;
  208. virtual bool output(KBufferBuilder& builder) = 0;
  209. WeakPtr<ProcFSProcessDirectory> m_parent_folder;
  210. mutable SpinLock<u8> m_refresh_lock;
  211. };
  212. }