Commit d6469690 authored by Alexey Gladkov's avatar Alexey Gladkov Committed by Eric W. Biederman
Browse files

Reimplement RLIMIT_SIGPENDING on top of ucounts



The rlimit counter is tied to uid in the user_namespace. This allows
rlimit values to be specified in userns even if they are already
globally exceeded by the user. However, the value of the previous
user_namespaces cannot be exceeded.

Changelog

v11:
* Revert most of changes to fix performance issues.

v10:
* Fix memory leak on get_ucounts failure.

Signed-off-by: default avatarAlexey Gladkov <legion@kernel.org>
Link: https://lkml.kernel.org/r/df9d7764dddd50f28616b7840de74ec0f81711a8.1619094428.git.legion@kernel.org


Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
parent 6e52a9f0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -284,7 +284,7 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
		collect_sigign_sigcatch(p, &ignored, &caught);
		num_threads = get_nr_threads(p);
		rcu_read_lock();  /* FIXME: is this correct? */
		qsize = atomic_read(&__task_cred(p)->user->sigpending);
		qsize = get_ucounts_value(task_ucounts(p), UCOUNT_RLIMIT_SIGPENDING);
		rcu_read_unlock();
		qlim = task_rlimit(p, RLIMIT_SIGPENDING);
		unlock_task_sighand(p, &flags);
+0 −1
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@
 */
struct user_struct {
	refcount_t __count;	/* reference count */
	atomic_t sigpending;	/* How many pending signals does this user have? */
#ifdef CONFIG_FANOTIFY
	atomic_t fanotify_listeners;
#endif
+3 −1
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ typedef struct kernel_siginfo {
	__SIGINFO;
} kernel_siginfo_t;

struct ucounts;

/*
 * Real Time signals may be queued.
 */
@@ -21,7 +23,7 @@ struct sigqueue {
	struct list_head list;
	int flags;
	kernel_siginfo_t info;
	struct user_struct *user;
	struct ucounts *ucounts;
};

/* flags values. */
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ enum ucount_type {
#endif
	UCOUNT_RLIMIT_NPROC,
	UCOUNT_RLIMIT_MSGQUEUE,
	UCOUNT_RLIMIT_SIGPENDING,
	UCOUNT_COUNTS,
};

+1 −0
Original line number Diff line number Diff line
@@ -824,6 +824,7 @@ void __init fork_init(void)

	init_user_ns.ucount_max[UCOUNT_RLIMIT_NPROC] = task_rlimit(&init_task, RLIMIT_NPROC);
	init_user_ns.ucount_max[UCOUNT_RLIMIT_MSGQUEUE] = task_rlimit(&init_task, RLIMIT_MSGQUEUE);
	init_user_ns.ucount_max[UCOUNT_RLIMIT_SIGPENDING] = task_rlimit(&init_task, RLIMIT_SIGPENDING);

#ifdef CONFIG_VMAP_STACK
	cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "fork:vm_stack_cache",
Loading