Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1421251 > unrolled thread

[RFC 00/18] Present useful limits to user

Started byTopi Miettinen <toiwoton@gmail.com>
First post2016-06-13 21:50 +0200
Last post2016-06-20 19:50 +0200
Articles 20 on this page of 50 — 14 participants

Back to article view | Back to linux.kernel


Contents

  [RFC 00/18] Present useful limits to user Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
    [RFC 16/18] limits: track RLIMIT_NICE actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
    [RFC 03/18] memcontrol: present maximum used memory also for cgroup-v2 Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
      Re: [RFC 03/18] memcontrol: present maximum used memory also for  cgroup-v2 Michal Hocko <mhocko@kernel.org> - 2016-06-14 09:10 +0200
        Re: [RFC 03/18] memcontrol: present maximum used memory also for  cgroup-v2 Topi Miettinen <toiwoton@gmail.com> - 2016-06-14 17:50 +0200
          Re: [RFC 03/18] memcontrol: present maximum used memory also for  cgroup-v2 Johannes Weiner <hannes@cmpxchg.org> - 2016-06-14 18:10 +0200
            Re: [RFC 03/18] memcontrol: present maximum used memory also for  cgroup-v2 Topi Miettinen <toiwoton@gmail.com> - 2016-06-14 19:20 +0200
              Re: [RFC 03/18] memcontrol: present maximum used memory also for  cgroup-v2 Michal Hocko <mhocko@kernel.org> - 2016-06-16 12:30 +0200
    [RFC 02/18] cgroup_pids: track maximum pids Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
      Re: [RFC 02/18] cgroup_pids: track maximum pids Tejun Heo <tj@kernel.org> - 2016-06-13 23:20 +0200
        Re: [RFC 02/18] cgroup_pids: track maximum pids Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 23:30 +0200
          Re: [RFC 02/18] cgroup_pids: track maximum pids Tejun Heo <tj@kernel.org> - 2016-06-13 23:40 +0200
            Re: [RFC 02/18] cgroup_pids: track maximum pids Topi Miettinen <toiwoton@gmail.com> - 2016-06-14 00:00 +0200
              Re: [RFC 02/18] cgroup_pids: track maximum pids Tejun Heo <tj@kernel.org> - 2016-06-14 00:10 +0200
    [RFC 01/18] capabilities: track actually used capabilities Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
      Re: [RFC 01/18] capabilities: track actually used capabilities Andy Lutomirski <luto@amacapital.net> - 2016-06-13 22:40 +0200
        Re: [RFC 01/18] capabilities: track actually used capabilities Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 22:50 +0200
          Re: [RFC 01/18] capabilities: track actually used capabilities Andy Lutomirski <luto@amacapital.net> - 2016-06-13 23:20 +0200
            Re: [RFC 01/18] capabilities: track actually used capabilities Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 23:50 +0200
    [RFC 18/18] proc: present VM_LOCKED memory in /proc/self/maps Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
      Re: [RFC 18/18] proc: present VM_LOCKED memory in /proc/self/maps Kees Cook <kees@outflux.net> - 2016-06-13 23:00 +0200
        Re: [RFC 18/18] proc: present VM_LOCKED memory in /proc/self/maps Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 23:00 +0200
    [RFC 14/18] limits: track RLIMIT_SIGPENDING actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
      Re: [RFC 14/18] limits: track RLIMIT_SIGPENDING actual max Oleg Nesterov <oleg@redhat.com> - 2016-06-14 17:00 +0200
        Re: [RFC 14/18] limits: track RLIMIT_SIGPENDING actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-14 18:00 +0200
    [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
      Re: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max Andy Lutomirski <luto@kernel.org> - 2016-06-13 22:50 +0200
        Re: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 23:20 +0200
          Re: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max Andy Lutomirski <luto@amacapital.net> - 2016-06-13 23:20 +0200
            Re: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-14 17:30 +0200
    [RFC 15/18] limits: track RLIMIT_MSGQUEUE actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
      Re: [RFC 15/18] limits: track RLIMIT_MSGQUEUE actual max Doug Ledford <dledford@redhat.com> - 2016-06-17 22:00 +0200
    [RFC 06/18] limits: present RLIMIT_CPU and RLIMIT_RTTIMER current status Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
      Re: [RFC 06/18] limits: present RLIMIT_CPU and RLIMIT_RTTIMER current status Alexey Dobriyan <adobriyan@gmail.com> - 2016-06-14 11:20 +0200
    [RFC 11/18] limits: track and present RLIMIT_NPROC actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
      Re: [RFC 11/18] limits: track and present RLIMIT_NPROC actual max Jann Horn <jann@thejh.net> - 2016-06-14 00:30 +0200
        Re: [RFC 11/18] limits: track and present RLIMIT_NPROC actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-14 17:50 +0200
          Re: [RFC 11/18] limits: track and present RLIMIT_NPROC actual max Jann Horn <jann@thejh.net> - 2016-06-15 01:20 +0200
    [RFC 17/18] limits: track RLIMIT_RTPRIO actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
    [RFC 04/18] device_cgroup: track and present accessed devices Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
      Re: [RFC 04/18] device_cgroup: track and present accessed devices "Serge E. Hallyn" <serge@hallyn.com> - 2016-06-17 17:30 +0200
    [RFC 10/18] limits: track RLIMIT_STACK actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
    [RFC 08/18] limits: track RLIMIT_DATA actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
    [RFC 13/18] limits: track RLIMIT_AS actual max Topi Miettinen <toiwoton@gmail.com> - 2016-06-13 21:50 +0200
    Re: [RFC 00/18] Present useful limits to user Konstantin Khlebnikov <koct9i@gmail.com> - 2016-06-14 21:10 +0200
      Re: [RFC 00/18] Present useful limits to user Topi Miettinen <toiwoton@gmail.com> - 2016-06-14 21:50 +0200
      Re: [RFC 00/18] Present useful limits to user "Austin S. Hemmelgarn" <ahferroin7@gmail.com> - 2016-06-15 16:50 +0200
        Re: [RFC 00/18] Present useful limits to user Konstantin Khlebnikov <koct9i@gmail.com> - 2016-06-18 16:50 +0200
          Re: [RFC 00/18] Present useful limits to user Topi Miettinen <toiwoton@gmail.com> - 2016-06-19 08:40 +0200
          Re: [RFC 00/18] Present useful limits to user "Austin S. Hemmelgarn" <ahferroin7@gmail.com> - 2016-06-20 19:50 +0200

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#1421314 — Re: [RFC 18/18] proc: present VM_LOCKED memory in /proc/self/maps

FromKees Cook <kees@outflux.net>
Date2016-06-13 23:00 +0200
SubjectRe: [RFC 18/18] proc: present VM_LOCKED memory in /proc/self/maps
Message-ID<rJH7I-2Zc-37@gated-at.bofh.it>
In reply to#1421257
On Mon, Jun 13, 2016 at 10:44:25PM +0300, Topi Miettinen wrote:
> Add a flag to /proc/self/maps to show that the memory area is locked.
> 
> Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
> ---
>  fs/proc/task_mmu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
> index 4648c7f..8229509 100644
> --- a/fs/proc/task_mmu.c
> +++ b/fs/proc/task_mmu.c

If you change the maps format, you'll need to update task_nommu.c too.

> @@ -313,13 +313,14 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
>  		end -= PAGE_SIZE;
>  
>  	seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);

