Re: [kernel-hardening] [PATCH 3/5] Protectable Memory Allocator - Debug interface

2017-06-06 Thread Igor Stoppa


On 05/06/17 23:24, Jann Horn wrote:
> On Mon, Jun 5, 2017 at 9:22 PM, Igor Stoppa  wrote:
>> Debugfs interface: it creates a file

[...]

> You should probably be using %pK to hide the kernel pointers.

ok, will do

---
igor


Re: [kernel-hardening] [PATCH 3/5] Protectable Memory Allocator - Debug interface

2017-06-06 Thread Igor Stoppa


On 05/06/17 23:24, Jann Horn wrote:
> On Mon, Jun 5, 2017 at 9:22 PM, Igor Stoppa  wrote:
>> Debugfs interface: it creates a file

[...]

> You should probably be using %pK to hide the kernel pointers.

ok, will do

---
igor


Re: [kernel-hardening] [PATCH 3/5] Protectable Memory Allocator - Debug interface

2017-06-05 Thread Jann Horn
On Mon, Jun 5, 2017 at 9:22 PM, Igor Stoppa  wrote:
> Debugfs interface: it creates a file
>
> /sys/kernel/debug/pmalloc/pools
>
> which exposes statistics about all the pools and memory nodes in use.
>
> Signed-off-by: Igor Stoppa 
[...]
> +   seq_printf(s, " - node:\t\t%p\n", node);
> +   seq_printf(s, "   - start of data ptr:\t%p\n", node->data);
> +   seq_printf(s, "   - end of node ptr:\t%p\n", (void *)end_of_node);
[...]
> +   seq_printf(s, "pool:\t\t\t%p\n", pool);
[...]
> +   debugfs_create_file("pools", 0644, pmalloc_root, NULL,
> +   _file_ops);

You should probably be using %pK to hide the kernel pointers.


Re: [kernel-hardening] [PATCH 3/5] Protectable Memory Allocator - Debug interface

2017-06-05 Thread Jann Horn
On Mon, Jun 5, 2017 at 9:22 PM, Igor Stoppa  wrote:
> Debugfs interface: it creates a file
>
> /sys/kernel/debug/pmalloc/pools
>
> which exposes statistics about all the pools and memory nodes in use.
>
> Signed-off-by: Igor Stoppa 
[...]
> +   seq_printf(s, " - node:\t\t%p\n", node);
> +   seq_printf(s, "   - start of data ptr:\t%p\n", node->data);
> +   seq_printf(s, "   - end of node ptr:\t%p\n", (void *)end_of_node);
[...]
> +   seq_printf(s, "pool:\t\t\t%p\n", pool);
[...]
> +   debugfs_create_file("pools", 0644, pmalloc_root, NULL,
> +   _file_ops);

You should probably be using %pK to hide the kernel pointers.


[PATCH 3/5] Protectable Memory Allocator - Debug interface

2017-06-05 Thread Igor Stoppa
Debugfs interface: it creates a file

/sys/kernel/debug/pmalloc/pools

which exposes statistics about all the pools and memory nodes in use.

Signed-off-by: Igor Stoppa 
---
 mm/Kconfig   |  11 ++
 mm/pmalloc.c | 113 +++
 2 files changed, 124 insertions(+)

diff --git a/mm/Kconfig b/mm/Kconfig
index beb7a45..dfbdc07 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -539,6 +539,17 @@ config CMA_AREAS
 
  If unsure, leave the default value "7".
 
+config PMALLOC_DEBUG
+bool "Protectable Memory Allocator debugging"
+depends on DEBUG_KERNEL
+default y
+help
+  Debugfs support for dumping information about memory pools.
+  It shows internal stats: free/used/total space, protection
+  status, data overhead, etc.
+
+  If unsure, say "y".
+
 config MEM_SOFT_DIRTY
bool "Track memory changes"
depends on CHECKPOINT_RESTORE && HAVE_ARCH_SOFT_DIRTY && PROC_FS
diff --git a/mm/pmalloc.c b/mm/pmalloc.c
index c73d60c..6dd6bbe 100644
--- a/mm/pmalloc.c
+++ b/mm/pmalloc.c
@@ -225,3 +225,116 @@ int __init pmalloc_init(void)
return 0;
 }
 EXPORT_SYMBOL(pmalloc_init);
