linux-api.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* + prctl-add-pr_set_proctitle_area-option-for-prctl.patch added to -mm tree
@ 2009-12-30 23:23 akpm
       [not found] ` <200912302323.nBUNNsGv008033-AB4EexQrvXRQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: akpm @ 2009-12-30 23:23 UTC (permalink / raw)
  To: mm-commits
  Cc: kosaki.motohiro, bdonlan, drepper, linux-api, mingo, oleg, tss,
	xiyou.wangcong


The patch titled
     prctl: add PR_SET_PROCTITLE_AREA option for prctl()
has been added to the -mm tree.  Its filename is
     prctl-add-pr_set_proctitle_area-option-for-prctl.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://userweb.kernel.org/~akpm/stuff/added-to-mm.txt to find
out what to do about this

The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/

------------------------------------------------------
Subject: prctl: add PR_SET_PROCTITLE_AREA option for prctl()
From: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>

Currently glibc2 doesn't have setproctitle(3), so several userland daemons
attempt to emulate it by doing some brutal stack modifications.  This
works most of the time, but it has problems.  For example:

 % ps -ef |grep avahi-daemon
 avahi     1679     1  0 09:20 ?        00:00:00 avahi-daemon: running [kosadesk.local]

 # cat /proc/1679/cmdline
 avahi-daemon: running [kosadesk.local]

This looks good, but the process has also overwritten its environment area
and made the environ file useless:

 # cat /proc/1679/environ
 adesk.local]

Another problem is that the process title length is limited by the size of
the environment.  Security conscious people try to avoid potential
information leaks by clearing most of the environment before running a
daemon:

 # env - MINIMUM_NEEDED_VAR=foo /path/to/daemon

The resulting environment size may be too small to fit the wanted process
titles.

This patch makes it possible for userspace to implement setproctitle()
cleanly.  It adds a new PR_SET_PROCTITLE_AREA option for prctl(), which
updates task's mm_struct->arg_start and arg_end to the given area.

 test_setproctitle.c
 ================================================
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <sys/prctl.h>

 #define ERR(str) (perror(str), exit(1))

 void settitle(char* title){
         int err;

         err = prctl(35, title, strlen(title)+1);
         if (err < 0)
                 ERR("prctl ");
 }

 void main(void){
         long i;
         char buf[1024];

         for (i = 0; i < 10000000000LL; i++){
                 sprintf(buf, "loooooooooooooooooooooooong string %d",i);
                 settitle(buf);
         }
 }
 ==================================================

Cc: Bryan Donlan <bdonlan@gmail.com>
Cc: Ulrich Drepper <drepper@redhat.com>
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: Timo Sirainen <tss@iki.fi>
Cc: WANG Cong <xiyou.wangcong@gmail.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: <linux-api@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 fs/proc/base.c        |   39 +++++++++++++++++++++++++++++----------
 include/linux/mm.h    |    2 ++
 include/linux/prctl.h |    3 +++
 kernel/sys.c          |   26 ++++++++++++++++++++++++++
 mm/memory.c           |   40 +++++++++++++++++++++++++++-------------
 5 files changed, 87 insertions(+), 23 deletions(-)

diff -puN fs/proc/base.c~prctl-add-pr_set_proctitle_area-option-for-prctl fs/proc/base.c
--- a/fs/proc/base.c~prctl-add-pr_set_proctitle_area-option-for-prctl
+++ a/fs/proc/base.c
@@ -255,34 +255,53 @@ static int proc_pid_cmdline(struct task_
 	int res = 0;
 	unsigned int len;
 	struct mm_struct *mm = get_task_mm(task);
+
 	if (!mm)
 		goto out;
+
+	/* The process was not constructed yet? */
 	if (!mm->arg_end)
 		goto out_mm;	/* Shh! No looking before we're done */
 
- 	len = mm->arg_end - mm->arg_start;
- 
+	down_read(&mm->mmap_sem);
+	len = mm->arg_end - mm->arg_start;
 	if (len > PAGE_SIZE)
 		len = PAGE_SIZE;
- 
-	res = access_process_vm(task, mm->arg_start, buffer, len, 0);
 
-	// If the nul at the end of args has been overwritten, then
-	// assume application is using setproctitle(3).
+	res = access_process_vm_locked(task, mm, mm->arg_start, buffer, len, 0);
+
+	/*
+	 * If argv and environ aren't continuous (i.e. the process used
+	 * prctl(PR_SET_PROCTITLE_AREA)), we don't care about the evironment
+	 * override.
+	 */
+	if (mm->arg_end != mm->env_start)
+		goto out_unlock;
+
+	/*
+	 * If the nul at the end of args has been overwritten, then assume
+	 * application is using sendmail's SPT_REUSEARGV style argv override.
+	 */
 	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
 		len = strnlen(buffer, res);
-		if (len < res) {
-		    res = len;
-		} else {
+		if (len < res)
+			res = len;
+		else {
 			len = mm->env_end - mm->env_start;
 			if (len > PAGE_SIZE - res)
 				len = PAGE_SIZE - res;
-			res += access_process_vm(task, mm->env_start, buffer+res, len, 0);
+			res += access_process_vm_locked(task, mm, mm->env_start,
+							buffer+res, len, 0);
 			res = strnlen(buffer, res);
 		}
 	}
+
+out_unlock:
+	up_read(&mm->mmap_sem);
+
 out_mm:
 	mmput(mm);
+
 out:
 	return res;
 }
diff -puN include/linux/mm.h~prctl-add-pr_set_proctitle_area-option-for-prctl include/linux/mm.h
--- a/include/linux/mm.h~prctl-add-pr_set_proctitle_area-option-for-prctl
+++ a/include/linux/mm.h
@@ -841,6 +841,8 @@ static inline int handle_mm_fault(struct
 
 extern int make_pages_present(unsigned long addr, unsigned long end);
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
+extern int access_process_vm_locked(struct task_struct *tsk, struct mm_struct *mm,
+				    unsigned long addr, void *buf, int len, int write);
 
 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 			unsigned long start, int nr_pages, int write, int force,
diff -puN include/linux/prctl.h~prctl-add-pr_set_proctitle_area-option-for-prctl include/linux/prctl.h
--- a/include/linux/prctl.h~prctl-add-pr_set_proctitle_area-option-for-prctl
+++ a/include/linux/prctl.h
@@ -102,4 +102,7 @@
 
 #define PR_MCE_KILL_GET 34
 
+/* Set process title memory area for setproctitle() */
+#define PR_SET_PROCTITLE_AREA 35
+
 #endif /* _LINUX_PRCTL_H */
diff -puN kernel/sys.c~prctl-add-pr_set_proctitle_area-option-for-prctl kernel/sys.c
--- a/kernel/sys.c~prctl-add-pr_set_proctitle_area-option-for-prctl
+++ a/kernel/sys.c
@@ -1683,6 +1683,32 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
 			else
 				error = PR_MCE_KILL_DEFAULT;
 			break;
+		case PR_SET_PROCTITLE_AREA: {
+			struct mm_struct *mm = current->mm;
+			unsigned long start = arg2;
+			unsigned long len = arg3;
+			unsigned long end = start + len;
+
+			if (len > PAGE_SIZE)
+				return -EINVAL;
+
+			/*
+			 * If the process pass broken pointer, EFAULT is might better
+			 * than ps output zero-length proctitle. Plus if
+			 * the process pass kernel address (or something-else),
+			 * We have to block it. Oherwise, strange exploit
+			 * chance is there.
+			 */
+			if (!access_ok(VERIFY_READ, start, len))
+				return -EFAULT;
+
+			down_write(&mm->mmap_sem);
+			mm->arg_start = start;
+			mm->arg_end = end;
+			up_write(&mm->mmap_sem);
+
+			return 0;
+		}
 		default:
 			error = -EINVAL;
 			break;
diff -puN mm/memory.c~prctl-add-pr_set_proctitle_area-option-for-prctl mm/memory.c
--- a/mm/memory.c~prctl-add-pr_set_proctitle_area-option-for-prctl
+++ a/mm/memory.c
@@ -3415,22 +3415,13 @@ int generic_access_phys(struct vm_area_s
 }
 #endif
 
-/*
- * Access another process' address space.
- * Source/target buffer must be kernel space,
- * Do not walk the page table directly, use get_user_pages
- */
-int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+/* Similar to access_process_vm(), but mmap_sem held is required. */
+int access_process_vm_locked(struct task_struct *tsk, struct mm_struct *mm,
+			     unsigned long addr, void *buf, int len, int write)
 {
-	struct mm_struct *mm;
 	struct vm_area_struct *vma;
 	void *old_buf = buf;
 
-	mm = get_task_mm(tsk);
-	if (!mm)
-		return 0;
-
-	down_read(&mm->mmap_sem);
 	/* ignore errors, just check how much was successfully transferred */
 	while (len) {
 		int bytes, ret, offset;
@@ -3477,10 +3468,33 @@ int access_process_vm(struct task_struct
 		buf += bytes;
 		addr += bytes;
 	}
+
+	return buf - old_buf;
+}
+
+/*
+ * Access another process' address space.
+ * Source/target buffer must be kernel space,
+ * Do not walk the page table directly, use get_user_pages
+ * ignore errors, just check how much was successfully transferred. IOW, this
+ * function always return >=0 value.
+ */
+int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+{
+	int ret;
+	struct mm_struct *mm;
+
+	/* Probably tsk isn't current. We can't access tsk->mm directly. */
+	mm = get_task_mm(tsk);
+	if (!mm)
+		return 0;
+
+	down_read(&mm->mmap_sem);
+	ret = access_process_vm_locked(tsk, mm, addr, buf, len, write);
 	up_read(&mm->mmap_sem);
 	mmput(mm);
 
-	return buf - old_buf;
+	return ret;
 }
 
 /*
_

Patches currently in -mm which might be from kosaki.motohiro@jp.fujitsu.com are

mm-introduce-dump_page-and-print-symbolic-flag-names.patch
prctl-add-pr_set_proctitle_area-option-for-prctl.patch
mm-pass-mm-flags-as-a-coredump-parameter-for-consistency.patch
fs-symlink-write_begin-allocation-context-fix-reiser4-fix.patch


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: + prctl-add-pr_set_proctitle_area-option-for-prctl.patch added to -mm tree
       [not found] ` <200912302323.nBUNNsGv008033-AB4EexQrvXRQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org>
