History

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull user namespace rlimit handling update from Eric Biederman: "This is the work mainly by Alexey Gladkov to limit rlimits to the rlimits of the user that created a user namespace, and to allow users to have stricter limits on the resources created within a user namespace." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: cred: add missing return error code when set_cred_ucounts() failed ucounts: Silence warning in dec_rlimit_ucounts ucounts: Set ucount_max to the largest positive value the type can hold kselftests: Add test to check for rlimit changes in different user namespaces Reimplement RLIMIT_MEMLOCK on top of ucounts Reimplement RLIMIT_SIGPENDING on top of ucounts Reimplement RLIMIT_MSGQUEUE on top of ucounts Reimplement RLIMIT_NPROC on top of ucounts Use atomic_t for ucounts reference counting Add a reference to ucounts for each cred Increase size of ucounts to atomic_long_t

Linus Torvalds committed 5 years ago

Commit c54b2452 parents e17c120 5e6b8a529 files · +468 −127Browse files

Showing the changes to kernel (8 of 29 files). Show all

Unified · Split

8 files
  1. kernel/cred.c +46 −5
  2. kernel/exit.c +1 −1
  3. kernel/fork.c +14 −4
  4. kernel/signal.c +13 −12
  5. kernel/sys.c +13 −1
  6. kernel/ucount.c +91 −25
  7. kernel/user.c +0 −3
  8. kernel/user_namespace.c +8 −1
