Skip to content

Commit 7dc5dbc

Browse files
committed
sysfs: Restrict mounting sysfs
Don't allow mounting sysfs unless the caller has CAP_SYS_ADMIN rights over the net namespace. The principle here is if you create or have capabilities over it you can mount it, otherwise you get to live with what other people have mounted. Instead of testing this with a straight forward ns_capable call, perform this check the long and torturous way with kobject helpers, this keeps direct knowledge of namespaces out of sysfs, and preserves the existing sysfs abstractions. Acked-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: "Eric W. Biederman" <[email protected]>
1 parent e51db73 commit 7dc5dbc

4 files changed

Lines changed: 34 additions & 3 deletions

File tree

fs/sysfs/mount.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,15 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type,
112112
struct super_block *sb;
113113
int error;
114114

115-
if (!(flags & MS_KERNMOUNT) && !capable(CAP_SYS_ADMIN) &&
116-
!fs_fully_visible(fs_type))
117-
return ERR_PTR(-EPERM);
115+
if (!(flags & MS_KERNMOUNT)) {
116+
if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
117+
return ERR_PTR(-EPERM);
118+
119+
for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) {
120+
if (!kobj_ns_current_may_mount(type))
121+
return ERR_PTR(-EPERM);
122+
}
123+
}
118124

119125
info = kzalloc(sizeof(*info), GFP_KERNEL);
120126
if (!info)

include/linux/kobject_ns.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ enum kobj_ns_type {
3939
*/
4040
struct kobj_ns_type_operations {
4141
enum kobj_ns_type type;
42+
bool (*current_may_mount)(void);
4243
void *(*grab_current_ns)(void);
4344
const void *(*netlink_ns)(struct sock *sk);
4445
const void *(*initial_ns)(void);
@@ -50,6 +51,7 @@ int kobj_ns_type_registered(enum kobj_ns_type type);
5051
const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
5152
const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
5253

54+
bool kobj_ns_current_may_mount(enum kobj_ns_type type);
5355
void *kobj_ns_grab_current(enum kobj_ns_type type);
5456
const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk);
5557
const void *kobj_ns_initial(enum kobj_ns_type type);

lib/kobject.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,21 @@ const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj)
915915
return kobj_child_ns_ops(kobj->parent);
916916
}
917917

918+
bool kobj_ns_current_may_mount(enum kobj_ns_type type)
919+
{
920+
bool may_mount = false;
921+
922+
if (type == KOBJ_NS_TYPE_NONE)
923+
return true;
924+
925+
spin_lock(&kobj_ns_type_lock);
926+
if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
927+
kobj_ns_ops_tbl[type])
928+
may_mount = kobj_ns_ops_tbl[type]->current_may_mount();
929+
spin_unlock(&kobj_ns_type_lock);
930+
931+
return may_mount;
932+
}
918933

919934
void *kobj_ns_grab_current(enum kobj_ns_type type)
920935
{

net/core/net-sysfs.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,13 @@ static void remove_queue_kobjects(struct net_device *net)
11571157
#endif
11581158
}
11591159

1160+
static bool net_current_may_mount(void)
1161+
{
1162+
struct net *net = current->nsproxy->net_ns;
1163+
1164+
return ns_capable(net->user_ns, CAP_SYS_ADMIN);
1165+
}
1166+
11601167
static void *net_grab_current_ns(void)
11611168
{
11621169
struct net *ns = current->nsproxy->net_ns;
@@ -1179,6 +1186,7 @@ static const void *net_netlink_ns(struct sock *sk)
11791186

11801187
struct kobj_ns_type_operations net_ns_type_operations = {
11811188
.type = KOBJ_NS_TYPE_NET,
1189+
.current_may_mount = net_current_may_mount,
11821190
.grab_current_ns = net_grab_current_ns,
11831191
.netlink_ns = net_netlink_ns,
11841192
.initial_ns = net_initial_ns,

0 commit comments

Comments
 (0)