aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/hypfs/inode.c12
-rw-r--r--drivers/firmware/efi/efi.c6
-rw-r--r--fs/configfs/mount.c10
-rw-r--r--fs/dcache.c11
-rw-r--r--fs/debugfs/inode.c11
-rw-r--r--fs/fuse/inode.c9
-rw-r--r--fs/kernfs/dir.c38
-rw-r--r--fs/kernfs/inode.c2
-rw-r--r--fs/libfs.c95
-rw-r--r--fs/namespace.c39
-rw-r--r--fs/proc/generic.c23
-rw-r--r--fs/proc/inode.c4
-rw-r--r--fs/proc/internal.h6
-rw-r--r--fs/proc/proc_sysctl.c37
-rw-r--r--fs/proc/root.c9
-rw-r--r--fs/pstore/inode.c12
-rw-r--r--fs/sysfs/dir.c34
-rw-r--r--fs/sysfs/mount.c5
-rw-r--r--fs/tracefs/inode.c6
-rw-r--r--include/linux/fs.h4
-rw-r--r--include/linux/kernfs.h3
-rw-r--r--include/linux/sysctl.h3
-rw-r--r--include/linux/sysfs.h15
-rw-r--r--kernel/cgroup.c10
-rw-r--r--kernel/sysctl.c8
-rw-r--r--security/inode.c10
-rw-r--r--security/selinux/selinuxfs.c11
-rw-r--r--security/smack/smackfs.c8
28 files changed, 340 insertions, 101 deletions
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index d3f896a35b98..2eeb0a0f506d 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -456,8 +456,6 @@ static const struct super_operations hypfs_s_ops = {
456 .show_options = hypfs_show_options, 456 .show_options = hypfs_show_options,
457}; 457};
458 458
459static struct kobject *s390_kobj;
460
461static int __init hypfs_init(void) 459static int __init hypfs_init(void)
462{ 460{
463 int rc; 461 int rc;
@@ -481,18 +479,16 @@ static int __init hypfs_init(void)
481 rc = -ENODATA; 479 rc = -ENODATA;
482 goto fail_hypfs_sprp_exit; 480 goto fail_hypfs_sprp_exit;
483 } 481 }
484 s390_kobj = kobject_create_and_add("s390", hypervisor_kobj); 482 rc = sysfs_create_mount_point(hypervisor_kobj, "s390");
485 if (!s390_kobj) { 483 if (rc)
486 rc = -ENOMEM;
487 goto fail_hypfs_diag0c_exit; 484 goto fail_hypfs_diag0c_exit;
488 }
489 rc = register_filesystem(&hypfs_type); 485 rc = register_filesystem(&hypfs_type);
490 if (rc) 486 if (rc)
491 goto fail_filesystem; 487 goto fail_filesystem;
492 return 0; 488 return 0;
493 489
494fail_filesystem: 490fail_filesystem:
495 kobject_put(s390_kobj); 491 sysfs_remove_mount_point(hypervisor_kobj, "s390");
496fail_hypfs_diag0c_exit: 492fail_hypfs_diag0c_exit:
497 hypfs_diag0c_exit(); 493 hypfs_diag0c_exit();
498fail_hypfs_sprp_exit: 494fail_hypfs_sprp_exit:
@@ -510,7 +506,7 @@ fail_dbfs_exit:
510static void __exit hypfs_exit(void) 506static void __exit hypfs_exit(void)
511{ 507{
512 unregister_filesystem(&hypfs_type); 508 unregister_filesystem(&hypfs_type);
513 kobject_put(s390_kobj); 509 sysfs_remove_mount_point(hypervisor_kobj, "s390");
514 hypfs_diag0c_exit(); 510 hypfs_diag0c_exit();
515 hypfs_sprp_exit(); 511 hypfs_sprp_exit();
516 hypfs_vm_exit(); 512 hypfs_vm_exit();
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index ca617f40574a..9fa8084a7c8d 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -66,7 +66,6 @@ static int __init parse_efi_cmdline(char *str)
66early_param("efi", parse_efi_cmdline); 66early_param("efi", parse_efi_cmdline);
67 67
68struct kobject *efi_kobj; 68struct kobject *efi_kobj;
69static struct kobject *efivars_kobj;
70 69
71/* 70/*
72 * Let's not leave out systab information that snuck into 71 * Let's not leave out systab information that snuck into
@@ -218,10 +217,9 @@ static int __init efisubsys_init(void)
218 goto err_remove_group; 217 goto err_remove_group;
219 218
220 /* and the standard mountpoint for efivarfs */ 219 /* and the standard mountpoint for efivarfs */
221 efivars_kobj = kobject_create_and_add("efivars", efi_kobj); 220 error = sysfs_create_mount_point(efi_kobj, "efivars");
222 if (!efivars_kobj) { 221 if (error) {
223 pr_err("efivars: Subsystem registration failed.\n"); 222 pr_err("efivars: Subsystem registration failed.\n");
224 error = -ENOMEM;
225 goto err_remove_group; 223 goto err_remove_group;
226 } 224 }
227 225
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c
index 537356742091..a8f3b589a2df 100644
--- a/fs/configfs/mount.c
+++ b/fs/configfs/mount.c
@@ -129,8 +129,6 @@ void configfs_release_fs(void)
129} 129}
130 130
131 131
132static struct kobject *config_kobj;
133
134static int __init configfs_init(void) 132static int __init configfs_init(void)
135{ 133{
136 int err = -ENOMEM; 134 int err = -ENOMEM;
@@ -141,8 +139,8 @@ static int __init configfs_init(void)
141 if (!configfs_dir_cachep) 139 if (!configfs_dir_cachep)
142 goto out; 140 goto out;
143 141
144 config_kobj = kobject_create_and_add("config", kernel_kobj); 142 err = sysfs_create_mount_point(kernel_kobj, "config");
145 if (!config_kobj) 143 if (err)
146 goto out2; 144 goto out2;
147 145
148 err = register_filesystem(&configfs_fs_type); 146 err = register_filesystem(&configfs_fs_type);
@@ -152,7 +150,7 @@ static int __init configfs_init(void)
152 return 0; 150 return 0;
153out3: 151out3:
154 pr_err("Unable to register filesystem!\n"); 152 pr_err("Unable to register filesystem!\n");
155 kobject_put(config_kobj); 153 sysfs_remove_mount_point(kernel_kobj, "config");
156out2: 154out2:
157 kmem_cache_destroy(configfs_dir_cachep); 155 kmem_cache_destroy(configfs_dir_cachep);
158 configfs_dir_cachep = NULL; 156 configfs_dir_cachep = NULL;
@@ -163,7 +161,7 @@ out:
163static void __exit configfs_exit(void) 161static void __exit configfs_exit(void)
164{ 162{
165 unregister_filesystem(&configfs_fs_type); 163 unregister_filesystem(&configfs_fs_type);
166 kobject_put(config_kobj); 164 sysfs_remove_mount_point(kernel_kobj, "config");
167 kmem_cache_destroy(configfs_dir_cachep); 165 kmem_cache_destroy(configfs_dir_cachep);
168 configfs_dir_cachep = NULL; 166 configfs_dir_cachep = NULL;
169} 167}
diff --git a/fs/dcache.c b/fs/dcache.c
index 592c4b582495..910968b4b6bf 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2927,17 +2927,6 @@ restart:
2927 vfsmnt = &mnt->mnt; 2927 vfsmnt = &mnt->mnt;
2928 continue; 2928 continue;
2929 } 2929 }
2930 /*
2931 * Filesystems needing to implement special "root names"
2932 * should do so with ->d_dname()
2933 */
2934 if (IS_ROOT(dentry) &&
2935 (dentry->d_name.len != 1 ||
2936 dentry->d_name.name[0] != '/')) {
2937 WARN(1, "Root dentry has weird name <%.*s>\n",
2938 (int) dentry->d_name.len,
2939 dentry->d_name.name);
2940 }
2941 if (!error) 2930 if (!error)
2942 error = is_mounted(vfsmnt) ? 1 : 2; 2931 error = is_mounted(vfsmnt) ? 1 : 2;
2943 break; 2932 break;
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 7eaec88ea970..d6d1cf004123 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -716,20 +716,17 @@ bool debugfs_initialized(void)
716} 716}
717EXPORT_SYMBOL_GPL(debugfs_initialized); 717EXPORT_SYMBOL_GPL(debugfs_initialized);
718 718
719
720static struct kobject *debug_kobj;
721
722static int __init debugfs_init(void) 719static int __init debugfs_init(void)
723{ 720{
724 int retval; 721 int retval;
725 722
726 debug_kobj = kobject_create_and_add("debug", kernel_kobj); 723 retval = sysfs_create_mount_point(kernel_kobj, "debug");
727 if (!debug_kobj) 724 if (retval)
728 return -EINVAL; 725 return retval;
729 726
730 retval = register_filesystem(&debug_fs_type); 727 retval = register_filesystem(&debug_fs_type);
731 if (retval) 728 if (retval)
732 kobject_put(debug_kobj); 729 sysfs_remove_mount_point(kernel_kobj, "debug");
733 else 730 else
734 debugfs_registered = true; 731 debugfs_registered = true;
735 732
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index ac81f48ab2f4..2913db2a5b99 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1294,7 +1294,6 @@ static void fuse_fs_cleanup(void)
1294} 1294}
1295 1295
1296static struct kobject *fuse_kobj; 1296static struct kobject *fuse_kobj;
1297static struct kobject *connections_kobj;
1298 1297
1299static int fuse_sysfs_init(void) 1298static int fuse_sysfs_init(void)
1300{ 1299{
@@ -1306,11 +1305,9 @@ static int fuse_sysfs_init(void)
1306 goto out_err; 1305 goto out_err;
1307 } 1306 }
1308 1307
1309 connections_kobj = kobject_create_and_add("connections", fuse_kobj); 1308 err = sysfs_create_mount_point(fuse_kobj, "connections");
1310 if (!connections_kobj) { 1309 if (err)
1311 err = -ENOMEM;
1312 goto out_fuse_unregister; 1310 goto out_fuse_unregister;
1313 }
1314 1311
1315 return 0; 1312 return 0;
1316 1313
@@ -1322,7 +1319,7 @@ static int fuse_sysfs_init(void)
1322 1319
1323static void fuse_sysfs_cleanup(void) 1320static void fuse_sysfs_cleanup(void)
1324{ 1321{
1325 kobject_put(connections_kobj); 1322 sysfs_remove_mount_point(fuse_kobj, "connections");
1326 kobject_put(fuse_kobj); 1323 kobject_put(fuse_kobj);
1327} 1324}
1328 1325
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index fffca9517321..2d48d28e1640 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -592,6 +592,9 @@ int kernfs_add_one(struct kernfs_node *kn)
592 goto out_unlock; 592 goto out_unlock;
593 593
594 ret = -ENOENT; 594 ret = -ENOENT;
595 if (parent->flags & KERNFS_EMPTY_DIR)
596 goto out_unlock;
597
595 if ((parent->flags & KERNFS_ACTIVATED) && !kernfs_active(parent)) 598 if ((parent->flags & KERNFS_ACTIVATED) && !kernfs_active(parent))
596 goto out_unlock; 599 goto out_unlock;
597 600
@@ -783,6 +786,38 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
783 return ERR_PTR(rc); 786 return ERR_PTR(rc);
784} 787}
785 788
789/**
790 * kernfs_create_empty_dir - create an always empty directory
791 * @parent: parent in which to create a new directory
792 * @name: name of the new directory
793 *
794 * Returns the created node on success, ERR_PTR() value on failure.
795 */
796struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent,
797 const char *name)
798{
799 struct kernfs_node *kn;
800 int rc;
801
802 /* allocate */
803 kn = kernfs_new_node(parent, name, S_IRUGO|S_IXUGO|S_IFDIR, KERNFS_DIR);
804 if (!kn)
805 return ERR_PTR(-ENOMEM);
806
807 kn->flags |= KERNFS_EMPTY_DIR;
808 kn->dir.root = parent->dir.root;
809 kn->ns = NULL;
810 kn->priv = NULL;
811
812 /* link in */
813 rc = kernfs_add_one(kn);
814 if (!rc)
815 return kn;
816
817 kernfs_put(kn);
818 return ERR_PTR(rc);
819}
820
786static struct dentry *kernfs_iop_lookup(struct inode *dir, 821static struct dentry *kernfs_iop_lookup(struct inode *dir,
787 struct dentry *dentry, 822 struct dentry *dentry,
788 unsigned int flags) 823 unsigned int flags)
@@ -1254,7 +1289,8 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
1254 mutex_lock(&kernfs_mutex); 1289 mutex_lock(&kernfs_mutex);
1255 1290
1256 error = -ENOENT; 1291 error = -ENOENT;
1257 if (!kernfs_active(kn) || !kernfs_active(new_parent)) 1292 if (!kernfs_active(kn) || !kernfs_active(new_parent) ||
1293 (new_parent->flags & KERNFS_EMPTY_DIR))
1258 goto out; 1294 goto out;
1259 1295
1260 error = 0; 1296 error = 0;
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index 2da8493a380b..756dd56aaf60 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -296,6 +296,8 @@ static void kernfs_init_inode(struct kernfs_node *kn, struct inode *inode)
296 case KERNFS_DIR: 296 case KERNFS_DIR:
297 inode->i_op = &kernfs_dir_iops; 297 inode->i_op = &kernfs_dir_iops;
298 inode->i_fop = &kernfs_dir_fops; 298 inode->i_fop = &kernfs_dir_fops;
299 if (kn->flags & KERNFS_EMPTY_DIR)
300 make_empty_dir_inode(inode);
299 break; 301 break;
300 case KERNFS_FILE: 302 case KERNFS_FILE:
301 inode->i_size = kn->attr.size; 303 inode->i_size = kn->attr.size;
diff --git a/fs/libfs.c b/fs/libfs.c
index 65e1feca8b98..88a4cb418756 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1108,3 +1108,98 @@ const struct inode_operations simple_symlink_inode_operations = {
1108 .readlink = generic_readlink 1108 .readlink = generic_readlink
1109}; 1109};
1110EXPORT_SYMBOL(simple_symlink_inode_operations); 1110EXPORT_SYMBOL(simple_symlink_inode_operations);
1111
1112/*
1113 * Operations for a permanently empty directory.
1114 */
1115static struct dentry *empty_dir_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
1116{
1117 return ERR_PTR(-ENOENT);
1118}
1119
1120static int empty_dir_getattr(struct vfsmount *mnt, struct dentry *dentry,
1121 struct kstat *stat)
1122{
1123 struct inode *inode = d_inode(dentry);
1124 generic_fillattr(inode, stat);
1125 return 0;
1126}
1127
1128static int empty_dir_setattr(struct dentry *dentry, struct iattr *attr)
1129{
1130 return -EPERM;
1131}
1132
1133static int empty_dir_setxattr(struct dentry *dentry, const char *name,
1134 const void *value, size_t size, int flags)
1135{
1136 return -EOPNOTSUPP;
1137}
1138
1139static ssize_t empty_dir_getxattr(struct dentry *dentry, const char *name,
1140 void *value, size_t size)
1141{
1142 return -EOPNOTSUPP;
1143}
1144
1145static int empty_dir_removexattr(struct dentry *dentry, const char *name)
1146{
1147 return -EOPNOTSUPP;
1148}
1149
1150static ssize_t empty_dir_listxattr(struct dentry *dentry, char *list, size_t size)
1151{
1152 return -EOPNOTSUPP;
1153}
1154
1155static const struct inode_operations empty_dir_inode_operations = {
1156 .lookup = empty_dir_lookup,
1157 .permission = generic_permission,
1158 .setattr = empty_dir_setattr,
1159 .getattr = empty_dir_getattr,
1160 .setxattr = empty_dir_setxattr,
1161 .getxattr = empty_dir_getxattr,
1162 .removexattr = empty_dir_removexattr,
1163 .listxattr = empty_dir_listxattr,
1164};
1165
1166static loff_t empty_dir_llseek(struct file *file, loff_t offset, int whence)
1167{
1168 /* An empty directory has two entries . and .. at offsets 0 and 1 */
1169 return generic_file_llseek_size(file, offset, whence, 2, 2);
1170}
1171
1172static int empty_dir_readdir(struct file *file, struct dir_context *ctx)
1173{
1174 dir_emit_dots(file, ctx);
1175 return 0;
1176}
1177
1178static const struct file_operations empty_dir_operations = {
1179 .llseek = empty_dir_llseek,
1180 .read = generic_read_dir,
1181 .iterate = empty_dir_readdir,
1182 .fsync = noop_fsync,
1183};
1184
1185
1186void make_empty_dir_inode(struct inode *inode)
1187{
1188 set_nlink(inode, 2);
1189 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
1190 inode->i_uid = GLOBAL_ROOT_UID;
1191 inode->i_gid = GLOBAL_ROOT_GID;
1192 inode->i_rdev = 0;
1193 inode->i_size = 2;
1194 inode->i_blkbits = PAGE_SHIFT;
1195 inode->i_blocks = 0;
1196
1197 inode->i_op = &empty_dir_inode_operations;
1198 inode->i_fop = &empty_dir_operations;
1199}
1200
1201bool is_empty_dir_inode(struct inode *inode)
1202{
1203 return (inode->i_fop == &empty_dir_operations) &&
1204 (inode->i_op == &empty_dir_inode_operations);
1205}
diff --git a/fs/namespace.c b/fs/namespace.c
index e99f1f4e00cd..c7cb8a526c05 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2343,6 +2343,8 @@ unlock:
2343 return err; 2343 return err;
2344} 2344}
2345 2345
2346static bool fs_fully_visible(struct file_system_type *fs_type, int *new_mnt_flags);
2347
2346/* 2348/*
2347 * create a new mount for userspace and request it to be added into the 2349 * create a new mount for userspace and request it to be added into the
2348 * namespace's tree 2350 * namespace's tree
@@ -2374,6 +2376,10 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,
2374 flags |= MS_NODEV; 2376 flags |= MS_NODEV;
2375 mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV; 2377 mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV;
2376 } 2378 }
2379 if (type->fs_flags & FS_USERNS_VISIBLE) {
2380 if (!fs_fully_visible(type, &mnt_flags))
2381 return -EPERM;
2382 }
2377 } 2383 }
2378 2384
2379 mnt = vfs_kern_mount(type, flags, name, data); 2385 mnt = vfs_kern_mount(type, flags, name, data);
@@ -3175,9 +3181,10 @@ bool current_chrooted(void)
3175 return chrooted; 3181 return chrooted;
3176} 3182}
3177 3183
3178bool fs_fully_visible(struct file_system_type *type) 3184static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
3179{ 3185{
3180 struct mnt_namespace *ns = current->nsproxy->mnt_ns; 3186 struct mnt_namespace *ns = current->nsproxy->mnt_ns;
3187 int new_flags = *new_mnt_flags;
3181 struct mount *mnt; 3188 struct mount *mnt;
3182 bool visible = false; 3189 bool visible = false;
3183 3190
@@ -3196,16 +3203,36 @@ bool fs_fully_visible(struct file_system_type *type)
3196 if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root) 3203 if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root)
3197 continue; 3204 continue;
3198 3205
3199 /* This mount is not fully visible if there are any child mounts 3206 /* Verify the mount flags are equal to or more permissive
3200 * that cover anything except for empty directories. 3207 * than the proposed new mount.
3208 */
3209 if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) &&
3210 !(new_flags & MNT_READONLY))
3211 continue;
3212 if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) &&
3213 !(new_flags & MNT_NODEV))
3214 continue;
3215 if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) &&
3216 ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK)))
3217 continue;
3218
3219 /* This mount is not fully visible if there are any
3220 * locked child mounts that cover anything except for
3221 * empty directories.
3201 */ 3222 */
3202 list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) { 3223 list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
3203 struct inode *inode = child->mnt_mountpoint->d_inode; 3224 struct inode *inode = child->mnt_mountpoint->d_inode;
3204 if (!S_ISDIR(inode->i_mode)) 3225 /* Only worry about locked mounts */
3205 goto next; 3226 if (!(mnt->mnt.mnt_flags & MNT_LOCKED))
3206 if (inode->i_nlink > 2) 3227 continue;
3228 /* Is the directory permanetly empty? */
3229 if (!is_empty_dir_inode(inode))
3207 goto next; 3230 goto next;
3208 } 3231 }
3232 /* Preserve the locked attributes */
3233 *new_mnt_flags |= mnt->mnt.mnt_flags & (MNT_LOCK_READONLY | \
3234 MNT_LOCK_NODEV | \
3235 MNT_LOCK_ATIME);
3209 visible = true; 3236 visible = true;
3210 goto found; 3237 goto found;
3211 next: ; 3238 next: ;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index df6327a2b865..e5dee5c3188e 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -373,6 +373,10 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
373 WARN(1, "create '/proc/%s' by hand\n", qstr.name); 373 WARN(1, "create '/proc/%s' by hand\n", qstr.name);
374 return NULL; 374 return NULL;
375 } 375 }
376 if (is_empty_pde(*parent)) {
377 WARN(1, "attempt to add to permanently empty directory");
378 return NULL;
379 }
376 380
377 ent = kzalloc(sizeof(struct proc_dir_entry) + qstr.len + 1, GFP_KERNEL); 381 ent = kzalloc(sizeof(struct proc_dir_entry) + qstr.len + 1, GFP_KERNEL);
378 if (!ent) 382 if (!ent)
@@ -455,6 +459,25 @@ struct proc_dir_entry *proc_mkdir(const char *name,
455} 459}
456EXPORT_SYMBOL(proc_mkdir); 460EXPORT_SYMBOL(proc_mkdir);
457 461
462struct proc_dir_entry *proc_create_mount_point(const char *name)
463{
464 umode_t mode = S_IFDIR | S_IRUGO | S_IXUGO;
465 struct proc_dir_entry *ent, *parent = NULL;
466
467 ent = __proc_create(&parent, name, mode, 2);
468 if (ent) {
469 ent->data = NULL;
470 ent->proc_fops = NULL;
471 ent->proc_iops = NULL;
472 if (proc_register(parent, ent) < 0) {
473 kfree(ent);
474 parent->nlink--;
475 ent = NULL;
476 }
477 }
478 return ent;
479}
480
458struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, 481struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
459 struct proc_dir_entry *parent, 482 struct proc_dir_entry *parent,
460 const struct file_operations *proc_fops, 483 const struct file_operations *proc_fops,
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index afe232b9df6e..bd95b9fdebb0 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -422,6 +422,10 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
422 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 422 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
423 PROC_I(inode)->pde = de; 423 PROC_I(inode)->pde = de;
424 424
425 if (is_empty_pde(de)) {
426 make_empty_dir_inode(inode);
427 return inode;
428 }
425 if (de->mode) { 429 if (de->mode) {
426 inode->i_mode = de->mode; 430 inode->i_mode = de->mode;
427 inode->i_uid = de->uid; 431 inode->i_uid = de->uid;
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index c835b94c0cd3..aa2781095bd1 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -191,6 +191,12 @@ static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde)
191} 191}
192extern void pde_put(struct proc_dir_entry *); 192extern void pde_put(struct proc_dir_entry *);
193 193
194static inline bool is_empty_pde(const struct proc_dir_entry *pde)
195{
196 return S_ISDIR(pde->mode) && !pde->proc_iops;
197}
198struct proc_dir_entry *proc_create_mount_point(const char *name);
199
194/* 200/*
195 * inode.c 201 * inode.c
196 */ 202 */
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index fea2561d773b..fdda62e6115e 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -19,6 +19,28 @@ static const struct inode_operations proc_sys_inode_operations;
19static const struct file_operations proc_sys_dir_file_operations; 19static const struct file_operations proc_sys_dir_file_operations;
20static const struct inode_operations proc_sys_dir_operations; 20static const struct inode_operations proc_sys_dir_operations;
21 21
22/* Support for permanently empty directories */
23
24struct ctl_table sysctl_mount_point[] = {
25 { }
26};
27
28static bool is_empty_dir(struct ctl_table_header *head)
29{
30 return head->ctl_table[0].child == sysctl_mount_point;
31}
32
33static void set_empty_dir(struct ctl_dir *dir)
34{
35 dir->header.ctl_table[0].child = sysctl_mount_point;
36}
37
38static void clear_empty_dir(struct ctl_dir *dir)
39
40{
41 dir->header.ctl_table[0].child = NULL;
42}
43
22void proc_sys_poll_notify(struct ctl_table_poll *poll) 44void proc_sys_poll_notify(struct ctl_table_poll *poll)
23{ 45{
24 if (!poll) 46 if (!poll)
@@ -187,6 +209,17 @@ static int insert_header(struct ctl_dir *dir, struct ctl_table_header *header)
187 struct ctl_table *entry; 209 struct ctl_table *entry;
188 int err; 210 int err;
189 211
212 /* Is this a permanently empty directory? */
213 if (is_empty_dir(&dir->header))
214 return -EROFS;
215
216 /* Am I creating a permanently empty directory? */
217 if (header->ctl_table == sysctl_mount_point) {
218 if (!RB_EMPTY_ROOT(&dir->root))
219 return -EINVAL;
220 set_empty_dir(dir);
221 }
222
190 dir->header.nreg++; 223 dir->header.nreg++;
191 header->parent = dir; 224 header->parent = dir;
192 err = insert_links(header); 225 err = insert_links(header);
@@ -202,6 +235,8 @@ fail:
202 erase_header(header); 235 erase_header(header);
203 put_links(header); 236 put_links(header);
204fail_links: 237fail_links:
238 if (header->ctl_table == sysctl_mount_point)
239 clear_empty_dir(dir);
205 header->parent = NULL; 240 header->parent = NULL;
206 drop_sysctl_table(&dir->header); 241 drop_sysctl_table(&dir->header);
207 return err; 242 return err;
@@ -419,6 +454,8 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
419 inode->i_mode |= S_IFDIR; 454 inode->i_mode |= S_IFDIR;
420 inode->i_op = &proc_sys_dir_operations; 455 inode->i_op = &proc_sys_dir_operations;
421 inode->i_fop = &proc_sys_dir_file_operations; 456 inode->i_fop = &proc_sys_dir_file_operations;
457 if (is_empty_dir(head))
458 make_empty_dir_inode(inode);
422 } 459 }
423out: 460out:
424 return inode; 461 return inode;
diff --git a/fs/proc/root.c b/fs/proc/root.c
index b7fa4bfe896a..68feb0f70e63 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -112,9 +112,6 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
112 ns = task_active_pid_ns(current); 112 ns = task_active_pid_ns(current);
113 options = data; 113 options = data;
114 114
115 if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
116 return ERR_PTR(-EPERM);
117
118 /* Does the mounter have privilege over the pid namespace? */ 115 /* Does the mounter have privilege over the pid namespace? */
119 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN)) 116 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
120 return ERR_PTR(-EPERM); 117 return ERR_PTR(-EPERM);
@@ -159,7 +156,7 @@ static struct file_system_type proc_fs_type = {
159 .name = "proc", 156 .name = "proc",
160 .mount = proc_mount, 157 .mount = proc_mount,
161 .kill_sb = proc_kill_sb, 158 .kill_sb = proc_kill_sb,
162 .fs_flags = FS_USERNS_MOUNT, 159 .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
163}; 160};
164 161
165void __init proc_root_init(void) 162void __init proc_root_init(void)
@@ -182,10 +179,10 @@ void __init proc_root_init(void)
182#endif 179#endif
183 proc_mkdir("fs", NULL); 180 proc_mkdir("fs", NULL);
184 proc_mkdir("driver", NULL); 181 proc_mkdir("driver", NULL);
185 proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */ 182 proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */
186#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) 183#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
187 /* just give it a mountpoint */ 184 /* just give it a mountpoint */
188 proc_mkdir("openprom", NULL); 185 proc_create_mount_point("openprom");
189#endif 186#endif
190 proc_tty_init(); 187 proc_tty_init();
191 proc_mkdir("bus", NULL); 188 proc_mkdir("bus", NULL);
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index dc43b5f29305..3adcc4669fac 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -461,22 +461,18 @@ static struct file_system_type pstore_fs_type = {
461 .kill_sb = pstore_kill_sb, 461 .kill_sb = pstore_kill_sb,
462}; 462};
463 463
464static struct kobject *pstore_kobj;
465
466static int __init init_pstore_fs(void) 464static int __init init_pstore_fs(void)
467{ 465{
468 int err = 0; 466 int err;
469 467
470 /* Create a convenient mount point for people to access pstore */ 468 /* Create a convenient mount point for people to access pstore */
471 pstore_kobj = kobject_create_and_add("pstore", fs_kobj); 469 err = sysfs_create_mount_point(fs_kobj, "pstore");
472 if (!pstore_kobj) { 470 if (err)
473 err = -ENOMEM;
474 goto out; 471 goto out;
475 }
476 472
477 err = register_filesystem(&pstore_fs_type); 473 err = register_filesystem(&pstore_fs_type);
478 if (err < 0) 474 if (err < 0)
479 kobject_put(pstore_kobj); 475 sysfs_remove_mount_point(fs_kobj, "pstore");
480 476
481out: 477out:
482 return err; 478 return err;
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 0b45ff42f374..94374e435025 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -121,3 +121,37 @@ int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
121 121
122 return kernfs_rename_ns(kn, new_parent, kn->name, new_ns); 122 return kernfs_rename_ns(kn, new_parent, kn->name, new_ns);
123} 123}
124
125/**
126 * sysfs_create_mount_point - create an always empty directory
127 * @parent_kobj: kobject that will contain this always empty directory
128 * @name: The name of the always empty directory to add
129 */
130int sysfs_create_mount_point(struct kobject *parent_kobj, const char *name)
131{
132 struct kernfs_node *kn, *parent = parent_kobj->sd;
133
134 kn = kernfs_create_empty_dir(parent, name);
135 if (IS_ERR(kn)) {
136 if (PTR_ERR(kn) == -EEXIST)
137 sysfs_warn_dup(parent, name);
138 return PTR_ERR(kn);
139 }
140
141 return 0;
142}
143EXPORT_SYMBOL_GPL(sysfs_create_mount_point);
144
145/**
146 * sysfs_remove_mount_point - remove an always empty directory.
147 * @parent_kobj: kobject that will contain this always empty directory
148 * @name: The name of the always empty directory to remove
149 *
150 */
151void sysfs_remove_mount_point(struct kobject *parent_kobj, const char *name)
152{
153 struct kernfs_node *parent = parent_kobj->sd;
154
155 kernfs_remove_by_name_ns(parent, name, NULL);
156}
157EXPORT_SYMBOL_GPL(sysfs_remove_mount_point);
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 8a49486bf30c..1c6ac6fcee9f 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -31,9 +31,6 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type,
31 bool new_sb; 31 bool new_sb;
32 32
33 if (!(flags & MS_KERNMOUNT)) { 33 if (!(flags & MS_KERNMOUNT)) {
34 if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
35 return ERR_PTR(-EPERM);
36
37 if (!kobj_ns_current_may_mount(KOBJ_NS_TYPE_NET)) 34 if (!kobj_ns_current_may_mount(KOBJ_NS_TYPE_NET))
38 return ERR_PTR(-EPERM); 35 return ERR_PTR(-EPERM);
39 } 36 }
@@ -58,7 +55,7 @@ static struct file_system_type sysfs_fs_type = {
58 .name = "sysfs", 55 .name = "sysfs",
59 .mount = sysfs_mount, 56 .mount = sysfs_mount,
60 .kill_sb = sysfs_kill_sb, 57 .kill_sb = sysfs_kill_sb,
61 .fs_flags = FS_USERNS_MOUNT, 58 .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
62}; 59};
63 60
64int __init sysfs_init(void) 61int __init sysfs_init(void)
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index d92bdf3b079a..a43df11a163f 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -631,14 +631,12 @@ bool tracefs_initialized(void)
631 return tracefs_registered; 631 return tracefs_registered;
632} 632}
633 633
634static struct kobject *trace_kobj;
635
636static int __init tracefs_init(void) 634static int __init tracefs_init(void)
637{ 635{
638 int retval; 636 int retval;
639 637
640 trace_kobj = kobject_create_and_add("tracing", kernel_kobj); 638 retval = sysfs_create_mount_point(kernel_kobj, "tracing");
641 if (!trace_kobj) 639 if (retval)
642 return -EINVAL; 640 return -EINVAL;
643 641
644 retval = register_filesystem(&trace_fs_type); 642 retval = register_filesystem(&trace_fs_type);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3f1a84635da8..8a81fcbb0074 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1917,6 +1917,7 @@ struct file_system_type {
1917#define FS_HAS_SUBTYPE 4 1917#define FS_HAS_SUBTYPE 4
1918#define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */ 1918#define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */
1919#define FS_USERNS_DEV_MOUNT 16 /* A userns mount does not imply MNT_NODEV */ 1919#define FS_USERNS_DEV_MOUNT 16 /* A userns mount does not imply MNT_NODEV */
1920#define FS_USERNS_VISIBLE 32 /* FS must already be visible */
1920#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ 1921#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
1921 struct dentry *(*mount) (struct file_system_type *, int, 1922 struct dentry *(*mount) (struct file_system_type *, int,
1922 const char *, void *); 1923 const char *, void *);
@@ -2004,7 +2005,6 @@ extern int vfs_ustat(dev_t, struct kstatfs *);
2004extern int freeze_super(struct super_block *super); 2005extern int freeze_super(struct super_block *super);
2005extern int thaw_super(struct super_block *super); 2006extern int thaw_super(struct super_block *super);
2006extern bool our_mnt(struct vfsmount *mnt); 2007extern bool our_mnt(struct vfsmount *mnt);
2007extern bool fs_fully_visible(struct file_system_type *);
2008 2008
2009extern int current_umask(void); 2009extern int current_umask(void);
2010 2010
@@ -2816,6 +2816,8 @@ extern struct dentry *simple_lookup(struct inode *, struct dentry *, unsigned in
2816extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *); 2816extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *);
2817extern const struct file_operations simple_dir_operations; 2817extern const struct file_operations simple_dir_operations;
2818extern const struct inode_operations simple_dir_inode_operations; 2818extern const struct inode_operations simple_dir_inode_operations;
2819extern void make_empty_dir_inode(struct inode *inode);
2820extern bool is_empty_dir_inode(struct inode *inode);
2819struct tree_descr { char *name; const struct file_operations *ops; int mode; }; 2821struct tree_descr { char *name; const struct file_operations *ops; int mode; };
2820struct dentry *d_alloc_name(struct dentry *, const char *); 2822struct dentry *d_alloc_name(struct dentry *, const char *);
2821extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *); 2823extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *);
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index e6b2f7db9c0c..123be25ea15a 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -45,6 +45,7 @@ enum kernfs_node_flag {
45 KERNFS_LOCKDEP = 0x0100, 45 KERNFS_LOCKDEP = 0x0100,
46 KERNFS_SUICIDAL = 0x0400, 46 KERNFS_SUICIDAL = 0x0400,
47 KERNFS_SUICIDED = 0x0800, 47 KERNFS_SUICIDED = 0x0800,
48 KERNFS_EMPTY_DIR = 0x1000,
48}; 49};
49 50
50/* @flags for kernfs_create_root() */ 51/* @flags for kernfs_create_root() */
@@ -286,6 +287,8 @@ void kernfs_destroy_root(struct kernfs_root *root);
286struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, 287struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
287 const char *name, umode_t mode, 288 const char *name, umode_t mode,
288 void *priv, const void *ns); 289 void *priv, const void *ns);
290struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent,
291 const char *name);
289struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, 292struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
290 const char *name, 293 const char *name,
291 umode_t mode, loff_t size, 294 umode_t mode, loff_t size,
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 795d5fea5697..fa7bc29925c9 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -188,6 +188,9 @@ struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
188void unregister_sysctl_table(struct ctl_table_header * table); 188void unregister_sysctl_table(struct ctl_table_header * table);
189 189
190extern int sysctl_init(void); 190extern int sysctl_init(void);
191
192extern struct ctl_table sysctl_mount_point[];
193
191#else /* CONFIG_SYSCTL */ 194#else /* CONFIG_SYSCTL */
192static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table) 195static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
193{ 196{
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 99382c0df17e..9f65758311a4 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -210,6 +210,10 @@ int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
210int __must_check sysfs_move_dir_ns(struct kobject *kobj, 210int __must_check sysfs_move_dir_ns(struct kobject *kobj,
211 struct kobject *new_parent_kobj, 211 struct kobject *new_parent_kobj,
212 const void *new_ns); 212 const void *new_ns);
213int __must_check sysfs_create_mount_point(struct kobject *parent_kobj,
214 const char *name);
215void sysfs_remove_mount_point(struct kobject *parent_kobj,
216 const char *name);
213 217
214int __must_check sysfs_create_file_ns(struct kobject *kobj, 218int __must_check sysfs_create_file_ns(struct kobject *kobj,
215 const struct attribute *attr, 219 const struct attribute *attr,
@@ -298,6 +302,17 @@ static inline int sysfs_move_dir_ns(struct kobject *kobj,
298 return 0; 302 return 0;
299} 303}
300 304
305static inline int sysfs_create_mount_point(struct kobject *parent_kobj,
306 const char *name)
307{
308 return 0;
309}
310
311static inline void sysfs_remove_mount_point(struct kobject *parent_kobj,
312 const char *name)
313{
314}
315
301static inline int sysfs_create_file_ns(struct kobject *kobj, 316static inline int sysfs_create_file_ns(struct kobject *kobj,
302 const struct attribute *attr, 317 const struct attribute *attr,
303 const void *ns) 318 const void *ns)
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 9ef9fc8a774b..f89d9292eee6 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1939,8 +1939,6 @@ static struct file_system_type cgroup_fs_type = {
1939 .kill_sb = cgroup_kill_sb, 1939 .kill_sb = cgroup_kill_sb,
1940}; 1940};
1941 1941
1942static struct kobject *cgroup_kobj;
1943
1944/** 1942/**
1945 * task_cgroup_path - cgroup path of a task in the first cgroup hierarchy 1943 * task_cgroup_path - cgroup path of a task in the first cgroup hierarchy
1946 * @task: target task 1944 * @task: target task
@@ -5070,13 +5068,13 @@ int __init cgroup_init(void)
5070 ss->bind(init_css_set.subsys[ssid]); 5068 ss->bind(init_css_set.subsys[ssid]);
5071 } 5069 }
5072 5070
5073 cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj); 5071 err = sysfs_create_mount_point(fs_kobj, "cgroup");
5074 if (!cgroup_kobj) 5072 if (err)
5075 return -ENOMEM; 5073 return err;
5076 5074
5077 err = register_filesystem(&cgroup_fs_type); 5075 err = register_filesystem(&cgroup_fs_type);
5078 if (err < 0) { 5076 if (err < 0) {
5079 kobject_put(cgroup_kobj); 5077 sysfs_remove_mount_point(fs_kobj, "cgroup");
5080 return err; 5078 return err;
5081 } 5079 }
5082 5080
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 812fcc3fd390..19b62b522158 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1538,12 +1538,6 @@ static struct ctl_table vm_table[] = {
1538 { } 1538 { }
1539}; 1539};
1540 1540
1541#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
1542static struct ctl_table binfmt_misc_table[] = {
1543 { }
1544};
1545#endif
1546
1547static struct ctl_table fs_table[] = { 1541static struct ctl_table fs_table[] = {
1548 { 1542 {
1549 .procname = "inode-nr", 1543 .procname = "inode-nr",
@@ -1697,7 +1691,7 @@ static struct ctl_table fs_table[] = {
1697 { 1691 {
1698 .procname = "binfmt_misc", 1692 .procname = "binfmt_misc",
1699 .mode = 0555, 1693 .mode = 0555,
1700 .child = binfmt_misc_table, 1694 .child = sysctl_mount_point,
1701 }, 1695 },
1702#endif 1696#endif
1703 { 1697 {
diff --git a/security/inode.c b/security/inode.c
index 91503b79c5f8..0e37e4fba8fa 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -215,19 +215,17 @@ void securityfs_remove(struct dentry *dentry)
215} 215}
216EXPORT_SYMBOL_GPL(securityfs_remove); 216EXPORT_SYMBOL_GPL(securityfs_remove);
217 217
218static struct kobject *security_kobj;
219
220static int __init securityfs_init(void) 218static int __init securityfs_init(void)
221{ 219{
222 int retval; 220 int retval;
223 221
224 security_kobj = kobject_create_and_add("security", kernel_kobj); 222 retval = sysfs_create_mount_point(kernel_kobj, "security");
225 if (!security_kobj) 223 if (retval)
226 return -EINVAL; 224 return retval;
227 225
228 retval = register_filesystem(&fs_type); 226 retval = register_filesystem(&fs_type);
229 if (retval) 227 if (retval)
230 kobject_put(security_kobj); 228 sysfs_remove_mount_point(kernel_kobj, "security");
231 return retval; 229 return retval;
232} 230}
233 231
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index d2787cca1fcb..3d2201413028 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1853,7 +1853,6 @@ static struct file_system_type sel_fs_type = {
1853}; 1853};
1854 1854
1855struct vfsmount *selinuxfs_mount; 1855struct vfsmount *selinuxfs_mount;
1856static struct kobject *selinuxfs_kobj;
1857 1856
1858static int __init init_sel_fs(void) 1857static int __init init_sel_fs(void)
1859{ 1858{
@@ -1862,13 +1861,13 @@ static int __init init_sel_fs(void)
1862 if (!selinux_enabled) 1861 if (!selinux_enabled)
1863 return 0; 1862 return 0;
1864 1863
1865 selinuxfs_kobj = kobject_create_and_add("selinux", fs_kobj); 1864 err = sysfs_create_mount_point(fs_kobj, "selinux");
1866 if (!selinuxfs_kobj) 1865 if (err)
1867 return -ENOMEM; 1866 return err;
1868 1867
1869 err = register_filesystem(&sel_fs_type); 1868 err = register_filesystem(&sel_fs_type);
1870 if (err) { 1869 if (err) {
1871 kobject_put(selinuxfs_kobj); 1870 sysfs_remove_mount_point(fs_kobj, "selinux");
1872 return err; 1871 return err;
1873 } 1872 }
1874 1873
@@ -1887,7 +1886,7 @@ __initcall(init_sel_fs);
1887#ifdef CONFIG_SECURITY_SELINUX_DISABLE 1886#ifdef CONFIG_SECURITY_SELINUX_DISABLE
1888void exit_sel_fs(void) 1887void exit_sel_fs(void)
1889{ 1888{
1890 kobject_put(selinuxfs_kobj); 1889 sysfs_remove_mount_point(fs_kobj, "selinux");
1891 kern_unmount(selinuxfs_mount); 1890 kern_unmount(selinuxfs_mount);
1892 unregister_filesystem(&sel_fs_type); 1891 unregister_filesystem(&sel_fs_type);
1893} 1892}
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 5e0a64ebdf23..2716d02119f3 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -2314,16 +2314,16 @@ static const struct file_operations smk_revoke_subj_ops = {
2314 .llseek = generic_file_llseek, 2314 .llseek = generic_file_llseek,
2315}; 2315};
2316 2316
2317static struct kset *smackfs_kset;
2318/** 2317/**
2319 * smk_init_sysfs - initialize /sys/fs/smackfs 2318 * smk_init_sysfs - initialize /sys/fs/smackfs
2320 * 2319 *
2321 */ 2320 */
2322static int smk_init_sysfs(void) 2321static int smk_init_sysfs(void)
2323{ 2322{
2324 smackfs_kset = kset_create_and_add("smackfs", NULL, fs_kobj); 2323 int err;
2325 if (!smackfs_kset) 2324 err = sysfs_create_mount_point(fs_kobj, "smackfs");
2326 return -ENOMEM; 2325 if (err)
2326 return err;
2327 return 0; 2327 return 0;
2328} 2328}
2329 2329