proc: Make inline name size calculation automatic
authorDavid Howells <dhowells@redhat.com>
Wed, 13 Jun 2018 18:43:19 +0000 (19:43 +0100)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 15 Jun 2018 04:48:57 +0000 (00:48 -0400)
Make calculation of the size of the inline name in struct proc_dir_entry
automatic, rather than having to manually encode the numbers and failing to
allow for lockdep.

Require a minimum inline name size of 33+1 to allow for names that look
like two hex numbers with a dash between.

Reported-by: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/proc/generic.c
fs/proc/inode.c
fs/proc/internal.h
fs/proc/root.c

index d0e5a68ae14a1657a2a9d8db3ab23ef80cde8bb0..210bd4b169477d7464605755035bd7fd5cd44354 100644 (file)
@@ -410,7 +410,7 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
        if (!ent)
                goto out;
 
-       if (qstr.len + 1 <= sizeof(ent->inline_name)) {
+       if (qstr.len + 1 <= SIZEOF_PDE_INLINE_NAME) {
                ent->name = ent->inline_name;
        } else {
                ent->name = kmalloc(qstr.len + 1, GFP_KERNEL);
index 2cf3b74391ca5774a04cabe2b70e1e84ec7b3002..85ffbd27f2883a8e6fb3dfe8275c2e1a36ac3ffe 100644 (file)
@@ -105,9 +105,8 @@ void __init proc_init_kmemcache(void)
                kmem_cache_create("pde_opener", sizeof(struct pde_opener), 0,
                                  SLAB_ACCOUNT|SLAB_PANIC, NULL);
        proc_dir_entry_cache = kmem_cache_create_usercopy(
-               "proc_dir_entry", sizeof(struct proc_dir_entry), 0, SLAB_PANIC,
-               offsetof(struct proc_dir_entry, inline_name),
-               sizeof_field(struct proc_dir_entry, inline_name), NULL);
+               "proc_dir_entry", SIZEOF_PDE_SLOT, 0, SLAB_PANIC,
+               OFFSETOF_PDE_NAME, SIZEOF_PDE_INLINE_NAME, NULL);
 }
 
 static int proc_show_options(struct seq_file *seq, struct dentry *root)
index 916ccc39073d945b5f1790b20e64ebdf4e42ce4b..d8d11fd9fdb0111bd4c95cf0e1b29dad13239c7a 100644 (file)
@@ -62,14 +62,20 @@ struct proc_dir_entry {
        char *name;
        umode_t mode;
        u8 namelen;
-#ifdef CONFIG_64BIT
-#define SIZEOF_PDE_INLINE_NAME (192-155)
-#else
-#define SIZEOF_PDE_INLINE_NAME (128-95)
-#endif
-       char inline_name[SIZEOF_PDE_INLINE_NAME];
+       char inline_name[];
 } __randomize_layout;
 
+#define OFFSETOF_PDE_NAME offsetof(struct proc_dir_entry, inline_name)
+#define SIZEOF_PDE_SLOT                                        \
+       (OFFSETOF_PDE_NAME + 34 <= 64 ? 64 :            \
+        OFFSETOF_PDE_NAME + 34 <= 128 ? 128 :          \
+        OFFSETOF_PDE_NAME + 34 <= 192 ? 192 :          \
+        OFFSETOF_PDE_NAME + 34 <= 256 ? 256 :          \
+        OFFSETOF_PDE_NAME + 34 <= 512 ? 512 :          \
+        0)
+
+#define SIZEOF_PDE_INLINE_NAME (SIZEOF_PDE_SLOT - OFFSETOF_PDE_NAME)
+
 extern struct kmem_cache *proc_dir_entry_cache;
 void pde_free(struct proc_dir_entry *pde);
 
index 61b7340b357a2aad54e6c9b5eca97b8c9bd7a425..f4b1a9d2eca6010be2838197dc9741ec67a3857e 100644 (file)
@@ -204,8 +204,7 @@ struct proc_dir_entry proc_root = {
        .proc_fops      = &proc_root_operations,
        .parent         = &proc_root,
        .subdir         = RB_ROOT,
-       .name           = proc_root.inline_name,
-       .inline_name    = "/proc",
+       .name           = "/proc",
 };
 
 int pid_ns_prepare_proc(struct pid_namespace *ns)