+
+#ifdef CONFIG_PMALLOC_DEBUG
+#include 
+static struct dentry *pmalloc_root;
+
+static void *__pmalloc_seq_start(struct seq_file *s, loff_t *pos)
+{
+   if (*pos)
+   return NULL;
+   return pos;
+}
+
+static void *__pmalloc_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+   return NULL;
+}
+
+static void __pmalloc_seq_stop(struct seq_file *s, void *v)
+{
+}
+
+static __always_inline
+void __seq_printf_node(struct seq_file *s, struct pmalloc_node *node)
+{
+   unsigned long total_space, node_pages, end_of_node,
+ used_space, available_space;
+   int total_words, used_words, available_words;
+
+   used_words = atomic_read(>used_words);
+   total_words = node->total_words;
+   available_words = total_words - used_words;
+   used_space = used_words * WORD_SIZE;
+   total_space = total_words * WORD_SIZE;
+   available_space = total_space - used_space;
+   node_pages = (total_space + HEADER_SIZE) / PAGE_SIZE;
+   end_of_node = total_space + HEADER_SIZE + (unsigned long) node;
+   seq_printf(s, " - node:\t\t%p\n", node);
+   seq_printf(s, "   - start of data ptr:\t%p\n", node->data);
+   seq_printf(s, "   - end of node ptr:\t%p\n", (void *)end_of_node);
+   seq_printf(s, "   - total words:\t%d\n", total_words);
+   seq_printf(s, "   - used words:\t%d\n", used_words);
+   seq_printf(s, "   - available words:\t%d\n", available_words);
+   seq_printf(s, "   - pages:\t\t%lu\n", node_pages);
+   seq_printf(s, "   - total space:\t%lu\n", total_space);
+   seq_printf(s, "   - used space:\t%lu\n", used_space);
+   seq_printf(s, "   - available space:\t%lu\n", available_space);
+}
+
+static __always_inline
+void __seq_printf_pool(struct seq_file *s, struct pmalloc_pool *pool)
+{
+   struct pmalloc_node *node;
+
+   seq_printf(s, "pool:\t\t\t%p\n", pool);
+   seq_printf(s, " - name:\t\t%s\n", pool->name);
+   seq_printf(s, " - protected:\t\t%u\n", pool->protected);
+   seq_printf(s, " - nodes count:\t\t%u\n",
+  atomic_read(>nodes_count));
+   rcu_read_lock();
+   hlist_for_each_entry_rcu(node, >nodes_list_head, nodes_list)
+   __seq_printf_node(s, node);
+   rcu_read_unlock();
+}
+
+static int __pmalloc_seq_show(struct seq_file *s, void *v)
+{
+   struct pmalloc_pool *pool;
+
+   seq_printf(s, "pools count:\t\t%u\n",
+  atomic_read(_data->pools_count));
+   seq_printf(s, "page size:\t\t%lu\n", PAGE_SIZE);
+   seq_printf(s, "word size:\t\t%lu\n", WORD_SIZE);
+   seq_printf(s, "node header size:\t%lu\n", HEADER_SIZE);
+   rcu_read_lock();
+   hlist_for_each_entry_rcu(pool, _data->pools_list_head,
+pools_list)
+   __seq_printf_pool(s, pool);
+   rcu_read_unlock();
+   return 0;
+}
+
+static const struct seq_operations pmalloc_seq_ops = {
+   .start = __pmalloc_seq_start,
+   .next  = __pmalloc_seq_next,
+   .stop  = __pmalloc_seq_stop,
+   .show  = __pmalloc_seq_show,
+};
+
+static int __pmalloc_open(struct inode *inode, struct file *file)
+{
+   return seq_open(file, _seq_ops);
+}
+
+static const struct file_operations pmalloc_file_ops = {
+   .owner   = THIS_MODULE,
+   .open= __pmalloc_open,
+   .read= seq_read,
+   .llseek  = seq_lseek,
+   .release = seq_release
+};
+
+
+static int __init __pmalloc_init_track_pool(void)
+{
+   struct dentry *de = NULL;
+
+   pmalloc_root = debugfs_create_dir("pmalloc", NULL);
+   debugfs_create_file("pools", 0644, pmalloc_root, NULL,
+   _file_ops);
+   return 0;
+}

[PATCH 3/5] Protectable Memory Allocator - Debug interface

2017-06-05 Thread Igor Stoppa
Debugfs interface: it creates a file

/sys/kernel/debug/pmalloc/pools

which exposes statistics about all the pools and memory nodes in use.

Signed-off-by: Igor Stoppa 
---
 mm/Kconfig   |  11 ++
 mm/pmalloc.c | 113 +++
 2 files changed, 124 insertions(+)

diff --git a/mm/Kconfig b/mm/Kconfig
index beb7a45..dfbdc07 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -539,6 +539,17 @@ config CMA_AREAS
 
  If unsure, leave the default value "7".
 
+config PMALLOC_DEBUG
+bool "Protectable Memory Allocator debugging"
+depends on DEBUG_KERNEL
+default y
+help
+  Debugfs support for dumping information about memory pools.
+  It shows internal stats: free/used/total space, protection
+  status, data overhead, etc.
+
+  If unsure, say "y".
+
 config MEM_SOFT_DIRTY