I think the width needs to be adjusted for the new character.

> -	seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
> +	seq_printf(m, "%08lx-%08lx %c%c%c%c%c %08llx %02x:%02x %lu ",

Have you checked that no userspace tools that parse "maps" will break with
this flag addition?

>  			start,
>  			end,
>  			flags & VM_READ ? 'r' : '-',
>  			flags & VM_WRITE ? 'w' : '-',
>  			flags & VM_EXEC ? 'x' : '-',
>  			flags & VM_MAYSHARE ? 's' : 'p',
> +			flags & VM_LOCKED ? 'l' : '-',

IIUC, the smaps file already includes the locked information in VmFlags as
"lo" (see show_smap_vma_flags), so I think you probably don't want this
patch at all.

-Kees

>  			pgoff,
>  			MAJOR(dev), MINOR(dev), ino);
>  
> -- 
> 2.8.1

-- 
Kees Cook                                            @outflux.net

[toc] | [prev] | [next] | [standalone]


#1421319 — Re: [RFC 18/18] proc: present VM_LOCKED memory in /proc/self/maps

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-13 23:00 +0200
SubjectRe: [RFC 18/18] proc: present VM_LOCKED memory in /proc/self/maps
Message-ID<rJH7I-2Zc-39@gated-at.bofh.it>
In reply to#1421314
On 06/13/16 20:43, Kees Cook wrote:
> On Mon, Jun 13, 2016 at 10:44:25PM +0300, Topi Miettinen wrote:
>> Add a flag to /proc/self/maps to show that the memory area is locked.
>>
>> Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
>> ---
>>  fs/proc/task_mmu.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
>> index 4648c7f..8229509 100644
>> --- a/fs/proc/task_mmu.c
>> +++ b/fs/proc/task_mmu.c
> 
> If you change the maps format, you'll need to update task_nommu.c too.
> 
>> @@ -313,13 +313,14 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
>>  		end -= PAGE_SIZE;
>>  
>>  	seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
> 
> I think the width needs to be adjusted for the new character.
> 
>> -	seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
>> +	seq_printf(m, "%08lx-%08lx %c%c%c%c%c %08llx %02x:%02x %lu ",
> 
> Have you checked that no userspace tools that parse "maps" will break with
> this flag addition?
> 
>>  			start,
>>  			end,
>>  			flags & VM_READ ? 'r' : '-',
>>  			flags & VM_WRITE ? 'w' : '-',
>>  			flags & VM_EXEC ? 'x' : '-',
>>  			flags & VM_MAYSHARE ? 's' : 'p',
>> +			flags & VM_LOCKED ? 'l' : '-',
> 
> IIUC, the smaps file already includes the locked information in VmFlags as
> "lo" (see show_smap_vma_flags), so I think you probably don't want this
> patch at all.

Yes. the amount of locked memory is also shown:
Locked:                8 kB
VmFlags: rd wr mr mw me lo ac sd

Sorry, I didn't notice that. I'll drop the patch.

-Topi

> 
> -Kees
> 
>>  			pgoff,
>>  			MAJOR(dev), MINOR(dev), ino);
>>  
>> -- 
>> 2.8.1
> 

[toc] | [prev] | [next] | [standalone]


#1421259 — [RFC 14/18] limits: track RLIMIT_SIGPENDING actual max

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-13 21:50 +0200
Subject[RFC 14/18] limits: track RLIMIT_SIGPENDING actual max
Message-ID<rJG1Y-2jr-27@gated-at.bofh.it>
In reply to#1421251
Track maximum number of pending signals, presented in /proc/self/limits.

Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
---
 kernel/signal.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/signal.c b/kernel/signal.c
index 96e9bc4..c8fbccd 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -387,6 +387,8 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
 		INIT_LIST_HEAD(&q->list);
 		q->flags = 0;
 		q->user = user;
+		/* XXX resource limits apply per task, not per user */
+		bump_rlimit(RLIMIT_SIGPENDING, atomic_read(&user->sigpending));
 	}
 
 	return q;
-- 
2.8.1

[toc] | [prev] | [next] | [standalone]


#1421982 — Re: [RFC 14/18] limits: track RLIMIT_SIGPENDING actual max

FromOleg Nesterov <oleg@redhat.com>
Date2016-06-14 17:00 +0200
SubjectRe: [RFC 14/18] limits: track RLIMIT_SIGPENDING actual max
Message-ID<rJXYR-69X-5@gated-at.bofh.it>
In reply to#1421259
On 06/13, Topi Miettinen wrote:
>
> Track maximum number of pending signals, presented in /proc/self/limits.
>
> Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
> ---
>  kernel/signal.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/kernel/signal.c b/kernel/signal.c
> index 96e9bc4..c8fbccd 100644
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -387,6 +387,8 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
>  		INIT_LIST_HEAD(&q->list);
>  		q->flags = 0;
>  		q->user = user;
> +		/* XXX resource limits apply per task, not per user */
> +		bump_rlimit(RLIMIT_SIGPENDING, atomic_read(&user->sigpending));

Well, I have to admit that I too dislike the very idea of these changes...

But this particular patch looks wrong in any case. I wasn't cc'ed on the
previous patches which add bump_rlimit(), but I have found

	"[RFC 05/18] limits: track and present RLIMIT_NOFILE actual max"
	http://marc.info/?l=linux-fsdevel&m=146584742331072&w=2

and bump_rlimit() changes current->signal->rlim_curmax, while in this case
you need to bump t->signal->rlim_curmax.

Oleg.

[toc] | [prev] | [next] | [standalone]


#1422037 — Re: [RFC 14/18] limits: track RLIMIT_SIGPENDING actual max

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-14 18:00 +0200
SubjectRe: [RFC 14/18] limits: track RLIMIT_SIGPENDING actual max
Message-ID<rJYUV-6QY-5@gated-at.bofh.it>
In reply to#1421982
On 06/14/16 14:50, Oleg Nesterov wrote:
> On 06/13, Topi Miettinen wrote:
>>
>> Track maximum number of pending signals, presented in /proc/self/limits.
>>
>> Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
>> ---
>>  kernel/signal.c | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/kernel/signal.c b/kernel/signal.c
>> index 96e9bc4..c8fbccd 100644
>> --- a/kernel/signal.c
>> +++ b/kernel/signal.c
>> @@ -387,6 +387,8 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
>>  		INIT_LIST_HEAD(&q->list);
>>  		q->flags = 0;
>>  		q->user = user;
>> +		/* XXX resource limits apply per task, not per user */
>> +		bump_rlimit(RLIMIT_SIGPENDING, atomic_read(&user->sigpending));
> 
> Well, I have to admit that I too dislike the very idea of these changes...
> 
> But this particular patch looks wrong in any case. I wasn't cc'ed on the
> previous patches which add bump_rlimit(), but I have found
> 
> 	"[RFC 05/18] limits: track and present RLIMIT_NOFILE actual max"
> 	http://marc.info/?l=linux-fsdevel&m=146584742331072&w=2
> 