@ 2010-01-15 23:16   ` H. Peter Anvin
       [not found]     ` <4B50F74F.2060608-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: H. Peter Anvin @ 2010-01-15 23:16 UTC (permalink / raw)
  To: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b
  Cc: mm-commits-u79uwXL29TY76Z2rM5mHXA,
	kosaki.motohiro-+CUm20s59erQFUHtdCDX3A,
	bdonlan-Re5JQEeQqe8AvxtiuMwx3w, drepper-H+wXaHxf7aLQT0dZR+AlfA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, mingo-X9Un+BFzKDI,
	oleg-H+wXaHxf7aLQT0dZR+AlfA, tss-X3B1VOXEql0,
	xiyou.wangcong-Re5JQEeQqe8AvxtiuMwx3w

On 12/30/2009 03:23 PM, akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org wrote:
> ------------------------------------------------------
> Subject: prctl: add PR_SET_PROCTITLE_AREA option for prctl()
> From: KOSAKI Motohiro <kosaki.motohiro-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
> 
> Currently glibc2 doesn't have setproctitle(3), so several userland daemons
> attempt to emulate it by doing some brutal stack modifications.  This
> works most of the time, but it has problems.  For example:
> 
>  % ps -ef |grep avahi-daemon
>  avahi     1679     1  0 09:20 ?        00:00:00 avahi-daemon: running [kosadesk.local]
> 
>  # cat /proc/1679/cmdline
>  avahi-daemon: running [kosadesk.local]
> 
> This looks good, but the process has also overwritten its environment area
> and made the environ file useless:
> 
>  # cat /proc/1679/environ
>  adesk.local]
> 
> Another problem is that the process title length is limited by the size of
> the environment.  Security conscious people try to avoid potential
> information leaks by clearing most of the environment before running a
> daemon:
> 
>  # env - MINIMUM_NEEDED_VAR=foo /path/to/daemon
> 
> The resulting environment size may be too small to fit the wanted process
> titles.
> 
> This patch makes it possible for userspace to implement setproctitle()
> cleanly.  It adds a new PR_SET_PROCTITLE_AREA option for prctl(), which
> updates task's mm_struct->arg_start and arg_end to the given area.
> 

