Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'ucount-rlimits-cleanups-for-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull ucounts update from Eric Biederman:
"Split rlimit and ucount values and max values

After the ucount rlimit code was merged a bunch of small but
siginificant bugs were found and fixed. At the time it was realized
that part of the problem was that while the ucount rlimits were very
similar to the oridinary ucounts (in being nested counts with limits)
the semantics were slightly different and the code would be less error
prone if there was less sharing.

This is the long awaited cleanup that should hopefully keep things
more comprehensible and less error prone for whoever needs to touch
that code next"

* tag 'ucount-rlimits-cleanups-for-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace:
ucounts: Split rlimit and ucount values and max values

+51 -46
+1 -1
fs/exec.c
··· 1879 1879 * whether NPROC limit is still exceeded. 1880 1880 */ 1881 1881 if ((current->flags & PF_NPROC_EXCEEDED) && 1882 - is_ucounts_overlimit(current_ucounts(), UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC))) { 1882 + is_rlimit_overlimit(current_ucounts(), UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC))) { 1883 1883 retval = -EAGAIN; 1884 1884 goto out_ret; 1885 1885 }
+1 -1
fs/proc/array.c
··· 279 279 collect_sigign_sigcatch(p, &ignored, &caught); 280 280 num_threads = get_nr_threads(p); 281 281 rcu_read_lock(); /* FIXME: is this correct? */ 282 - qsize = get_ucounts_value(task_ucounts(p), UCOUNT_RLIMIT_SIGPENDING); 282 + qsize = get_rlimit_value(task_ucounts(p), UCOUNT_RLIMIT_SIGPENDING); 283 283 rcu_read_unlock(); 284 284 qlim = task_rlimit(p, RLIMIT_SIGPENDING); 285 285 unlock_task_sighand(p, &flags);
+22 -13
include/linux/user_namespace.h
··· 54 54 UCOUNT_FANOTIFY_GROUPS, 55 55 UCOUNT_FANOTIFY_MARKS, 56 56 #endif 57 + UCOUNT_COUNTS, 58 + }; 59 + 60 + enum rlimit_type { 57 61 UCOUNT_RLIMIT_NPROC, 58 62 UCOUNT_RLIMIT_MSGQUEUE, 59 63 UCOUNT_RLIMIT_SIGPENDING, 60 64 UCOUNT_RLIMIT_MEMLOCK, 61 - UCOUNT_COUNTS, 65 + UCOUNT_RLIMIT_COUNTS, 62 66 }; 63 - 64 - #define MAX_PER_NAMESPACE_UCOUNTS UCOUNT_RLIMIT_NPROC 65 67 66 68 struct user_namespace { 67 69 struct uid_gid_map uid_map; ··· 101 99 #endif 102 100 struct ucounts *ucounts; 103 101 long ucount_max[UCOUNT_COUNTS]; 102 + long rlimit_max[UCOUNT_RLIMIT_COUNTS]; 104 103 } __randomize_layout; 105 104 106 105 struct ucounts { ··· 110 107 kuid_t uid; 111 108 atomic_t count; 112 109 atomic_long_t ucount[UCOUNT_COUNTS]; 110 + atomic_long_t rlimit[UCOUNT_RLIMIT_COUNTS]; 113 111 }; 114 112 115 113 extern struct user_namespace init_user_ns; ··· 124 120 struct ucounts * __must_check get_ucounts(struct ucounts *ucounts); 125 121 void put_ucounts(struct ucounts *ucounts); 126 122 127 - static inline long get_ucounts_value(struct ucounts *ucounts, enum ucount_type type) 123 + static inline long get_rlimit_value(struct ucounts *ucounts, enum rlimit_type type) 128 124 { 129 - return atomic_long_read(&ucounts->ucount[type]); 125 + return atomic_long_read(&ucounts->rlimit[type]); 130 126 } 131 127 132 - long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v); 133 - bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v); 134 - long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type); 135 - void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type); 136 - bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max); 128 + long inc_rlimit_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v); 129 + bool dec_rlimit_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v); 130 + long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type); 131 + void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum rlimit_type type); 132 + bool is_rlimit_overlimit(struct ucounts *ucounts, enum rlimit_type type, unsigned long max); 137 133 138 - static inline void set_rlimit_ucount_max(struct user_namespace *ns, 139 - enum ucount_type type, unsigned long max) 134 + static inline long get_userns_rlimit_max(struct user_namespace *ns, enum rlimit_type type) 140 135 { 141 - ns->ucount_max[type] = max <= LONG_MAX ? max : LONG_MAX; 136 + return READ_ONCE(ns->rlimit_max[type]); 137 + } 138 + 139 + static inline void set_userns_rlimit_max(struct user_namespace *ns, 140 + enum rlimit_type type, unsigned long max) 141 + { 142 + ns->rlimit_max[type] = max <= LONG_MAX ? max : LONG_MAX; 142 143 } 143 144 144 145 #ifdef CONFIG_USER_NS
+6 -6
kernel/fork.c
··· 925 925 init_task.signal->rlim[RLIMIT_SIGPENDING] = 926 926 init_task.signal->rlim[RLIMIT_NPROC]; 927 927 928 - for (i = 0; i < MAX_PER_NAMESPACE_UCOUNTS; i++) 928 + for (i = 0; i < UCOUNT_COUNTS; i++) 929 929 init_user_ns.ucount_max[i] = max_threads/2; 930 930 931 - set_rlimit_ucount_max(&init_user_ns, UCOUNT_RLIMIT_NPROC, RLIM_INFINITY); 932 - set_rlimit_ucount_max(&init_user_ns, UCOUNT_RLIMIT_MSGQUEUE, RLIM_INFINITY); 933 - set_rlimit_ucount_max(&init_user_ns, UCOUNT_RLIMIT_SIGPENDING, RLIM_INFINITY); 934 - set_rlimit_ucount_max(&init_user_ns, UCOUNT_RLIMIT_MEMLOCK, RLIM_INFINITY); 931 + set_userns_rlimit_max(&init_user_ns, UCOUNT_RLIMIT_NPROC, RLIM_INFINITY); 932 + set_userns_rlimit_max(&init_user_ns, UCOUNT_RLIMIT_MSGQUEUE, RLIM_INFINITY); 933 + set_userns_rlimit_max(&init_user_ns, UCOUNT_RLIMIT_SIGPENDING, RLIM_INFINITY); 934 + set_userns_rlimit_max(&init_user_ns, UCOUNT_RLIMIT_MEMLOCK, RLIM_INFINITY); 935 935 936 936 #ifdef CONFIG_VMAP_STACK 937 937 cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "fork:vm_stack_cache", ··· 2117 2117 goto bad_fork_free; 2118 2118 2119 2119 retval = -EAGAIN; 2120 - if (is_ucounts_overlimit(task_ucounts(p), UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC))) { 2120 + if (is_rlimit_overlimit(task_ucounts(p), UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC))) { 2121 2121 if (p->real_cred->user != INIT_USER && 2122 2122 !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) 2123 2123 goto bad_fork_cleanup_count;
+1 -1
kernel/sys.c
··· 496 496 * for programs doing set*uid()+execve() by harmlessly deferring the 497 497 * failure to the execve() stage. 498 498 */ 499 - if (is_ucounts_overlimit(new->ucounts, UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC)) && 499 + if (is_rlimit_overlimit(new->ucounts, UCOUNT_RLIMIT_NPROC, rlimit(RLIMIT_NPROC)) && 500 500 new->user != INIT_USER) 501 501 current->flags |= PF_NPROC_EXCEEDED; 502 502 else
+15 -19
kernel/ucount.c
··· 87 87 UCOUNT_ENTRY("max_fanotify_groups"), 88 88 UCOUNT_ENTRY("max_fanotify_marks"), 89 89 #endif 90 - { }, 91 - { }, 92 - { }, 93 - { }, 94 90 { } 95 91 }; 96 92 #endif /* CONFIG_SYSCTL */ ··· 259 263 put_ucounts(ucounts); 260 264 } 261 265 262 - long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v) 266 + long inc_rlimit_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v) 263 267 { 264 268 struct ucounts *iter; 265 269 long max = LONG_MAX; 266 270 long ret = 0; 267 271 268 272 for (iter = ucounts; iter; iter = iter->ns->ucounts) { 269 - long new = atomic_long_add_return(v, &iter->ucount[type]); 273 + long new = atomic_long_add_return(v, &iter->rlimit[type]); 270 274 if (new < 0 || new > max) 271 275 ret = LONG_MAX; 272 276 else if (iter == ucounts) 273 277 ret = new; 274 - max = READ_ONCE(iter->ns->ucount_max[type]); 278 + max = get_userns_rlimit_max(iter->ns, type); 275 279 } 276 280 return ret; 277 281 } 278 282 279 - bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v) 283 + bool dec_rlimit_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v) 280 284 { 281 285 struct ucounts *iter; 282 286 long new = -1; /* Silence compiler warning */ 283 287 for (iter = ucounts; iter; iter = iter->ns->ucounts) { 284 - long dec = atomic_long_sub_return(v, &iter->ucount[type]); 288 + long dec = atomic_long_sub_return(v, &iter->rlimit[type]); 285 289 WARN_ON_ONCE(dec < 0); 286 290 if (iter == ucounts) 287 291 new = dec; ··· 290 294 } 291 295 292 296 static void do_dec_rlimit_put_ucounts(struct ucounts *ucounts, 293 - struct ucounts *last, enum ucount_type type) 297 + struct ucounts *last, enum rlimit_type type) 294 298 { 295 299 struct ucounts *iter, *next; 296 300 for (iter = ucounts; iter != last; iter = next) { 297 - long dec = atomic_long_sub_return(1, &iter->ucount[type]); 301 + long dec = atomic_long_sub_return(1, &iter->rlimit[type]); 298 302 WARN_ON_ONCE(dec < 0); 299 303 next = iter->ns->ucounts; 300 304 if (dec == 0) ··· 302 306 } 303 307 } 304 308 305 - void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type) 309 + void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum rlimit_type type) 306 310 { 307 311 do_dec_rlimit_put_ucounts(ucounts, NULL, type); 308 312 } 309 313 310 - long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type) 314 + long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type) 311 315 { 312 316 /* Caller must hold a reference to ucounts */ 313 317 struct ucounts *iter; ··· 315 319 long dec, ret = 0; 316 320 317 321 for (iter = ucounts; iter; iter = iter->ns->ucounts) { 318 - long new = atomic_long_add_return(1, &iter->ucount[type]); 322 + long new = atomic_long_add_return(1, &iter->rlimit[type]); 319 323 if (new < 0 || new > max) 320 324 goto unwind; 321 325 if (iter == ucounts) 322 326 ret = new; 323 - max = READ_ONCE(iter->ns->ucount_max[type]); 327 + max = get_userns_rlimit_max(iter->ns, type); 324 328 /* 325 329 * Grab an extra ucount reference for the caller when 326 330 * the rlimit count was previously 0. ··· 332 336 } 333 337 return ret; 334 338 dec_unwind: 335 - dec = atomic_long_sub_return(1, &iter->ucount[type]); 339 + dec = atomic_long_sub_return(1, &iter->rlimit[type]); 336 340 WARN_ON_ONCE(dec < 0); 337 341 unwind: 338 342 do_dec_rlimit_put_ucounts(ucounts, iter, type); 339 343 return 0; 340 344 } 341 345 342 - bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long rlimit) 346 + bool is_rlimit_overlimit(struct ucounts *ucounts, enum rlimit_type type, unsigned long rlimit) 343 347 { 344 348 struct ucounts *iter; 345 349 long max = rlimit; 346 350 if (rlimit > LONG_MAX) 347 351 max = LONG_MAX; 348 352 for (iter = ucounts; iter; iter = iter->ns->ucounts) { 349 - long val = get_ucounts_value(iter, type); 353 + long val = get_rlimit_value(iter, type); 350 354 if (val < 0 || val > max) 351 355 return true; 352 - max = READ_ONCE(iter->ns->ucount_max[type]); 356 + max = get_userns_rlimit_max(iter->ns, type); 353 357 } 354 358 return false; 355 359 }
+5 -5
kernel/user_namespace.c
··· 136 136 ns->owner = owner; 137 137 ns->group = group; 138 138 INIT_WORK(&ns->work, free_user_ns); 139 - for (i = 0; i < MAX_PER_NAMESPACE_UCOUNTS; i++) { 139 + for (i = 0; i < UCOUNT_COUNTS; i++) { 140 140 ns->ucount_max[i] = INT_MAX; 141 141 } 142 - set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_NPROC, enforced_nproc_rlimit()); 143 - set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_MSGQUEUE, rlimit(RLIMIT_MSGQUEUE)); 144 - set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_SIGPENDING, rlimit(RLIMIT_SIGPENDING)); 145 - set_rlimit_ucount_max(ns, UCOUNT_RLIMIT_MEMLOCK, rlimit(RLIMIT_MEMLOCK)); 142 + set_userns_rlimit_max(ns, UCOUNT_RLIMIT_NPROC, enforced_nproc_rlimit()); 143 + set_userns_rlimit_max(ns, UCOUNT_RLIMIT_MSGQUEUE, rlimit(RLIMIT_MSGQUEUE)); 144 + set_userns_rlimit_max(ns, UCOUNT_RLIMIT_SIGPENDING, rlimit(RLIMIT_SIGPENDING)); 145 + set_userns_rlimit_max(ns, UCOUNT_RLIMIT_MEMLOCK, rlimit(RLIMIT_MEMLOCK)); 146 146 ns->ucounts = ucounts; 147 147 148 148 /* Inherit USERNS_SETGROUPS_ALLOWED from our parent */