Skip to content

Commit b6c770d

Browse files
braunergregkh
authored andcommitted
binderfs: make each binderfs mount a new instance
When currently mounting binderfs in the same ipc namespace twice: mount -t binder binder /A mount -t binder binder /B then the binderfs instances mounted on /A and /B will be the same, i.e. they will have the same superblock. This was the first approach that seemed reasonable. However, this leads to some problems and inconsistencies: /* private binderfs instance in same ipc namespace */ There is no way for a user to request a private binderfs instance in the same ipc namespace. This request has been made in a private mail to me by two independent people. /* bind-mounts */ If users want the same binderfs instance to appear in multiple places they can use bind mounts. So there is no value in having a request for a new binderfs mount giving them the same instance. /* unexpected behavior */ It's surprising that request to mount binderfs is not giving the user a new instance like tmpfs, devpts, ramfs, and others do. /* past mistakes */ Other pseudo-filesystems once made the same mistakes of giving back the same superblock when actually requesting a new mount (cf. devpts's deprecated "newinstance" option). We should not make the same mistake. Once we've committed to always giving back the same superblock in the same IPC namespace with the next kernel release we will not be able to make that change so better to do it now. /* kdbusfs */ It was pointed out to me that kdbusfs - which is conceptually closely related to binderfs - also allowed users to get a private kdbusfs instance in the same IPC namespace by making each mount of kdbusfs a separate instance. I think that makes a lot of sense. Signed-off-by: Christian Brauner <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 3fdd94a commit b6c770d

File tree

1 file changed

+2
-39
lines changed

1 file changed

+2
-39
lines changed

drivers/android/binderfs.c

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ static int binderfs_fill_super(struct super_block *sb, void *data, int silent)
379379
struct binderfs_info *info;
380380
int ret = -ENOMEM;
381381
struct inode *inode = NULL;
382-
struct ipc_namespace *ipc_ns = sb->s_fs_info;
382+
struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
383383

384384
get_ipc_ns(ipc_ns);
385385

@@ -450,48 +450,11 @@ static int binderfs_fill_super(struct super_block *sb, void *data, int silent)
450450
return ret;
451451
}
452452

453-
static int binderfs_test_super(struct super_block *sb, void *data)
454-
{
455-
struct binderfs_info *info = sb->s_fs_info;
456-
457-
if (info)
458-
return info->ipc_ns == data;
459-
460-
return 0;
461-
}
462-
463-
static int binderfs_set_super(struct super_block *sb, void *data)
464-
{
465-
sb->s_fs_info = data;
466-
return set_anon_super(sb, NULL);
467-
}
468-
469453
static struct dentry *binderfs_mount(struct file_system_type *fs_type,
470454
int flags, const char *dev_name,
471455
void *data)
472456
{
473-
struct super_block *sb;
474-
struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
475-
476-
if (!ns_capable(ipc_ns->user_ns, CAP_SYS_ADMIN))
477-
return ERR_PTR(-EPERM);
478-
479-
sb = sget_userns(fs_type, binderfs_test_super, binderfs_set_super,
480-
flags, ipc_ns->user_ns, ipc_ns);
481-
if (IS_ERR(sb))
482-
return ERR_CAST(sb);
483-
484-
if (!sb->s_root) {
485-
int ret = binderfs_fill_super(sb, data, flags & SB_SILENT ? 1 : 0);
486-
if (ret) {
487-
deactivate_locked_super(sb);
488-
return ERR_PTR(ret);
489-
}
490-
491-
sb->s_flags |= SB_ACTIVE;
492-
}
493-
494-
return dget(sb->s_root);
457+
return mount_nodev(fs_type, flags, data, binderfs_fill_super);
495458
}
496459

497460
static void binderfs_kill_super(struct super_block *sb)

0 commit comments

Comments
 (0)