I used git send-email --cc-cmd=scripts/get_maintainer.pl to generate the
CC lists. Is there a better way?

> and bump_rlimit() changes current->signal->rlim_curmax, while in this case
> you need to bump t->signal->rlim_curmax.
> 
> Oleg.
> 

Yes, I also added task_bump_rlimit() which would be better choice here.

-Topi

[toc] | [prev] | [next] | [standalone]


#1421260 — [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-13 21:50 +0200
Subject[RFC 05/18] limits: track and present RLIMIT_NOFILE actual max
Message-ID<rJG1Y-2jr-31@gated-at.bofh.it>
In reply to#1421251
Track maximum number of files for the process, present current maximum
in /proc/self/limits.

Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
---
 fs/file.c             |  4 ++++
 fs/proc/base.c        | 10 ++++++----
 include/linux/sched.h |  7 +++++++
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index 6b1acdf..2d0d206 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -547,6 +547,8 @@ repeat:
 	}
 #endif
 
+	bump_rlimit(RLIMIT_NOFILE, fd);
+
 out:
 	spin_unlock(&files->file_lock);
 	return error;
@@ -857,6 +859,8 @@ __releases(&files->file_lock)
 	if (tofree)
 		filp_close(tofree, files);
 
+	bump_rlimit(RLIMIT_NOFILE, fd);
+
 	return fd;
 
 Ebusy:
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a11eb71..227997b 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -630,8 +630,8 @@ static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
 	/*
 	 * print the file header
 	 */
-       seq_printf(m, "%-25s %-20s %-20s %-10s\n",
-		  "Limit", "Soft Limit", "Hard Limit", "Units");
+	seq_printf(m, "%-25s %-20s %-20s %-10s %-20s\n",
+		   "Limit", "Soft Limit", "Hard Limit", "Units", "Max");
 
 	for (i = 0; i < RLIM_NLIMITS; i++) {
 		if (rlim[i].rlim_cur == RLIM_INFINITY)
@@ -647,9 +647,11 @@ static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
 			seq_printf(m, "%-20lu ", rlim[i].rlim_max);
 
 		if (lnames[i].unit)
-			seq_printf(m, "%-10s\n", lnames[i].unit);
+			seq_printf(m, "%-10s", lnames[i].unit);
 		else
-			seq_putc(m, '\n');
+			seq_printf(m, "%-10s", "");
+		seq_printf(m, "%-20lu\n",
+			   task->signal->rlim_curmax[i]);
 	}
 
 	return 0;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 9c48a08..0150380 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -782,6 +782,7 @@ struct signal_struct {
 	 * have no need to disable irqs.
 	 */
 	struct rlimit rlim[RLIM_NLIMITS];
+	unsigned long rlim_curmax[RLIM_NLIMITS];
 
 #ifdef CONFIG_BSD_PROCESS_ACCT
 	struct pacct_struct pacct;	/* per-process accounting information */
@@ -3376,6 +3377,12 @@ static inline unsigned long rlimit_max(unsigned int limit)
 	return task_rlimit_max(current, limit);
 }
 