Sorry for the late feedback...

On the subject of this patch: would it also make sense to have a prctl()
to give the kernel the address of the "environ" variable, so that
/proc/*/environ can give the *current* environment inside the process
(which is otherwise strictly a user-space matter) as opposed to the
initial environment passed by the kernel (unless modified in-place)?

	-hpa

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: + prctl-add-pr_set_proctitle_area-option-for-prctl.patch added to -mm tree
       [not found]     ` <4B50F74F.2060608-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
@ 2010-01-18  0:56       ` KOSAKI Motohiro
       [not found]         ` <20100118093413.AE1C.A69D9226-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: KOSAKI Motohiro @ 2010-01-18  0:56 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: kosaki.motohiro-+CUm20s59erQFUHtdCDX3A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mm-commits-u79uwXL29TY76Z2rM5mHXA, bdonlan-Re5JQEeQqe8AvxtiuMwx3w,
	drepper-H+wXaHxf7aLQT0dZR+AlfA, linux-api-u79uwXL29TY76Z2rM5mHXA,
	mingo-X9Un+BFzKDI, oleg-H+wXaHxf7aLQT0dZR+AlfA, tss-X3B1VOXEql0,
	xiyou.wangcong-Re5JQEeQqe8AvxtiuMwx3w

> On 12/30/2009 03:23 PM, akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org wrote:
> > ------------------------------------------------------
> > Subject: prctl: add PR_SET_PROCTITLE_AREA option for prctl()
> > From: KOSAKI Motohiro <kosaki.motohiro-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
> > 
> > Currently glibc2 doesn't have setproctitle(3), so several userland daemons
> > attempt to emulate it by doing some brutal stack modifications.  This
> > works most of the time, but it has problems.  For example:
> > 
> >  % ps -ef |grep avahi-daemon
> >  avahi     1679     1  0 09:20 ?        00:00:00 avahi-daemon: running [kosadesk.local]
> > 
> >  # cat /proc/1679/cmdline
> >  avahi-daemon: running [kosadesk.local]
> > 
> > This looks good, but the process has also overwritten its environment area
> > and made the environ file useless:
> > 
> >  # cat /proc/1679/environ
> >  adesk.local]
> > 
> > Another problem is that the process title length is limited by the size of
> > the environment.  Security conscious people try to avoid potential
> > information leaks by clearing most of the environment before running a
> > daemon:
> > 
> >  # env - MINIMUM_NEEDED_VAR=foo /path/to/daemon
> > 
> > The resulting environment size may be too small to fit the wanted process
> > titles.
> > 
> > This patch makes it possible for userspace to implement setproctitle()
> > cleanly.  It adds a new PR_SET_PROCTITLE_AREA option for prctl(), which
> > updates task's mm_struct->arg_start and arg_end to the given area.
> > 
> 
> Sorry for the late feedback...
> 
> On the subject of this patch: would it also make sense to have a prctl()
> to give the kernel the address of the "environ" variable, so that
> /proc/*/environ can give the *current* environment inside the process
> (which is otherwise strictly a user-space matter) as opposed to the
> initial environment passed by the kernel (unless modified in-place)?