bool "Track memory changes"
depends on CHECKPOINT_RESTORE && HAVE_ARCH_SOFT_DIRTY && PROC_FS
diff --git a/mm/pmalloc.c b/mm/pmalloc.c
index c73d60c..6dd6bbe 100644
--- a/mm/pmalloc.c
+++ b/mm/pmalloc.c
@@ -225,3 +225,116 @@ int __init pmalloc_init(void)
return 0;
 }
 EXPORT_SYMBOL(pmalloc_init);
+
+#ifdef CONFIG_PMALLOC_DEBUG
+#include 
+static struct dentry *pmalloc_root;
+
+static void *__pmalloc_seq_start(struct seq_file *s, loff_t *pos)
+{
+   if (*pos)
+   return NULL;
+   return pos;
+}
+
+static void *__pmalloc_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+   return NULL;
+}
+
+static void __pmalloc_seq_stop(struct seq_file *s, void *v)
+{
+}
+
+static __always_inline
+void __seq_printf_node(struct seq_file *s, struct pmalloc_node *node)
+{
+   unsigned long total_space, node_pages, end_of_node,
+ used_space, available_space;
+   int total_words, used_words, available_words;
+
+   used_words = atomic_read(>used_words);
+   total_words = node->total_words;
+   available_words = total_words - used_words;
+   used_space = used_words * WORD_SIZE;
+   total_space = total_words * WORD_SIZE;
+   available_space = total_space - used_space;
+   node_pages = (total_space + HEADER_SIZE) / PAGE_SIZE;
+   end_of_node = total_space + HEADER_SIZE + (unsigned long) node;
+   seq_printf(s, " - node:\t\t%p\n", node);
+   seq_printf(s, "   - start of data ptr:\t%p\n", node->data);
+   seq_printf(s, "   - end of node ptr:\t%p\n", (void *)end_of_node);
+   seq_printf(s, "   - total words:\t%d\n", total_words);
+   seq_printf(s, "   - used words:\t%d\n", used_words);
+   seq_printf(s, "   - available words:\t%d\n", available_words);
+   seq_printf(s, "   - pages:\t\t%lu\n", node_pages);
+   seq_printf(s, "   - total space:\t%lu\n", total_space);
+   seq_printf(s, "   - used space:\t%lu\n", used_space);
+   seq_printf(s, "   - available space:\t%lu\n", available_space);
+}
+
+static __always_inline
+void __seq_printf_pool(struct seq_file *s, struct pmalloc_pool *pool)
+{
+   struct pmalloc_node *node;
+
+   seq_printf(s, "pool:\t\t\t%p\n", pool);
+   seq_printf(s, " - name:\t\t%s\n", pool->name);
+   seq_printf(s, " - protected:\t\t%u\n", pool->protected);
+   seq_printf(s, " - nodes count:\t\t%u\n",
+  atomic_read(>nodes_count));
+   rcu_read_lock();
+   hlist_for_each_entry_rcu(node, >nodes_list_head, nodes_list)
+   __seq_printf_node(s, node);
+   rcu_read_unlock();
+}
+
+static int __pmalloc_seq_show(struct seq_file *s, void *v)
+{
+   struct pmalloc_pool *pool;
+
+   seq_printf(s, "pools count:\t\t%u\n",
+  atomic_read(_data->pools_count));
+   seq_printf(s, "page size:\t\t%lu\n", PAGE_SIZE);
+   seq_printf(s, "word size:\t\t%lu\n", WORD_SIZE);
+   seq_printf(s, "node header size:\t%lu\n", HEADER_SIZE);
+   rcu_read_lock();
+   hlist_for_each_entry_rcu(pool, _data->pools_list_head,
+pools_list)
+   __seq_printf_pool(s, pool);
+   rcu_read_unlock();
+   return 0;
+}
+
+static const struct seq_operations pmalloc_seq_ops = {
+   .start = __pmalloc_seq_start,
+   .next  = __pmalloc_seq_next,
+   .stop  = __pmalloc_seq_stop,
+   .show  = __pmalloc_seq_show,
+};
+
+static int __pmalloc_open(struct inode *inode, struct file *file)
+{
+   return seq_open(file, _seq_ops);
+}
+
+static const struct file_operations pmalloc_file_ops = {
+   .owner   = THIS_MODULE,
+   .open= __pmalloc_open,
+   .read= seq_read,
+   .llseek  = seq_lseek,
+   .release = seq_release
+};
+
+
+static int __init __pmalloc_init_track_pool(void)
+{
+   struct dentry *de = NULL;
+
+   pmalloc_root = debugfs_create_dir("pmalloc", NULL);
+   debugfs_create_file("pools", 0644, pmalloc_root, NULL,
+   _file_ops);
+   return 0;
+}
+late_initcall(__pmalloc_init_track_pool);
+#endif
-- 
2.9.3