Merge tag 'fixes-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux
Pull misc fixes from Christian Brauner:
"This contains several fixes which felt worth being combined into a
single branch:
- Use put_nsproxy() instead of open-coding it switch_task_namespaces()
- Kirill's work to unify lifecycle management for all namespaces. The
lifetime counters are used identically for all namespaces types.
Namespaces may of course have additional unrelated counters and
these are not altered. This work allows us to unify the type of the
counters and reduces maintenance cost by moving the counter in one
place and indicating that basic lifetime management is identical
for all namespaces.
- Peilin's fix adding three byte padding to Dmitry's
PTRACE_GET_SYSCALL_INFO uapi struct to prevent an info leak.
- Two smal patches to convert from the /* fall through */ comment
annotation to the fallthrough keyword annotation which I had taken
into my branch and into -next before df561f6688 ("treewide: Use
fallthrough pseudo-keyword") made it upstream which fixed this
tree-wide.
Since I didn't want to invalidate all testing for other commits I
didn't rebase and kept them"
* tag 'fixes-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux:
nsproxy: use put_nsproxy() in switch_task_namespaces()
sys: Convert to the new fallthrough notation
signal: Convert to the new fallthrough notation
time: Use generic ns_common::count
cgroup: Use generic ns_common::count
mnt: Use generic ns_common::count
user: Use generic ns_common::count
pid: Use generic ns_common::count
ipc: Use generic ns_common::count
uts: Use generic ns_common::count
net: Use generic ns_common::count
ns: Add a common refcount into ns_common
ptrace: Prevent kernel-infoleak in ptrace_get_syscall_info()
This commit is contained in:
@@ -199,7 +199,7 @@ static u16 have_canfork_callback __read_mostly;
|
||||
|
||||
/* cgroup namespace for init task */
|
||||
struct cgroup_namespace init_cgroup_ns = {
|
||||
.count = REFCOUNT_INIT(2),
|
||||
.ns.count = REFCOUNT_INIT(2),
|
||||
.user_ns = &init_user_ns,
|
||||
.ns.ops = &cgroupns_operations,
|
||||
.ns.inum = PROC_CGROUP_INIT_INO,
|
||||
|
||||
@@ -32,7 +32,7 @@ static struct cgroup_namespace *alloc_cgroup_ns(void)
|
||||
kfree(new_ns);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
refcount_set(&new_ns->count, 1);
|
||||
refcount_set(&new_ns->ns.count, 1);
|
||||
new_ns->ns.ops = &cgroupns_operations;
|
||||
return new_ns;
|
||||
}
|
||||
|
||||
+3
-3
@@ -172,7 +172,7 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
|
||||
* it along with CLONE_NEWIPC.
|
||||
*/
|
||||
if ((flags & (CLONE_NEWIPC | CLONE_SYSVSEM)) ==
|
||||
(CLONE_NEWIPC | CLONE_SYSVSEM))
|
||||
(CLONE_NEWIPC | CLONE_SYSVSEM))
|
||||
return -EINVAL;
|
||||
|
||||
new_ns = create_new_namespaces(flags, tsk, user_ns, tsk->fs);
|
||||
@@ -245,8 +245,8 @@ void switch_task_namespaces(struct task_struct *p, struct nsproxy *new)
|
||||
p->nsproxy = new;
|
||||
task_unlock(p);
|
||||
|
||||
if (ns && atomic_dec_and_test(&ns->count))
|
||||
free_nsproxy(ns);
|
||||
if (ns)
|
||||
put_nsproxy(ns);
|
||||
}
|
||||
|
||||
void exit_task_namespaces(struct task_struct *p)
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ int pid_max_max = PID_MAX_LIMIT;
|
||||
* the scheme scales to up to 4 million PIDs, runtime.
|
||||
*/
|
||||
struct pid_namespace init_pid_ns = {
|
||||
.kref = KREF_INIT(2),
|
||||
.ns.count = REFCOUNT_INIT(2),
|
||||
.idr = IDR_INIT(init_pid_ns.idr),
|
||||
.pid_allocated = PIDNS_ADDING,
|
||||
.level = 0,
|
||||
|
||||
+3
-10
@@ -102,7 +102,7 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns
|
||||
goto out_free_idr;
|
||||
ns->ns.ops = &pidns_operations;
|
||||
|
||||
kref_init(&ns->kref);
|
||||
refcount_set(&ns->ns.count, 1);
|
||||
ns->level = level;
|
||||
ns->parent = get_pid_ns(parent_pid_ns);
|
||||
ns->user_ns = get_user_ns(user_ns);
|
||||
@@ -148,22 +148,15 @@ struct pid_namespace *copy_pid_ns(unsigned long flags,
|
||||
return create_pid_namespace(user_ns, old_ns);
|
||||
}
|
||||
|
||||
static void free_pid_ns(struct kref *kref)
|
||||
{
|
||||
struct pid_namespace *ns;
|
||||
|
||||
ns = container_of(kref, struct pid_namespace, kref);
|
||||
destroy_pid_namespace(ns);
|
||||
}
|
||||
|
||||
void put_pid_ns(struct pid_namespace *ns)
|
||||
{
|
||||
struct pid_namespace *parent;
|
||||
|
||||
while (ns != &init_pid_ns) {
|
||||
parent = ns->parent;
|
||||
if (!kref_put(&ns->kref, free_pid_ns))
|
||||
if (!refcount_dec_and_test(&ns->ns.count))
|
||||
break;
|
||||
destroy_pid_namespace(ns);
|
||||
ns = parent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ static struct time_namespace *clone_time_ns(struct user_namespace *user_ns,
|
||||
if (!ns)
|
||||
goto fail_dec;
|
||||
|
||||
kref_init(&ns->kref);
|
||||
refcount_set(&ns->ns.count, 1);
|
||||
|
||||
ns->vvar_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
||||
if (!ns->vvar_page)
|
||||
@@ -226,11 +226,8 @@ out:
|
||||
mutex_unlock(&offset_lock);
|
||||
}
|
||||
|
||||
void free_time_ns(struct kref *kref)
|
||||
void free_time_ns(struct time_namespace *ns)
|
||||
{
|
||||
struct time_namespace *ns;
|
||||
|
||||
ns = container_of(kref, struct time_namespace, kref);
|
||||
dec_time_namespaces(ns->ucounts);
|
||||
put_user_ns(ns->user_ns);
|
||||
ns_free_inum(&ns->ns);
|
||||
@@ -462,7 +459,7 @@ const struct proc_ns_operations timens_for_children_operations = {
|
||||
};
|
||||
|
||||
struct time_namespace init_time_ns = {
|
||||
.kref = KREF_INIT(3),
|
||||
.ns.count = REFCOUNT_INIT(3),
|
||||
.user_ns = &init_user_ns,
|
||||
.ns.inum = PROC_TIME_INIT_INO,
|
||||
.ns.ops = &timens_operations,
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ struct user_namespace init_user_ns = {
|
||||
},
|
||||
},
|
||||
},
|
||||
.count = ATOMIC_INIT(3),
|
||||
.ns.count = REFCOUNT_INIT(3),
|
||||
.owner = GLOBAL_ROOT_UID,
|
||||
.group = GLOBAL_ROOT_GID,
|
||||
.ns.inum = PROC_USER_INIT_INO,
|
||||
|
||||
@@ -111,7 +111,7 @@ int create_user_ns(struct cred *new)
|
||||
goto fail_free;
|
||||
ns->ns.ops = &userns_operations;
|
||||
|
||||
atomic_set(&ns->count, 1);
|
||||
refcount_set(&ns->ns.count, 1);
|
||||
/* Leave the new->user_ns reference with the new user namespace. */
|
||||
ns->parent = parent_ns;
|
||||
ns->level = parent_ns->level + 1;
|
||||
@@ -197,7 +197,7 @@ static void free_user_ns(struct work_struct *work)
|
||||
kmem_cache_free(user_ns_cachep, ns);
|
||||
dec_user_namespaces(ucounts);
|
||||
ns = parent;
|
||||
} while (atomic_dec_and_test(&parent->count));
|
||||
} while (refcount_dec_and_test(&parent->ns.count));
|
||||
}
|
||||
|
||||
void __put_user_ns(struct user_namespace *ns)
|
||||
|
||||
+2
-5
@@ -33,7 +33,7 @@ static struct uts_namespace *create_uts_ns(void)
|
||||
|
||||
uts_ns = kmem_cache_alloc(uts_ns_cache, GFP_KERNEL);
|
||||
if (uts_ns)
|
||||
kref_init(&uts_ns->kref);
|
||||
refcount_set(&uts_ns->ns.count, 1);
|
||||
return uts_ns;
|
||||
}
|
||||
|
||||
@@ -103,11 +103,8 @@ struct uts_namespace *copy_utsname(unsigned long flags,
|
||||
return new_ns;
|
||||
}
|
||||
|
||||
void free_uts_ns(struct kref *kref)
|
||||
void free_uts_ns(struct uts_namespace *ns)
|
||||
{
|
||||
struct uts_namespace *ns;
|
||||
|
||||
ns = container_of(kref, struct uts_namespace, kref);
|
||||
dec_uts_namespaces(ns->ucounts);
|
||||
put_user_ns(ns->user_ns);
|
||||
ns_free_inum(&ns->ns);
|
||||
|
||||
Reference in New Issue
Block a user