+static inline void bump_rlimit(unsigned int limit, unsigned long r)
+{
+	if (READ_ONCE(current->signal->rlim_curmax[limit]) < r)
+		current->signal->rlim_curmax[limit] = r;
+}
+
 #ifdef CONFIG_CPU_FREQ
 struct update_util_data {
 	void (*func)(struct update_util_data *data,
-- 
2.8.1

[toc] | [prev] | [next] | [standalone]


#1421297 — Re: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max

FromAndy Lutomirski <luto@kernel.org>
Date2016-06-13 22:50 +0200
SubjectRe: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max
Message-ID<rJGY1-2UX-5@gated-at.bofh.it>
In reply to#1421260
On 06/13/2016 12:44 PM, Topi Miettinen wrote:
> Track maximum number of files for the process, present current maximum
> in /proc/self/limits.

The core part should be its own patch.

Also, you have this weirdly named (and racy!) function bump_rlimit. 
Wouldn't this be nicer if you taught the rlimit code to track the 
*current* usage generically and to derive the max usage from that?

> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index a11eb71..227997b 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -630,8 +630,8 @@ static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
>  	/*
>  	 * print the file header
>  	 */
> -       seq_printf(m, "%-25s %-20s %-20s %-10s\n",
> -		  "Limit", "Soft Limit", "Hard Limit", "Units");
> +	seq_printf(m, "%-25s %-20s %-20s %-10s %-20s\n",
> +		   "Limit", "Soft Limit", "Hard Limit", "Units", "Max");

What existing programs, if any, does this break?

>
>  	for (i = 0; i < RLIM_NLIMITS; i++) {
>  		if (rlim[i].rlim_cur == RLIM_INFINITY)
> @@ -647,9 +647,11 @@ static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
>  			seq_printf(m, "%-20lu ", rlim[i].rlim_max);
>
>  		if (lnames[i].unit)
> -			seq_printf(m, "%-10s\n", lnames[i].unit);
> +			seq_printf(m, "%-10s", lnames[i].unit);
>  		else
> -			seq_putc(m, '\n');
> +			seq_printf(m, "%-10s", "");
> +		seq_printf(m, "%-20lu\n",
> +			   task->signal->rlim_curmax[i]);
>  	}
>
>  	return 0;
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 9c48a08..0150380 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -782,6 +782,7 @@ struct signal_struct {
>  	 * have no need to disable irqs.
>  	 */
>  	struct rlimit rlim[RLIM_NLIMITS];
> +	unsigned long rlim_curmax[RLIM_NLIMITS];
>
>  #ifdef CONFIG_BSD_PROCESS_ACCT
>  	struct pacct_struct pacct;	/* per-process accounting information */
> @@ -3376,6 +3377,12 @@ static inline unsigned long rlimit_max(unsigned int limit)
>  	return task_rlimit_max(current, limit);
>  }
>
> +static inline void bump_rlimit(unsigned int limit, unsigned long r)
> +{
> +	if (READ_ONCE(current->signal->rlim_curmax[limit]) < r)
> +		current->signal->rlim_curmax[limit] = r;
> +}
> +
>  #ifdef CONFIG_CPU_FREQ
>  struct update_util_data {
>  	void (*func)(struct update_util_data *data,
>

[toc] | [prev] | [next] | [standalone]


#1421338 — Re: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-13 23:20 +0200
SubjectRe: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max
Message-ID<rJHr3-3m2-19@gated-at.bofh.it>
In reply to#1421297
On 06/13/16 20:40, Andy Lutomirski wrote:
> On 06/13/2016 12:44 PM, Topi Miettinen wrote:
>> Track maximum number of files for the process, present current maximum
>> in /proc/self/limits.
> 
> The core part should be its own patch.
> 
> Also, you have this weirdly named (and racy!) function bump_rlimit.

I can change the name if you have better suggestions. rlimit_track_max?

The max value is written often but read seldom, if ever. What kind of
locking should I use then?

> Wouldn't this be nicer if you taught the rlimit code to track the
> *current* usage generically and to derive the max usage from that?

Current rlimit code performs checks against current limits. These are
typically done early in the calling function and further checks could
also fail. Thus max should not be updated until much later. Maybe these
could be combined, but not easily if at all.

> 
>> diff --git a/fs/proc/base.c b/fs/proc/base.c
>> index a11eb71..227997b 100644
>> --- a/fs/proc/base.c
>> +++ b/fs/proc/base.c
>> @@ -630,8 +630,8 @@ static int proc_pid_limits(struct seq_file *m,
>> struct pid_namespace *ns,
>>      /*
>>       * print the file header
>>       */
>> -       seq_printf(m, "%-25s %-20s %-20s %-10s\n",
>> -          "Limit", "Soft Limit", "Hard Limit", "Units");
>> +    seq_printf(m, "%-25s %-20s %-20s %-10s %-20s\n",
>> +           "Limit", "Soft Limit", "Hard Limit", "Units", "Max");
> 
> What existing programs, if any, does this break?

Using Debian codesearch for /limits" string, I'd check pam_limits and
rtkit. The max values could be put into a new file if you prefer.

> 
>>
>>      for (i = 0; i < RLIM_NLIMITS; i++) {
>>          if (rlim[i].rlim_cur == RLIM_INFINITY)
>> @@ -647,9 +647,11 @@ static int proc_pid_limits(struct seq_file *m,
>> struct pid_namespace *ns,
>>              seq_printf(m, "%-20lu ", rlim[i].rlim_max);
>>
>>          if (lnames[i].unit)
>> -            seq_printf(m, "%-10s\n", lnames[i].unit);
>> +            seq_printf(m, "%-10s", lnames[i].unit);
>>          else
>> -            seq_putc(m, '\n');
>> +            seq_printf(m, "%-10s", "");
>> +        seq_printf(m, "%-20lu\n",
>> +               task->signal->rlim_curmax[i]);
>>      }
>>
>>      return 0;
>> diff --git a/include/linux/sched.h b/include/linux/sched.h
>> index 9c48a08..0150380 100644
>> --- a/include/linux/sched.h
>> +++ b/include/linux/sched.h
>> @@ -782,6 +782,7 @@ struct signal_struct {
>>       * have no need to disable irqs.
>>       */
>>      struct rlimit rlim[RLIM_NLIMITS];
>> +    unsigned long rlim_curmax[RLIM_NLIMITS];
>>
>>  #ifdef CONFIG_BSD_PROCESS_ACCT
>>      struct pacct_struct pacct;    /* per-process accounting
>> information */
>> @@ -3376,6 +3377,12 @@ static inline unsigned long rlimit_max(unsigned
>> int limit)
>>      return task_rlimit_max(current, limit);
>>  }
>>
>> +static inline void bump_rlimit(unsigned int limit, unsigned long r)
>> +{
>> +    if (READ_ONCE(current->signal->rlim_curmax[limit]) < r)
>> +        current->signal->rlim_curmax[limit] = r;
>> +}
>> +
>>  #ifdef CONFIG_CPU_FREQ
>>  struct update_util_data {
>>      void (*func)(struct update_util_data *data,
>>
> 

[toc] | [prev] | [next] | [standalone]


#1421339 — Re: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max

FromAndy Lutomirski <luto@amacapital.net>
Date2016-06-13 23:20 +0200
SubjectRe: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max
Message-ID<rJHr3-3m2-23@gated-at.bofh.it>
In reply to#1421338
On Mon, Jun 13, 2016 at 2:13 PM, Topi Miettinen <toiwoton@gmail.com> wrote:
> On 06/13/16 20:40, Andy Lutomirski wrote:
>> On 06/13/2016 12:44 PM, Topi Miettinen wrote:
>>> Track maximum number of files for the process, present current maximum
>>> in /proc/self/limits.
>>
>> The core part should be its own patch.
>>
>> Also, you have this weirdly named (and racy!) function bump_rlimit.
>
> I can change the name if you have better suggestions. rlimit_track_max?
>
> The max value is written often but read seldom, if ever. What kind of
> locking should I use then?

Possibly none, but WRITE_ONCE would be good as would a comment
indicating that your code in intentionally racy.  Or you could use
atomic_cmpxchg if that won't kill performance.

rlimit_track_max sounds like a better name to me.

>
>> Wouldn't this be nicer if you taught the rlimit code to track the
>> *current* usage generically and to derive the max usage from that?
>
> Current rlimit code performs checks against current limits. These are
> typically done early in the calling function and further checks could
> also fail. Thus max should not be updated until much later. Maybe these
> could be combined, but not easily if at all.

I mean:  why not actually show the current value in /proc/pid/limits
and track the max via whatever teaches proc about the current value?

>
>>
>>> diff --git a/fs/proc/base.c b/fs/proc/base.c
>>> index a11eb71..227997b 100644
>>> --- a/fs/proc/base.c
>>> +++ b/fs/proc/base.c
>>> @@ -630,8 +630,8 @@ static int proc_pid_limits(struct seq_file *m,
>>> struct pid_namespace *ns,
>>>      /*
>>>       * print the file header
>>>       */
>>> -       seq_printf(m, "%-25s %-20s %-20s %-10s\n",
>>> -          "Limit", "Soft Limit", "Hard Limit", "Units");
>>> +    seq_printf(m, "%-25s %-20s %-20s %-10s %-20s\n",
>>> +           "Limit", "Soft Limit", "Hard Limit", "Units", "Max");
>>
>> What existing programs, if any, does this break?
>
> Using Debian codesearch for /limits" string, I'd check pam_limits and
> rtkit. The max values could be put into a new file if you prefer.

If it actually breaks them, then you need to change the patch so you
don't break them.

[toc] | [prev] | [next] | [standalone]


#1422018 — Re: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-14 17:30 +0200
SubjectRe: [RFC 05/18] limits: track and present RLIMIT_NOFILE actual max
Message-ID<rJYrU-6Cf-43@gated-at.bofh.it>
In reply to#1421339
On 06/13/16 21:16, Andy Lutomirski wrote:
> On Mon, Jun 13, 2016 at 2:13 PM, Topi Miettinen <toiwoton@gmail.com> wrote:
>> On 06/13/16 20:40, Andy Lutomirski wrote:
>>> On 06/13/2016 12:44 PM, Topi Miettinen wrote:
>>>> Track maximum number of files for the process, present current maximum
>>>> in /proc/self/limits.
>>>
>>> The core part should be its own patch.
>>>
>>> Also, you have this weirdly named (and racy!) function bump_rlimit.
>>
>> I can change the name if you have better suggestions. rlimit_track_max?
>>
>> The max value is written often but read seldom, if ever. What kind of
>> locking should I use then?
> 
> Possibly none, but WRITE_ONCE would be good as would a comment
> indicating that your code in intentionally racy.  Or you could use
> atomic_cmpxchg if that won't kill performance.
> 
> rlimit_track_max sounds like a better name to me.
> 
>>
>>> Wouldn't this be nicer if you taught the rlimit code to track the
>>> *current* usage generically and to derive the max usage from that?
>>
>> Current rlimit code performs checks against current limits. These are
>> typically done early in the calling function and further checks could
>> also fail. Thus max should not be updated until much later. Maybe these
>> could be combined, but not easily if at all.
> 
> I mean:  why not actually show the current value in /proc/pid/limits
> and track the max via whatever teaches proc about the current value?
> 

That could be interesting data too. In other comments, a new file was
proposed and then your model would be good choice.

>>
>>>
>>>> diff --git a/fs/proc/base.c b/fs/proc/base.c
>>>> index a11eb71..227997b 100644
>>>> --- a/fs/proc/base.c
>>>> +++ b/fs/proc/base.c
>>>> @@ -630,8 +630,8 @@ static int proc_pid_limits(struct seq_file *m,
>>>> struct pid_namespace *ns,
>>>>      /*
>>>>       * print the file header
>>>>       */
>>>> -       seq_printf(m, "%-25s %-20s %-20s %-10s\n",
>>>> -          "Limit", "Soft Limit", "Hard Limit", "Units");
>>>> +    seq_printf(m, "%-25s %-20s %-20s %-10s %-20s\n",
>>>> +           "Limit", "Soft Limit", "Hard Limit", "Units", "Max");
>>>
>>> What existing programs, if any, does this break?
>>
>> Using Debian codesearch for /limits" string, I'd check pam_limits and
>> rtkit. The max values could be put into a new file if you prefer.
> 
> If it actually breaks them, then you need to change the patch so you
> don't break them.
> 

[toc] | [prev] | [next] | [standalone]


#1421261 — [RFC 15/18] limits: track RLIMIT_MSGQUEUE actual max

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-13 21:50 +0200
Subject[RFC 15/18] limits: track RLIMIT_MSGQUEUE actual max
Message-ID<rJG1Y-2jr-25@gated-at.bofh.it>
In reply to#1421251
Track maximum size of message queues, presented in /proc/self/limits.

Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
---
 ipc/mqueue.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index ade739f..edccf55 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -287,6 +287,8 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
 
 		/* all is ok */
 		info->user = get_uid(u);
+		/* XXX resource limits apply per task, not per user */
+		bump_rlimit(RLIMIT_MSGQUEUE, u->mq_bytes);
 	} else if (S_ISDIR(mode)) {
 		inc_nlink(inode);
 		/* Some things misbehave if size == 0 on a directory */
-- 
2.8.1

[toc] | [prev] | [next] | [standalone]


#1425418 — Re: [RFC 15/18] limits: track RLIMIT_MSGQUEUE actual max

FromDoug Ledford <dledford@redhat.com>
Date2016-06-17 22:00 +0200
SubjectRe: [RFC 15/18] limits: track RLIMIT_MSGQUEUE actual max
Message-ID<rL85Q-2kS-43@gated-at.bofh.it>
In reply to#1421261

[Multipart message — attachments visible in raw view] — view raw

On 6/13/2016 3:44 PM, Topi Miettinen wrote:
> Track maximum size of message queues, presented in /proc/self/limits.
> 
> Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
> ---
>  ipc/mqueue.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/ipc/mqueue.c b/ipc/mqueue.c
> index ade739f..edccf55 100644
> --- a/ipc/mqueue.c
> +++ b/ipc/mqueue.c
> @@ -287,6 +287,8 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
>  
>  		/* all is ok */
>  		info->user = get_uid(u);
> +		/* XXX resource limits apply per task, not per user */
> +		bump_rlimit(RLIMIT_MSGQUEUE, u->mq_bytes);
>  	} else if (S_ISDIR(mode)) {
>  		inc_nlink(inode);
>  		/* Some things misbehave if size == 0 on a directory */
> 

This patch looks all sorts of wrong to me.

In a current linus tree I can't find a single instance of bump_rlimit.
Where is this magical function coming from?

Second, u->mq_bytes is the current size of all message queues for a
given user.  It is not per-task.  So your message about limits being
per-task is wrong (at least partially, the actual byte count is per-user
not per-task, but the limit we check when we create a new queue is
per-task and not per-user).  So your comment is wrong, the one
functional line you added appears to be a non-existent function, and
even if those two things are resolved, why in the world would the fact
that we created a new message queue mean we should bump our rlimit?
That makes no sense, because would *never* have a working rlimit any
more, we would simply increase our rlimit by the size of our existing
queues every time we made a queue.

This is just a totally broken patch.  Major NAK.

-- 
Doug Ledford <dledford@redhat.com>
    GPG Key ID: 0E572FDD

[toc] | [prev] | [next] | [standalone]


#1421262 — [RFC 06/18] limits: present RLIMIT_CPU and RLIMIT_RTTIMER current status

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-13 21:50 +0200
Subject[RFC 06/18] limits: present RLIMIT_CPU and RLIMIT_RTTIMER current status
Message-ID<rJG1Y-2jr-35@gated-at.bofh.it>
In reply to#1421251
Present current cputimer status in /proc/self/limits.

Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
---
 fs/proc/base.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 227997b..1df4fc8 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -650,8 +650,30 @@ static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
 			seq_printf(m, "%-10s", lnames[i].unit);
 		else
 			seq_printf(m, "%-10s", "");
-		seq_printf(m, "%-20lu\n",
-			   task->signal->rlim_curmax[i]);
+
+		switch (i) {
+		case RLIMIT_RTTIME:
+		case RLIMIT_CPU:
+			if (rlim[i].rlim_max == RLIM_INFINITY)
+				seq_printf(m, "%-20s\n", "-");
+			else {
+				unsigned long long utime, ptime;
+				unsigned long psecs;
+				struct task_cputime cputime;
+
+				thread_group_cputimer(task, &cputime);
+				utime = cputime_to_expires(cputime.utime);
+				ptime = utime + cputime_to_expires(cputime.stime);
+				psecs = cputime_to_secs(ptime);
+				if (i == RLIMIT_RTTIME)
+					psecs *= USEC_PER_SEC;
+				seq_printf(m, "%-20lu\n", psecs);
+			}
+			break;
+		default:
+			seq_printf(m, "%-20lu\n",
+				   task->signal->rlim_curmax[i]);
+		}
 	}
 
 	return 0;
-- 
2.8.1

[toc] | [prev] | [next] | [standalone]


#1421692 — Re: [RFC 06/18] limits: present RLIMIT_CPU and RLIMIT_RTTIMER current status

FromAlexey Dobriyan <adobriyan@gmail.com>
Date2016-06-14 11:20 +0200
SubjectRe: [RFC 06/18] limits: present RLIMIT_CPU and RLIMIT_RTTIMER current status
Message-ID<rJSFP-2Rh-7@gated-at.bofh.it>
In reply to#1421262
On Mon, Jun 13, 2016 at 10:44 PM, Topi Miettinen <toiwoton@gmail.com> wrote:
> Present current cputimer status in /proc/self/limits.

> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -650,8 +650,30 @@ static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
> +               switch (i) {
> +               case RLIMIT_RTTIME:
> +               case RLIMIT_CPU:
> +                       if (rlim[i].rlim_max == RLIM_INFINITY)
> +                               seq_printf(m, "%-20s\n", "-");
> +                       else {
> +                               unsigned long long utime, ptime;
> +                               unsigned long psecs;
> +                               struct task_cputime cputime;
> +
> +                               thread_group_cputimer(task, &cputime);
> +                               utime = cputime_to_expires(cputime.utime);
> +                               ptime = utime + cputime_to_expires(cputime.stime);
> +                               psecs = cputime_to_secs(ptime);
> +                               if (i == RLIMIT_RTTIME)
> +                                       psecs *= USEC_PER_SEC;
> +                               seq_printf(m, "%-20lu\n", psecs);
> +                       }
> +                       break;

Let's keep rlimits file for rlimits.

[toc] | [prev] | [next] | [standalone]


#1421265 — [RFC 11/18] limits: track and present RLIMIT_NPROC actual max

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-13 21:50 +0200
Subject[RFC 11/18] limits: track and present RLIMIT_NPROC actual max
Message-ID<rJG1Y-2jr-41@gated-at.bofh.it>
In reply to#1421251
Track maximum number of processes per user and present it
in /proc/self/limits.

Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
---
 fs/proc/base.c        | 4 ++++
 include/linux/sched.h | 1 +
 kernel/fork.c         | 5 +++++
 kernel/sys.c          | 5 +++++
 4 files changed, 15 insertions(+)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 1df4fc8..02576c6 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -670,6 +670,10 @@ static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
 				seq_printf(m, "%-20lu\n", psecs);
 			}
 			break;
+		case RLIMIT_NPROC:
+			seq_printf(m, "%-20d\n",
+				   atomic_read(&task->real_cred->user->max_processes));
+			break;
 		default:
 			seq_printf(m, "%-20lu\n",
 				   task->signal->rlim_curmax[i]);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 0150380..feb9bb7 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -838,6 +838,7 @@ static inline int signal_group_exit(const struct signal_struct *sig)
 struct user_struct {
 	atomic_t __count;	/* reference count */
 	atomic_t processes;	/* How many processes does this user have? */
+	atomic_t max_processes;	/* How many processes has this user had at the same time? */
 	atomic_t sigpending;	/* How many pending signals does this user have? */
 #ifdef CONFIG_INOTIFY_USER
 	atomic_t inotify_watches; /* How many inotify watches does this user have? */
diff --git a/kernel/fork.c b/kernel/fork.c
index 5c2c355..667290f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1653,6 +1653,11 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 	trace_task_newtask(p, clone_flags);
 	uprobe_copy_process(p, clone_flags);
 
+	if (atomic_read(&p->real_cred->user->max_processes) <
+	    atomic_read(&p->real_cred->user->processes))
+		atomic_set(&p->real_cred->user->max_processes,
+			   atomic_read(&p->real_cred->user->processes));
+
 	return p;
 
 bad_fork_cancel_cgroup:
diff --git a/kernel/sys.c b/kernel/sys.c
index 6629f6f..955cf21 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -439,6 +439,11 @@ static int set_user(struct cred *new)
 	else
 		current->flags &= ~PF_NPROC_EXCEEDED;
 
+	if (atomic_read(&new_user->max_processes) <
+	    atomic_read(&new_user->processes))
+		atomic_set(&new_user->max_processes,
+			   atomic_read(&new_user->processes));
+
 	free_uid(new->user);
 	new->user = new_user;
 	return 0;
-- 
2.8.1

[toc] | [prev] | [next] | [standalone]


#1421380 — Re: [RFC 11/18] limits: track and present RLIMIT_NPROC actual max

FromJann Horn <jann@thejh.net>
Date2016-06-14 00:30 +0200
SubjectRe: [RFC 11/18] limits: track and present RLIMIT_NPROC actual max
Message-ID<rJIwO-46h-31@gated-at.bofh.it>
In reply to#1421265

[Multipart message — attachments visible in raw view] — view raw

On Mon, Jun 13, 2016 at 10:44:18PM +0300, Topi Miettinen wrote:
> Track maximum number of processes per user and present it
> in /proc/self/limits.
> 
> Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
> ---
>  fs/proc/base.c        | 4 ++++
>  include/linux/sched.h | 1 +
>  kernel/fork.c         | 5 +++++
>  kernel/sys.c          | 5 +++++
>  4 files changed, 15 insertions(+)
> 
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index 1df4fc8..02576c6 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -670,6 +670,10 @@ static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
>  				seq_printf(m, "%-20lu\n", psecs);
>  			}
>  			break;
> +		case RLIMIT_NPROC:
> +			seq_printf(m, "%-20d\n",
> +				   atomic_read(&task->real_cred->user->max_processes));

Don't you have to take an RCU read lock before dereferencing task->real_cred?
And shouldn't this be done with __task_cred(task) instead of task->real_cred?


> +			break;
>  		default:
>  			seq_printf(m, "%-20lu\n",
>  				   task->signal->rlim_curmax[i]);
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 0150380..feb9bb7 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -838,6 +838,7 @@ static inline int signal_group_exit(const struct signal_struct *sig)
>  struct user_struct {
>  	atomic_t __count;	/* reference count */
>  	atomic_t processes;	/* How many processes does this user have? */
> +	atomic_t max_processes;	/* How many processes has this user had at the same time? */
>  	atomic_t sigpending;	/* How many pending signals does this user have? */
>  #ifdef CONFIG_INOTIFY_USER
>  	atomic_t inotify_watches; /* How many inotify watches does this user have? */
> diff --git a/kernel/fork.c b/kernel/fork.c
> index 5c2c355..667290f 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -1653,6 +1653,11 @@ static struct task_struct *copy_process(unsigned long clone_flags,
>  	trace_task_newtask(p, clone_flags);
>  	uprobe_copy_process(p, clone_flags);
>  
> +	if (atomic_read(&p->real_cred->user->max_processes) <
> +	    atomic_read(&p->real_cred->user->processes))
> +		atomic_set(&p->real_cred->user->max_processes,
> +			   atomic_read(&p->real_cred->user->processes));
> +
>  	return p;
>  
>  bad_fork_cancel_cgroup:
> diff --git a/kernel/sys.c b/kernel/sys.c
> index 6629f6f..955cf21 100644
> --- a/kernel/sys.c
> +++ b/kernel/sys.c
> @@ -439,6 +439,11 @@ static int set_user(struct cred *new)
>  	else
>  		current->flags &= ~PF_NPROC_EXCEEDED;
>  
> +	if (atomic_read(&new_user->max_processes) <
> +	    atomic_read(&new_user->processes))
> +		atomic_set(&new_user->max_processes,
> +			   atomic_read(&new_user->processes));
> +

Is this intentionally slightly racy? If so, it might be nice to have a comment
here that documents that.

[toc] | [prev] | [next] | [standalone]


#1422033 — Re: [RFC 11/18] limits: track and present RLIMIT_NPROC actual max

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-14 17:50 +0200
SubjectRe: [RFC 11/18] limits: track and present RLIMIT_NPROC actual max
Message-ID<rJYLg-6MM-25@gated-at.bofh.it>
In reply to#1421380
On 06/13/16 22:27, Jann Horn wrote:
> On Mon, Jun 13, 2016 at 10:44:18PM +0300, Topi Miettinen wrote:
>> Track maximum number of processes per user and present it
>> in /proc/self/limits.
>>
>> Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
>> ---
>>  fs/proc/base.c        | 4 ++++
>>  include/linux/sched.h | 1 +
>>  kernel/fork.c         | 5 +++++
>>  kernel/sys.c          | 5 +++++
>>  4 files changed, 15 insertions(+)
>>
>> diff --git a/fs/proc/base.c b/fs/proc/base.c
>> index 1df4fc8..02576c6 100644
>> --- a/fs/proc/base.c
>> +++ b/fs/proc/base.c
>> @@ -670,6 +670,10 @@ static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
>>  				seq_printf(m, "%-20lu\n", psecs);
>>  			}
>>  			break;
>> +		case RLIMIT_NPROC:
>> +			seq_printf(m, "%-20d\n",
>> +				   atomic_read(&task->real_cred->user->max_processes));
> 
> Don't you have to take an RCU read lock before dereferencing task->real_cred?

In other comments in the series, cmpxchg loop was suggested, would that
work here?

> And shouldn't this be done with __task_cred(task) instead of task->real_cred?

How about atomic_read(task_cred_xxx(task, user)->max_processes)?

> 
> 
>> +			break;
>>  		default:
>>  			seq_printf(m, "%-20lu\n",
>>  				   task->signal->rlim_curmax[i]);
>> diff --git a/include/linux/sched.h b/include/linux/sched.h
>> index 0150380..feb9bb7 100644
>> --- a/include/linux/sched.h
>> +++ b/include/linux/sched.h
>> @@ -838,6 +838,7 @@ static inline int signal_group_exit(const struct signal_struct *sig)
>>  struct user_struct {
>>  	atomic_t __count;	/* reference count */
>>  	atomic_t processes;	/* How many processes does this user have? */
>> +	atomic_t max_processes;	/* How many processes has this user had at the same time? */
>>  	atomic_t sigpending;	/* How many pending signals does this user have? */
>>  #ifdef CONFIG_INOTIFY_USER
>>  	atomic_t inotify_watches; /* How many inotify watches does this user have? */
>> diff --git a/kernel/fork.c b/kernel/fork.c
>> index 5c2c355..667290f 100644
>> --- a/kernel/fork.c
>> +++ b/kernel/fork.c
>> @@ -1653,6 +1653,11 @@ static struct task_struct *copy_process(unsigned long clone_flags,
>>  	trace_task_newtask(p, clone_flags);
>>  	uprobe_copy_process(p, clone_flags);
>>  
>> +	if (atomic_read(&p->real_cred->user->max_processes) <
>> +	    atomic_read(&p->real_cred->user->processes))
>> +		atomic_set(&p->real_cred->user->max_processes,
>> +			   atomic_read(&p->real_cred->user->processes));
>> +
>>  	return p;
>>  
>>  bad_fork_cancel_cgroup:
>> diff --git a/kernel/sys.c b/kernel/sys.c
>> index 6629f6f..955cf21 100644
>> --- a/kernel/sys.c
>> +++ b/kernel/sys.c
>> @@ -439,6 +439,11 @@ static int set_user(struct cred *new)
>>  	else
>>  		current->flags &= ~PF_NPROC_EXCEEDED;
>>  
>> +	if (atomic_read(&new_user->max_processes) <
>> +	    atomic_read(&new_user->processes))
>> +		atomic_set(&new_user->max_processes,
>> +			   atomic_read(&new_user->processes));
>> +
> 
> Is this intentionally slightly racy? If so, it might be nice to have a comment
> here that documents that.
> 

I'd suppose cmpxchg loop could be used to avoid races.

-Topi

[toc] | [prev] | [next] | [standalone]


#1422448 — Re: [RFC 11/18] limits: track and present RLIMIT_NPROC actual max

FromJann Horn <jann@thejh.net>
Date2016-06-15 01:20 +0200
SubjectRe: [RFC 11/18] limits: track and present RLIMIT_NPROC actual max
Message-ID<rK5MJ-2ZU-1@gated-at.bofh.it>
In reply to#1422033

[Multipart message — attachments visible in raw view] — view raw

On Tue, Jun 14, 2016 at 03:40:35PM +0000, Topi Miettinen wrote:
> On 06/13/16 22:27, Jann Horn wrote:
> > On Mon, Jun 13, 2016 at 10:44:18PM +0300, Topi Miettinen wrote:
> >> Track maximum number of processes per user and present it
> >> in /proc/self/limits.
> >>
> >> Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
> >> ---
> >>  fs/proc/base.c        | 4 ++++
> >>  include/linux/sched.h | 1 +
> >>  kernel/fork.c         | 5 +++++
> >>  kernel/sys.c          | 5 +++++
> >>  4 files changed, 15 insertions(+)
> >>
> >> diff --git a/fs/proc/base.c b/fs/proc/base.c
> >> index 1df4fc8..02576c6 100644
> >> --- a/fs/proc/base.c
> >> +++ b/fs/proc/base.c
> >> @@ -670,6 +670,10 @@ static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
> >>  				seq_printf(m, "%-20lu\n", psecs);
> >>  			}
> >>  			break;
> >> +		case RLIMIT_NPROC:
> >> +			seq_printf(m, "%-20d\n",
> >> +				   atomic_read(&task->real_cred->user->max_processes));
> > 
> > Don't you have to take an RCU read lock before dereferencing task->real_cred?
> 
> In other comments in the series, cmpxchg loop was suggested, would that
> work here?

What would a cmpxchg loop have to do with missing RCU locking?

> > And shouldn't this be done with __task_cred(task) instead of task->real_cred?
> 
> How about atomic_read(task_cred_xxx(task, user)->max_processes)?

No. You'd still end up dereferencing max_processes in the user_struct without
any guarantee that it hasn't been freed. I think the code should look this way:

    case RLIMIT_NPROC:
        rcu_read_lock();
        seq_printf(m, "%-20d\n",
            atomic_read(&__task_cred(task)->user->max_processes));
        rcu_read_unlock();
        break;

[toc] | [prev] | [next] | [standalone]


#1421266 — [RFC 17/18] limits: track RLIMIT_RTPRIO actual max

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-13 21:50 +0200
Subject[RFC 17/18] limits: track RLIMIT_RTPRIO actual max
Message-ID<rJG1Y-2jr-45@gated-at.bofh.it>
In reply to#1421251
Track maximum RT priority, presented in /proc/self/limits.

Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
---
 kernel/sched/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 817d720..d31a06a 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4219,6 +4219,8 @@ change:
 	balance_callback(rq);
 	preempt_enable();
 
+	task_bump_rlimit(p, RLIMIT_RTPRIO, attr->sched_priority);
+
 	return 0;
 }
 
-- 
2.8.1

[toc] | [prev] | [next] | [standalone]


#1421267 — [RFC 04/18] device_cgroup: track and present accessed devices

FromTopi Miettinen <toiwoton@gmail.com>
Date2016-06-13 21:50 +0200
Subject[RFC 04/18] device_cgroup: track and present accessed devices
Message-ID<rJG1Y-2jr-47@gated-at.bofh.it>
In reply to#1421251
Track what devices are accessed and present them cgroup devices.accessed.

Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
---
 security/device_cgroup.c | 70 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 60 insertions(+), 10 deletions(-)

diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 03c1652..45aa730 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -48,6 +48,7 @@ struct dev_exception_item {
 struct dev_cgroup {
 	struct cgroup_subsys_state css;
 	struct list_head exceptions;
+	struct list_head accessed;
 	enum devcg_behavior behavior;
 };
 
@@ -90,7 +91,7 @@ free_and_exit:
 /*
  * called under devcgroup_mutex
  */
-static int dev_exception_add(struct dev_cgroup *dev_cgroup,
+static int dev_exception_add(struct list_head *exceptions,
 			     struct dev_exception_item *ex)
 {
 	struct dev_exception_item *excopy, *walk;
@@ -101,7 +102,7 @@ static int dev_exception_add(struct dev_cgroup *dev_cgroup,
 	if (!excopy)
 		return -ENOMEM;
 
-	list_for_each_entry(walk, &dev_cgroup->exceptions, list) {
+	list_for_each_entry(walk, exceptions, list) {
 		if (walk->type != ex->type)
 			continue;
 		if (walk->major != ex->major)
@@ -115,7 +116,7 @@ static int dev_exception_add(struct dev_cgroup *dev_cgroup,
 	}
 
 	if (excopy != NULL)
-		list_add_tail_rcu(&excopy->list, &dev_cgroup->exceptions);
+		list_add_tail_rcu(&excopy->list, exceptions);
 	return 0;
 }
 
@@ -155,6 +156,16 @@ static void __dev_exception_clean(struct dev_cgroup *dev_cgroup)
 	}
 }
 
+static void dev_accessed_clean(struct dev_cgroup *dev_cgroup)
+{
+	struct dev_exception_item *ex, *tmp;
+
+	list_for_each_entry_safe(ex, tmp, &dev_cgroup->accessed, list) {
+		list_del_rcu(&ex->list);
+		kfree_rcu(ex, rcu);
+	}
+}
+
 /**
  * dev_exception_clean - frees all entries of the exception list
  * @dev_cgroup: dev_cgroup with the exception list to be cleaned
@@ -221,6 +232,7 @@ devcgroup_css_alloc(struct cgroup_subsys_state *parent_css)
 	if (!dev_cgroup)
 		return ERR_PTR(-ENOMEM);
 	INIT_LIST_HEAD(&dev_cgroup->exceptions);
+	INIT_LIST_HEAD(&dev_cgroup->accessed);
 	dev_cgroup->behavior = DEVCG_DEFAULT_NONE;
 
 	return &dev_cgroup->css;
@@ -231,6 +243,7 @@ static void devcgroup_css_free(struct cgroup_subsys_state *css)
 	struct dev_cgroup *dev_cgroup = css_to_devcgroup(css);
 
 	__dev_exception_clean(dev_cgroup);
+	dev_accessed_clean(dev_cgroup);
 	kfree(dev_cgroup);
 }
 
@@ -272,9 +285,9 @@ static void set_majmin(char *str, unsigned m)
 		sprintf(str, "%u", m);
 }
 
-static int devcgroup_seq_show(struct seq_file *m, void *v)
+static int devcgroup_seq_show_list(struct seq_file *m, struct dev_cgroup *devcgroup,
+				   struct list_head *exceptions, bool allow)
 {
-	struct dev_cgroup *devcgroup = css_to_devcgroup(seq_css(m));
 	struct dev_exception_item *ex;
 	char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN];
 
@@ -285,14 +298,14 @@ static int devcgroup_seq_show(struct seq_file *m, void *v)
 	 * - List the exceptions in case the default policy is to deny
 	 * This way, the file remains as a "whitelist of devices"
 	 */
-	if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) {
+	if (allow) {
 		set_access(acc, ACC_MASK);
 		set_majmin(maj, ~0);
 		set_majmin(min, ~0);
 		seq_printf(m, "%c %s:%s %s\n", type_to_char(DEV_ALL),
 			   maj, min, acc);
 	} else {
-		list_for_each_entry_rcu(ex, &devcgroup->exceptions, list) {
+		list_for_each_entry_rcu(ex, exceptions, list) {
 			set_access(acc, ex->access);
 			set_majmin(maj, ex->major);
 			set_majmin(min, ex->minor);
@@ -305,6 +318,36 @@ static int devcgroup_seq_show(struct seq_file *m, void *v)
 	return 0;
 }
 
+static int devcgroup_seq_show(struct seq_file *m, void *v)
+{
+	struct dev_cgroup *devcgroup = css_to_devcgroup(seq_css(m));
+
+	return devcgroup_seq_show_list(m, devcgroup, &devcgroup->exceptions,
+				       devcgroup->behavior == DEVCG_DEFAULT_ALLOW);
+}
+
+static int devcgroup_seq_show_accessed(struct seq_file *m, void *v)
+{
+	struct dev_cgroup *devcgroup = css_to_devcgroup(seq_css(m));
+
+	return devcgroup_seq_show_list(m, devcgroup, &devcgroup->accessed, false);
+}
+
+static void devcgroup_add_accessed(struct dev_cgroup *dev_cgroup, short type,
+				   u32 major, u32 minor, short access)
+{
+	struct dev_exception_item ex;
+
+	ex.type = type;
+	ex.major = major;
+	ex.minor = minor;
+	ex.access = access;
+
+	mutex_lock(&devcgroup_mutex);
+	dev_exception_add(&dev_cgroup->accessed, &ex);
+	mutex_unlock(&devcgroup_mutex);
+}
+
 /**
  * match_exception	- iterates the exception list trying to find a complete match
  * @exceptions: list of exceptions
@@ -566,7 +609,7 @@ static int propagate_exception(struct dev_cgroup *devcg_root,
 		 */
 		if (devcg_root->behavior == DEVCG_DEFAULT_ALLOW &&
 		    devcg->behavior == DEVCG_DEFAULT_ALLOW) {
-			rc = dev_exception_add(devcg, ex);
+			rc = dev_exception_add(&devcg->exceptions, ex);
 			if (rc)
 				break;
 		} else {
@@ -736,7 +779,7 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
 
 		if (!parent_has_perm(devcgroup, &ex))
 			return -EPERM;
-		rc = dev_exception_add(devcgroup, &ex);
+		rc = dev_exception_add(&devcgroup->exceptions, &ex);
 		break;
 	case DEVCG_DENY:
 		/*
@@ -747,7 +790,7 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
 		if (devcgroup->behavior == DEVCG_DEFAULT_DENY)
 			dev_exception_rm(devcgroup, &ex);
 		else
-			rc = dev_exception_add(devcgroup, &ex);
+			rc = dev_exception_add(&devcgroup->exceptions, &ex);
 
 		if (rc)
 			break;
@@ -788,6 +831,11 @@ static struct cftype dev_cgroup_files[] = {
 		.seq_show = devcgroup_seq_show,
 		.private = DEVCG_LIST,
 	},
+	{
+		.name = "accessed",
+		.seq_show = devcgroup_seq_show_accessed,
+		.private = DEVCG_LIST,
+	},
 	{ }	/* terminate */
 };
 
@@ -830,6 +878,8 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor,
 	if (!rc)
 		return -EPERM;
 
+	devcgroup_add_accessed(dev_cgroup, type, major, minor, access);
+
 	return 0;
 }
 
-- 
2.8.1

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | linux.kernel


csiph-web