kernel/cred.c+46−5
@@ -60,6 +60,7 @@ struct cred init_cred = { · 59 unmodified lines
6060 .user = INIT_USER,
6161 .user_ns = &init_user_ns,
6262 .group_info = &init_groups,
63+ .ucounts = &init_ucounts,
6364 };
6465
6566 static inline void set_cred_subscribers(struct cred *cred, int n)
@@ -119,6 +120,8 @@ static void put_cred_rcu(struct rcu_head *rcu) · 53 unmodified lines
119120 if (cred->group_info)
120121 put_group_info(cred->group_info);
121122 free_uid(cred->user);
123+ if (cred->ucounts)
124+ put_ucounts(cred->ucounts);
122125 put_user_ns(cred->user_ns);
123126 kmem_cache_free(cred_jar, cred);
124127 }
@@ -222,6 +225,7 @@ struct cred *cred_alloc_blank(void) · 97 unmodified lines
222225 #ifdef CONFIG_DEBUG_CREDENTIALS
223226 new->magic = CRED_MAGIC;
224227 #endif
228+ new->ucounts = get_ucounts(&init_ucounts);
225229
226230 if (security_cred_alloc_blank(new, GFP_KERNEL_ACCOUNT) < 0)
227231 goto error;
@@ -284,6 +288,11 @@ struct cred *prepare_creds(void) · 56 unmodified lines
284288
285289 if (security_prepare_creds(new, old, GFP_KERNEL_ACCOUNT) < 0)
286290 goto error;
291+
292+ new->ucounts = get_ucounts(new->ucounts);
293+ if (!new->ucounts)
294+ goto error;
295+
287296 validate_creds(new);
288297 return new;
289298
@@ -351,7 +360,7 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) · 61 unmodified lines
351360 kdebug("share_creds(%p{%d,%d})",
352361 p->cred, atomic_read(&p->cred->usage),
353362 read_cred_subscribers(p->cred));
354− atomic_inc(&p->cred->user->processes);
363+ inc_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
355364 return 0;
356365 }
357366
@@ -363,6 +372,9 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) · 5 unmodified lines
363372 ret = create_user_ns(new);
364373 if (ret < 0)
365374 goto error_put;
375+ ret = set_cred_ucounts(new);
376+ if (ret < 0)
377+ goto error_put;
366378 }
367379
368380 #ifdef CONFIG_KEYS
@@ -384,8 +396,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) · 15 unmodified lines
384396 }
385397 #endif
386398
387− atomic_inc(&new->user->processes);
388399 p->cred = p->real_cred = get_cred(new);
400+ inc_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
389401 alter_cred_subscribers(new, 2);
390402 validate_creds(new);
391403 return 0;
@@ -485,12 +497,12 @@ int commit_creds(struct cred *new) · 93 unmodified lines
485497 * in set_user().
486498 */
487499 alter_cred_subscribers(new, 2);
488− if (new->user != old->user)
489− atomic_inc(&new->user->processes);
500+ if (new->user != old->user || new->user_ns != old->user_ns)
501+ inc_rlimit_ucounts(new->ucounts, UCOUNT_RLIMIT_NPROC, 1);
490502 rcu_assign_pointer(task->real_cred, new);
491503 rcu_assign_pointer(task->cred, new);
492504 if (new->user != old->user)
493− atomic_dec(&old->user->processes);
505+ dec_rlimit_ucounts(old->ucounts, UCOUNT_RLIMIT_NPROC, 1);
494506 alter_cred_subscribers(old, -2);
495507
496508 /* send notifications */
@@ -653,6 +665,31 @@ int cred_fscmp(const struct cred *a, const struct cred *b) · 156 unmodified lines
653665 }
654666 EXPORT_SYMBOL(cred_fscmp);
655667
668+int set_cred_ucounts(struct cred *new)
669+{
670+ struct task_struct *task = current;
671+ const struct cred *old = task->real_cred;
672+ struct ucounts *old_ucounts = new->ucounts;
673+
674+ if (new->user == old->user && new->user_ns == old->user_ns)
675+ return 0;
676+
677+ /*
678+ * This optimization is needed because alloc_ucounts() uses locks
679+ * for table lookups.
680+ */
681+ if (old_ucounts && old_ucounts->ns == new->user_ns && uid_eq(old_ucounts->uid, new->euid))
682+ return 0;
683+
684+ if (!(new->ucounts = alloc_ucounts(new->user_ns, new->euid)))
685+ return -EAGAIN;
686+
687+ if (old_ucounts)
688+ put_ucounts(old_ucounts);
689+
690+ return 0;
691+}
692+
656693 /*
657694 * initialise the credentials stuff
658695 */
@@ -719,6 +756,10 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) · 60 unmodified lines
719756 if (security_prepare_creds(new, old, GFP_KERNEL_ACCOUNT) < 0)
720757 goto error;
721758
759+ new->ucounts = get_ucounts(new->ucounts);
760+ if (!new->ucounts)
761+ goto error;
762+
722763 put_cred(old);
723764 validate_creds(new);
724765 return new;
kernel/exit.c+1−1
@@ -188,7 +188,7 @@ repeat: · 187 unmodified lines
188188 /* don't need to get the RCU readlock here - the process is dead and
189189 * can't be modifying its own credentials. But shut RCU-lockdep up */
190190 rcu_read_lock();
191− atomic_dec(&__task_cred(p)->user->processes);
191+ dec_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
192192 rcu_read_unlock();
193193
194194 cgroup_release(p);
kernel/fork.c+14−4
@@ -825,9 +825,14 @@ void __init fork_init(void) · 824 unmodified lines
825825 init_task.signal->rlim[RLIMIT_SIGPENDING] =
826826 init_task.signal->rlim[RLIMIT_NPROC];
827827
828− for (i = 0; i < UCOUNT_COUNTS; i++)
828+ for (i = 0; i < MAX_PER_NAMESPACE_UCOUNTS; i++)
829829 init_user_ns.ucount_max[i] = max_threads/2;
830830
831+ set_rlimit_ucount_max(&init_user_ns, UCOUNT_RLIMIT_NPROC, task_rlimit(&init_task, RLIMIT_NPROC));
832+ set_rlimit_ucount_max(&init_user_ns, UCOUNT_RLIMIT_MSGQUEUE, task_rlimit(&init_task, RLIMIT_MSGQUEUE));
833+ set_rlimit_ucount_max(&init_user_ns, UCOUNT_RLIMIT_SIGPENDING, task_rlimit(&init_task, RLIMIT_SIGPENDING));
834+ set_rlimit_ucount_max(&init_user_ns, UCOUNT_RLIMIT_MEMLOCK, task_rlimit(&init_task, RLIMIT_MEMLOCK));
835+
831836 #ifdef CONFIG_VMAP_STACK
832837 cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "fork:vm_stack_cache",
833838 NULL, free_vm_stack_cache);
@@ -1978,8 +1983,7 @@ static __latent_entropy struct task_struct *copy_process( · 1144 unmodified lines
19781983 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
19791984 #endif
19801985 retval = -EAGAIN;
1981− if (atomic_read(&p->real_cred->user->processes) >=
1982− task_rlimit(p, RLIMIT_NPROC)) {
1986+ if (is_ucounts_overlimit(task_ucounts(p), UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC))) {
19831987 if (p->real_cred->user != INIT_USER &&
19841988 !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN))
19851989 goto bad_fork_free;
@@ -2388,7 +2392,7 @@ bad_fork_cleanup_threadgroup_lock: · 402 unmodified lines
23882392 #endif
23892393 delayacct_tsk_free(p);
23902394 bad_fork_cleanup_count:
2391− atomic_dec(&p->cred->user->processes);
2395+ dec_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
23922396 exit_creds(p);
23932397 bad_fork_free:
23942398 WRITE_ONCE(p->__state, TASK_DEAD);
@@ -3001,6 +3005,12 @@ int ksys_unshare(unsigned long unshare_flags) · 606 unmodified lines
30013005 if (err)
30023006 goto bad_unshare_cleanup_cred;
30033007
3008+ if (new_cred) {
3009+ err = set_cred_ucounts(new_cred);
3010+ if (err)
3011+ goto bad_unshare_cleanup_cred;
3012+ }
3013+
30043014 if (new_fs || new_fd || do_sysvsem || new_cred || new_nsproxy) {
30053015 if (do_sysvsem) {
30063016 /*
kernel/signal.c+13−12
@@ -412,8 +412,8 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags, · 411 unmodified lines
412412 int override_rlimit, const unsigned int sigqueue_flags)
413413 {
414414 struct sigqueue *q = NULL;
415− struct user_struct *user;
416− int sigpending;
415+ struct ucounts *ucounts = NULL;
416+ long sigpending;
417417
418418 /*
419419 * Protect access to @t credentials. This can go away when all
@@ -424,27 +424,26 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags, · 4 unmodified lines
424424 * changes from/to zero.
425425 */
426426 rcu_read_lock();
427− user = __task_cred(t)->user;
428− sigpending = atomic_inc_return(&user->sigpending);
427+ ucounts = task_ucounts(t);
428+ sigpending = inc_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
429429 if (sigpending == 1)
430− get_uid(user);
430+ ucounts = get_ucounts(ucounts);
431431 rcu_read_unlock();
432432
433− if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
433+ if (override_rlimit || (sigpending < LONG_MAX && sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
434434 q = kmem_cache_alloc(sigqueue_cachep, gfp_flags);
435435 } else {
436436 print_dropped_signal(sig);
437437 }
438438
439439 if (unlikely(q == NULL)) {
440− if (atomic_dec_and_test(&user->sigpending))
441− free_uid(user);
440+ if (ucounts && dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1))
441+ put_ucounts(ucounts);
442442 } else {
443443 INIT_LIST_HEAD(&q->list);
444444 q->flags = sigqueue_flags;
445− q->user = user;
445+ q->ucounts = ucounts;
446446 }
447−
448447 return q;
449448 }
450449
@@ -452,8 +451,10 @@ static void __sigqueue_free(struct sigqueue *q) · 1 unmodified line
452451 {
453452 if (q->flags & SIGQUEUE_PREALLOC)
454453 return;
455− if (atomic_dec_and_test(&q->user->sigpending))
456− free_uid(q->user);
454+ if (q->ucounts && dec_rlimit_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING, 1)) {
455+ put_ucounts(q->ucounts);
456+ q->ucounts = NULL;
457+ }
457458 kmem_cache_free(sigqueue_cachep, q);
458459 }
459460
kernel/sys.c+13−1
@@ -479,7 +479,7 @@ static int set_user(struct cred *new) · 478 unmodified lines
479479 * for programs doing set*uid()+execve() by harmlessly deferring the
480480 * failure to the execve() stage.
481481 */
482− if (atomic_read(&new_user->processes) >= rlimit(RLIMIT_NPROC) &&
482+ if (is_ucounts_overlimit(new->ucounts, UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC)) &&
483483 new_user != INIT_USER)
484484 current->flags |= PF_NPROC_EXCEEDED;
485485 else
@@ -558,6 +558,10 @@ long __sys_setreuid(uid_t ruid, uid_t euid) · 72 unmodified lines
558558 if (retval < 0)
559559 goto error;
560560
561+ retval = set_cred_ucounts(new);
562+ if (retval < 0)
563+ goto error;
564+
561565 return commit_creds(new);
562566
563567 error:
@@ -616,6 +620,10 @@ long __sys_setuid(uid_t uid) · 52 unmodified lines
616620 if (retval < 0)
617621 goto error;
618622
623+ retval = set_cred_ucounts(new);
624+ if (retval < 0)
625+ goto error;
626+
619627 return commit_creds(new);
620628
621629 error:
@@ -691,6 +699,10 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) · 69 unmodified lines
691699 if (retval < 0)
692700 goto error;
693701
702+ retval = set_cred_ucounts(new);
703+ if (retval < 0)
704+ goto error;
705+
694706 return commit_creds(new);
695707
696708 error:
kernel/ucount.c+91−25
@@ -8,6 +8,12 @@ · 7 unmodified lines
88 #include <linux/kmemleak.h>
99 #include <linux/user_namespace.h>
1010
11+struct ucounts init_ucounts = {
12+ .ns = &init_user_ns,
13+ .uid = GLOBAL_ROOT_UID,
14+ .count = ATOMIC_INIT(1),
15+};
16+
1117 #define UCOUNTS_HASHTABLE_BITS 10
1218 static struct hlist_head ucounts_hashtable[(1 << UCOUNTS_HASHTABLE_BITS)];
1319 static DEFINE_SPINLOCK(ucounts_lock);
@@ -78,6 +84,10 @@ static struct ctl_table user_table[] = { · 64 unmodified lines
7884 UCOUNT_ENTRY("max_fanotify_groups"),
7985 UCOUNT_ENTRY("max_fanotify_marks"),
8086 #endif
87+ { },
88+ { },
89+ { },
90+ { },
8191 { }
8292 };
8393 #endif /* CONFIG_SYSCTL */
@@ -129,7 +139,24 @@ static struct ucounts *find_ucounts(struct user_namespace *ns, kuid_t uid, struc · 45 unmodified lines
129139 return NULL;
130140 }
131141
132−static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
142+static void hlist_add_ucounts(struct ucounts *ucounts)
143+{
144+ struct hlist_head *hashent = ucounts_hashentry(ucounts->ns, ucounts->uid);
145+ spin_lock_irq(&ucounts_lock);
146+ hlist_add_head(&ucounts->node, hashent);
147+ spin_unlock_irq(&ucounts_lock);
148+}
149+
150+struct ucounts *get_ucounts(struct ucounts *ucounts)
151+{
152+ if (ucounts && atomic_add_negative(1, &ucounts->count)) {
153+ put_ucounts(ucounts);
154+ ucounts = NULL;
155+ }
156+ return ucounts;
157+}
158+
159+struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid)
133160 {
134161 struct hlist_head *hashent = ucounts_hashentry(ns, uid);
135162 struct ucounts *ucounts, *new;
@@ -145,7 +172,7 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid) · 9 unmodified lines
145172
146173 new->ns = ns;
147174 new->uid = uid;
148− new->count = 0;
175+ atomic_set(&new->count, 1);
149176
150177 spin_lock_irq(&ucounts_lock);
151178 ucounts = find_ucounts(ns, uid, hashent);
@@ -153,40 +180,35 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid) · 1 unmodified line
153180 kfree(new);
154181 } else {
155182 hlist_add_head(&new->node, hashent);
156− ucounts = new;
183+ spin_unlock_irq(&ucounts_lock);
184+ return new;
157185 }
158186 }
159− if (ucounts->count == INT_MAX)
160− ucounts = NULL;
161− else
162− ucounts->count += 1;
163187 spin_unlock_irq(&ucounts_lock);
188+ ucounts = get_ucounts(ucounts);
164189 return ucounts;
165190 }
166191
167−static void put_ucounts(struct ucounts *ucounts)
192+void put_ucounts(struct ucounts *ucounts)
168193 {
169194 unsigned long flags;
170195
171− spin_lock_irqsave(&ucounts_lock, flags);
172− ucounts->count -= 1;
173− if (!ucounts->count)
196+ if (atomic_dec_and_test(&ucounts->count)) {
197+ spin_lock_irqsave(&ucounts_lock, flags);
174198 hlist_del_init(&ucounts->node);
175− else
176− ucounts = NULL;
177− spin_unlock_irqrestore(&ucounts_lock, flags);
178−
179− kfree(ucounts);
199+ spin_unlock_irqrestore(&ucounts_lock, flags);
200+ kfree(ucounts);
201+ }
180202 }
181203
182−static inline bool atomic_inc_below(atomic_t *v, int u)
204+static inline bool atomic_long_inc_below(atomic_long_t *v, int u)
183205 {
184− int c, old;
185− c = atomic_read(v);
206+ long c, old;
207+ c = atomic_long_read(v);
186208 for (;;) {
187209 if (unlikely(c >= u))
188210 return false;
189− old = atomic_cmpxchg(v, c, c+1);
211+ old = atomic_long_cmpxchg(v, c, c+1);
190212 if (likely(old == c))
191213 return true;
192214 c = old;
@@ -198,19 +220,19 @@ struct ucounts *inc_ucount(struct user_namespace *ns, kuid_t uid, · 5 unmodified lines
198220 {
199221 struct ucounts *ucounts, *iter, *bad;
200222 struct user_namespace *tns;
201− ucounts = get_ucounts(ns, uid);
223+ ucounts = alloc_ucounts(ns, uid);
202224 for (iter = ucounts; iter; iter = tns->ucounts) {
203− int max;
225+ long max;
204226 tns = iter->ns;
205227 max = READ_ONCE(tns->ucount_max[type]);
206− if (!atomic_inc_below(&iter->ucount[type], max))
228+ if (!atomic_long_inc_below(&iter->ucount[type], max))
207229 goto fail;
208230 }
209231 return ucounts;
210232 fail:
211233 bad = iter;
212234 for (iter = ucounts; iter != bad; iter = iter->ns->ucounts)
213− atomic_dec(&iter->ucount[type]);
235+ atomic_long_dec(&iter->ucount[type]);
214236
215237 put_ucounts(ucounts);
216238 return NULL;
@@ -220,12 +242,54 @@ void dec_ucount(struct ucounts *ucounts, enum ucount_type type) · 3 unmodified lines
220242 {
221243 struct ucounts *iter;
222244 for (iter = ucounts; iter; iter = iter->ns->ucounts) {
223− int dec = atomic_dec_if_positive(&iter->ucount[type]);
245+ long dec = atomic_long_dec_if_positive(&iter->ucount[type]);
224246 WARN_ON_ONCE(dec < 0);
225247 }
226248 put_ucounts(ucounts);
227249 }
228250
251+long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v)
252+{
253+ struct ucounts *iter;
254+ long ret = 0;
255+
256+ for (iter = ucounts; iter; iter = iter->ns->ucounts) {
257+ long max = READ_ONCE(iter->ns->ucount_max[type]);
258+ long new = atomic_long_add_return(v, &iter->ucount[type]);
259+ if (new < 0 || new > max)
260+ ret = LONG_MAX;
261+ else if (iter == ucounts)
262+ ret = new;
263+ }
264+ return ret;
265+}
266+
267+bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v)
268+{
269+ struct ucounts *iter;
270+ long new = -1; /* Silence compiler warning */
271+ for (iter = ucounts; iter; iter = iter->ns->ucounts) {
272+ long dec = atomic_long_add_return(-v, &iter->ucount[type]);
273+ WARN_ON_ONCE(dec < 0);
274+ if (iter == ucounts)
275+ new = dec;
276+ }
277+ return (new == 0);
278+}
279+
280+bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max)
281+{
282+ struct ucounts *iter;
283+ if (get_ucounts_value(ucounts, type) > max)
284+ return true;
285+ for (iter = ucounts; iter; iter = iter->ns->ucounts) {
286+ max = READ_ONCE(iter->ns->ucount_max[type]);
287+ if (get_ucounts_value(iter, type) > max)
288+ return true;
289+ }
290+ return false;
291+}
292+
229293 static __init int user_namespace_sysctl_init(void)
230294 {
231295 #ifdef CONFIG_SYSCTL
@@ -241,6 +305,8 @@ static __init int user_namespace_sysctl_init(void) · 9 unmodified lines
241305 BUG_ON(!user_header);
242306 BUG_ON(!setup_userns_sysctls(&init_user_ns));
243307 #endif
308+ hlist_add_ucounts(&init_ucounts);
309+ inc_rlimit_ucounts(&init_ucounts, UCOUNT_RLIMIT_NPROC, 1);
244310 return 0;
245311 }
246312 subsys_initcall(user_namespace_sysctl_init);
kernel/user.c+0−3
@@ -98,9 +98,6 @@ static DEFINE_SPINLOCK(uidhash_lock); · 97 unmodified lines
9898 /* root_user.__count is 1, for init task cred */
9999 struct user_struct root_user = {
100100 .__count = REFCOUNT_INIT(1),
101− .processes = ATOMIC_INIT(1),
102− .sigpending = ATOMIC_INIT(0),
103− .locked_shm = 0,
104101 .uid = GLOBAL_ROOT_UID,
105102 .ratelimit = RATELIMIT_STATE_INIT(root_user.ratelimit, 0, 0),
106103 };
kernel/user_namespace.c+8−1
@@ -119,9 +119,13 @@ int create_user_ns(struct cred *new) · 118 unmodified lines
119119 ns->owner = owner;
120120 ns->group = group;
121121 INIT_WORK(&ns->work, free_user_ns);
122− for (i = 0; i < UCOUNT_COUNTS; i++) {
122+ for (i = 0; i < MAX_PER_NAMESPACE_UCOUNTS; i++) {
123123 ns->ucount_max[i] = INT_MAX;
124124 }
125+ set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC));
126+ set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_MSGQUEUE, rlimit(RLIMIT_MSGQUEUE));
127+ set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_SIGPENDING, rlimit(RLIMIT_SIGPENDING));
128+ set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_MEMLOCK, rlimit(RLIMIT_MEMLOCK));
125129 ns->ucounts = ucounts;
126130
127131 /* Inherit USERNS_SETGROUPS_ALLOWED from our parent */
@@ -1340,6 +1344,9 @@ static int userns_install(struct nsset *nsset, struct ns_common *ns) · 1212 unmodified lines
13401344 put_user_ns(cred->user_ns);
13411345 set_cred_user_ns(cred, get_user_ns(user_ns));
13421346
1347+ if (set_cred_ucounts(cred) < 0)
1348+ return -EINVAL;
1349+
13431350 return 0;
13441351 }
13451352

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t