Thank you good comments! 
I have two comments.

1 Yes, to change /proc/*/environ makes lots sense. probably.
  My last worry is, If security aware daemon want to hide environment intentionally,
  it should be able to do. iow, automatical environ area finding seems bad. 
  probably we need new prctl or new syscall.
2 this prctl is intend to the base of implement setproctitle() libc function. libc5 had it, but glibc2
   lost it.  few month ago, imap daemon devepler wanted to implement its function in
   libc-alpha. and I've hear similar requreiment sometimes. then I added this. correct 
  setproctitle() require this patch.
   plus, lots application have #ifdef HAVE_SETPROCTITLE configuration already. iow, 
   this patch don't require application change. it only require libc change.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: + prctl-add-pr_set_proctitle_area-option-for-prctl.patch added to -mm tree
       [not found]         ` <20100118093413.AE1C.A69D9226-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
@ 2010-01-18  1:46           ` H. Peter Anvin
       [not found]             ` <4B53BD61.9040609-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: H. Peter Anvin @ 2010-01-18  1:46 UTC (permalink / raw)
  To: KOSAKI Motohiro
  Cc: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mm-commits-u79uwXL29TY76Z2rM5mHXA, bdonlan-Re5JQEeQqe8AvxtiuMwx3w,
	drepper-H+wXaHxf7aLQT0dZR+AlfA, linux-api-u79uwXL29TY76Z2rM5mHXA,
	mingo-X9Un+BFzKDI, oleg-H+wXaHxf7aLQT0dZR+AlfA, tss-X3B1VOXEql0,
	xiyou.wangcong-Re5JQEeQqe8AvxtiuMwx3w

On 01/17/2010 04:56 PM, KOSAKI Motohiro wrote:
>>
>> Sorry for the late feedback...
>>
>> On the subject of this patch: would it also make sense to have a prctl()
>> to give the kernel the address of the "environ" variable, so that
>> /proc/*/environ can give the *current* environment inside the process
>> (which is otherwise strictly a user-space matter) as opposed to the
>> initial environment passed by the kernel (unless modified in-place)?
> 
> Thank you good comments! 
> I have two comments.
> 
> 1 Yes, to change /proc/*/environ makes lots sense. probably.
>   My last worry is, If security aware daemon want to hide environment intentionally,
>   it should be able to do. iow, automatical environ area finding seems bad. 
>   probably we need new prctl or new syscall.

Finding environ automatically is not only bad, but totally impractical
(how would the kernel know where environ is?)  However, libc could
invoke a prctl to point the kernel at environ.

	-hpa

-- 
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel.  I don't speak on their behalf.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: + prctl-add-pr_set_proctitle_area-option-for-prctl.patch added to -mm tree
       [not found]             ` <4B53BD61.9040609-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
@ 2010-01-18  1:48               ` KOSAKI Motohiro
  0 siblings, 0 replies; 5+ messages in thread
From: KOSAKI Motohiro @ 2010-01-18  1:48 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: kosaki.motohiro-+CUm20s59erQFUHtdCDX3A,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mm-commits-u79uwXL29TY76Z2rM5mHXA, bdonlan-Re5JQEeQqe8AvxtiuMwx3w,
	drepper-H+wXaHxf7aLQT0dZR+AlfA, linux-api-u79uwXL29TY76Z2rM5mHXA,
	mingo-X9Un+BFzKDI, oleg-H+wXaHxf7aLQT0dZR+AlfA, tss-X3B1VOXEql0,
	xiyou.wangcong-Re5JQEeQqe8AvxtiuMwx3w

> On 01/17/2010 04:56 PM, KOSAKI Motohiro wrote:
> >>
> >> Sorry for the late feedback...
> >>
> >> On the subject of this patch: would it also make sense to have a prctl()
> >> to give the kernel the address of the "environ" variable, so that
> >> /proc/*/environ can give the *current* environment inside the process
> >> (which is otherwise strictly a user-space matter) as opposed to the
> >> initial environment passed by the kernel (unless modified in-place)?
> > 
> > Thank you good comments! 
> > I have two comments.
> > 
> > 1 Yes, to change /proc/*/environ makes lots sense. probably.
> >   My last worry is, If security aware daemon want to hide environment intentionally,
> >   it should be able to do. iow, automatical environ area finding seems bad. 
> >   probably we need new prctl or new syscall.
> 
> Finding environ automatically is not only bad, but totally impractical
> (how would the kernel know where environ is?)  However, libc could
> invoke a prctl to point the kernel at environ.

Sure. okey, I'm prepare such new prctl.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-01-18  1:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-30 23:23 + prctl-add-pr_set_proctitle_area-option-for-prctl.patch added to -mm tree akpm
     [not found] ` <200912302323.nBUNNsGv008033-AB4EexQrvXRQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org>
2010-01-15 23:16   ` H. Peter Anvin
     [not found]     ` <4B50F74F.2060608-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
2010-01-18  0:56       ` KOSAKI Motohiro
     [not found]         ` <20100118093413.AE1C.A69D9226-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
2010-01-18  1:46           ` H. Peter Anvin
     [not found]             ` <4B53BD61.9040609-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
2010-01-18  1:48               ` KOSAKI Motohiro

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).