Browse Source

Kernel: Let InodeWatcher track child inode numbers instead of names

First of all, this fixes a dumb info leak where we'd write kernel heap
addresses (StringImpl*) into userspace memory when reading a watcher.

Instead of trying to pass names to userspace, we now simply pass the
child inode index. Nothing in userspace makes use of this yet anyway,
so it's not like we're breaking anything. We'll see how this evolves.
Andreas Kling 4 years ago
parent
commit
2cb32f8356

+ 2 - 2
Kernel/FileSystem/Ext2FileSystem.cpp

@@ -1027,7 +1027,7 @@ KResult Ext2FSInode::add_child(Inode& child, const StringView& name, mode_t mode
     if (success)
         m_lookup_cache.set(name, child.index());
 
-    did_add_child(name);
+    did_add_child(child.identifier());
     return KSuccess;
 }
 
@@ -1072,7 +1072,7 @@ KResult Ext2FSInode::remove_child(const StringView& name)
     if (result.is_error())
         return result;
 
-    did_remove_child(name);
+    did_remove_child(child_id);
     return KSuccess;
 }
 

+ 4 - 4
Kernel/FileSystem/Inode.cpp

@@ -229,19 +229,19 @@ void Inode::set_metadata_dirty(bool metadata_dirty)
     }
 }
 
-void Inode::did_add_child(const String& name)
+void Inode::did_add_child(const InodeIdentifier& child_id)
 {
     LOCKER(m_lock);
     for (auto& watcher : m_watchers) {
-        watcher->notify_child_added({}, name);
+        watcher->notify_child_added({}, child_id);
     }
 }
 
-void Inode::did_remove_child(const String& name)
+void Inode::did_remove_child(const InodeIdentifier& child_id)
 {
     LOCKER(m_lock);
     for (auto& watcher : m_watchers) {
-        watcher->notify_child_removed({}, name);
+        watcher->notify_child_removed({}, child_id);
     }
 }
 

+ 2 - 2
Kernel/FileSystem/Inode.h

@@ -126,8 +126,8 @@ protected:
     void inode_size_changed(size_t old_size, size_t new_size);
     KResult prepare_to_write_data();
 
-    void did_add_child(const String& name);
-    void did_remove_child(const String& name);
+    void did_add_child(const InodeIdentifier&);
+    void did_remove_child(const InodeIdentifier&);
 
     mutable Lock m_lock { "Inode" };
 

+ 5 - 5
Kernel/FileSystem/InodeWatcher.cpp

@@ -96,19 +96,19 @@ String InodeWatcher::absolute_path(const FileDescription&) const
 void InodeWatcher::notify_inode_event(Badge<Inode>, Event::Type event_type)
 {
     LOCKER(m_lock);
-    m_queue.enqueue({ event_type, {} });
+    m_queue.enqueue({ event_type });
 }
 
-void InodeWatcher::notify_child_added(Badge<Inode>, const String& child_name)
+void InodeWatcher::notify_child_added(Badge<Inode>, const InodeIdentifier& child_id)
 {
     LOCKER(m_lock);
-    m_queue.enqueue({ Event::Type::ChildAdded, child_name });
+    m_queue.enqueue({ Event::Type::ChildAdded, child_id.index() });
 }
 
-void InodeWatcher::notify_child_removed(Badge<Inode>, const String& child_name)
+void InodeWatcher::notify_child_removed(Badge<Inode>, const InodeIdentifier& child_id)
 {
     LOCKER(m_lock);
-    m_queue.enqueue({ Event::Type::ChildRemoved, child_name });
+    m_queue.enqueue({ Event::Type::ChildRemoved, child_id.index() });
 }
 
 }

+ 3 - 3
Kernel/FileSystem/InodeWatcher.h

@@ -50,7 +50,7 @@ public:
         };
 
         Type type { Type::Invalid };
-        String string;
+        unsigned inode_index { 0 };
     };
 
     virtual bool can_read(const FileDescription&, size_t) const override;
@@ -61,8 +61,8 @@ public:
     virtual const char* class_name() const override { return "InodeWatcher"; };
 
     void notify_inode_event(Badge<Inode>, Event::Type);
-    void notify_child_added(Badge<Inode>, const String& child_name);
-    void notify_child_removed(Badge<Inode>, const String& child_name);
+    void notify_child_added(Badge<Inode>, const InodeIdentifier& child_id);
+    void notify_child_removed(Badge<Inode>, const InodeIdentifier& child_id);
 
 private:
     explicit InodeWatcher(Inode&);

+ 3 - 2
Kernel/FileSystem/TmpFS.cpp

@@ -298,7 +298,7 @@ KResult TmpFSInode::add_child(Inode& child, const StringView& name, mode_t)
     ASSERT(child.fsid() == fsid());
 
     m_children.set(name, { name, static_cast<TmpFSInode&>(child) });
-    did_add_child(name);
+    did_add_child(child.identifier());
     return KSuccess;
 }
 
@@ -313,8 +313,9 @@ KResult TmpFSInode::remove_child(const StringView& name)
     auto it = m_children.find(name);
     if (it == m_children.end())
         return KResult(-ENOENT);
+    auto child_id = it->value.inode->identifier();
     m_children.remove(it);
-    did_remove_child(name);
+    did_remove_child(child_id);
     return KSuccess;
 }