regressions.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
@ 2021-06-08 17:12 Kees Cook
  2021-06-09  6:40 ` Christian Brauner
  2021-06-14 10:02 ` youling257
  0 siblings, 2 replies; 14+ messages in thread
From: Kees Cook @ 2021-06-08 17:12 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Kees Cook, Christian Brauner, Andrea Righi, stable, linux-kernel,
	regressions

Commit bfb819ea20ce ("proc: Check /proc/$pid/attr/ writes against file opener")
tried to make sure that there could not be a confusion between the opener of
a /proc/$pid/attr/ file and the writer. It used struct cred to make sure
the privileges didn't change. However, there were existing cases where a more
privileged thread was passing the opened fd to a differently privileged thread
(during container setup). Instead, use mm_struct to track whether the opener
and writer are still the same process. (This is what several other proc files
already do, though for different reasons.)

Reported-by: Christian Brauner <christian.brauner@ubuntu.com>
Reported-by: Andrea Righi <andrea.righi@canonical.com>
Tested-by: Andrea Righi <andrea.righi@canonical.com>
Fixes: bfb819ea20ce ("proc: Check /proc/$pid/attr/ writes against file opener")
Cc: stable@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/proc/base.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 58bbf334265b..7118ebe38fa6 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2674,6 +2674,11 @@ static int proc_pident_readdir(struct file *file, struct dir_context *ctx,
 }
 
 #ifdef CONFIG_SECURITY
+static int proc_pid_attr_open(struct inode *inode, struct file *file)
+{
+	return __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS);
+}
+
 static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
 				  size_t count, loff_t *ppos)
 {
@@ -2704,7 +2709,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
 	int rv;
 
 	/* A task may only write when it was the opener. */
-	if (file->f_cred != current_real_cred())
+	if (file->private_data != current->mm)
 		return -EPERM;
 
 	rcu_read_lock();
@@ -2754,9 +2759,11 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
 }
 
 static const struct file_operations proc_pid_attr_operations = {
+	.open		= proc_pid_attr_open,
 	.read		= proc_pid_attr_read,
 	.write		= proc_pid_attr_write,
 	.llseek		= generic_file_llseek,
+	.release	= mem_release,
 };
 
 #define LSM_DIR_OPS(LSM) \
-- 
2.25.1


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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-08 17:12 [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct Kees Cook
@ 2021-06-09  6:40 ` Christian Brauner
  2021-06-14 10:02 ` youling257
  1 sibling, 0 replies; 14+ messages in thread
From: Christian Brauner @ 2021-06-09  6:40 UTC (permalink / raw)
  To: Kees Cook; +Cc: Linus Torvalds, Andrea Righi, stable, linux-kernel, regressions

On Tue, Jun 08, 2021 at 10:12:21AM -0700, Kees Cook wrote:
> Commit bfb819ea20ce ("proc: Check /proc/$pid/attr/ writes against file opener")
> tried to make sure that there could not be a confusion between the opener of
> a /proc/$pid/attr/ file and the writer. It used struct cred to make sure
> the privileges didn't change. However, there were existing cases where a more
> privileged thread was passing the opened fd to a differently privileged thread
> (during container setup). Instead, use mm_struct to track whether the opener
> and writer are still the same process. (This is what several other proc files
> already do, though for different reasons.)
> 
> Reported-by: Christian Brauner <christian.brauner@ubuntu.com>
> Reported-by: Andrea Righi <andrea.righi@canonical.com>
> Tested-by: Andrea Righi <andrea.righi@canonical.com>
> Fixes: bfb819ea20ce ("proc: Check /proc/$pid/attr/ writes against file opener")
> Cc: stable@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---

Thanks!
Acked-by: Christian Brauner <christian.brauner@ubuntu.com>

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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-08 17:12 [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct Kees Cook
  2021-06-09  6:40 ` Christian Brauner
@ 2021-06-14 10:02 ` youling257
  2021-06-14 15:32   ` Kees Cook
  1 sibling, 1 reply; 14+ messages in thread
From: youling257 @ 2021-06-14 10:02 UTC (permalink / raw)
  To: keescook
  Cc: torvalds, christian.brauner, andrea.righi, linux-kernel, stable,
	regressions

I used mainline kernel on android, this patch cause "failed to retrieve pid context" problem.

06-14 02:15:51.165  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1682) failed to retrieve pid context.
06-14 02:15:51.166  1685  1685 E ServiceManager: add_service('batteryproperties',1) uid=0 - PERMISSION DENIED
06-14 02:15:51.166  1682  1682 I ServiceManager: addService() batteryproperties failed (err -1 - no service manager yet?).  Retrying...
06-14 02:15:51.197  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1695) failed to retrieve pid context.
06-14 02:15:51.197  1685  1685 E ServiceManager: add_service('android.security.keystore',1) uid=1017 - PERMISSION DENIED
06-14 02:15:51.198  1695  1695 I ServiceManager: addService() android.security.keystore failed (err -1 - no service manager yet?).  Retrying...
06-14 02:15:51.207  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1708) failed to retrieve pid context.
06-14 02:15:51.207  1685  1685 E ServiceManager: add_service('android.service.gatekeeper.IGateKeeperService',1) uid=1000 - PERMISSION DENIED
06-14 02:15:51.207  1708  1708 I ServiceManager: addService() android.service.gatekeeper.IGateKeeperService failed (err -1 - no service manager yet?).  Retrying...
06-14 02:15:51.275  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1693) failed to retrieve pid context.
06-14 02:15:51.275  1692  1692 I cameraserver: ServiceManager: 0xf6d309e0
06-14 02:15:51.275  1685  1685 E ServiceManager: add_service('drm.drmManager',1) uid=1019 - PERMISSION DENIED
06-14 02:15:51.276  1693  1693 I ServiceManager: addService() drm.drmManager failed (err -1 - no service manager yet?).  Retrying...


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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-14 10:02 ` youling257
@ 2021-06-14 15:32   ` Kees Cook
  2021-06-14 16:45     ` Kees Cook
  2021-06-14 17:52     ` Casey Schaufler
  0 siblings, 2 replies; 14+ messages in thread
From: Kees Cook @ 2021-06-14 15:32 UTC (permalink / raw)
  To: youling257
  Cc: torvalds, christian.brauner, andrea.righi, linux-kernel, stable,
	regressions, linux-security-module, Paul Moore, Stephen Smalley,
	SElinux list

On Mon, Jun 14, 2021 at 06:02:34PM +0800, youling257 wrote:
> I used mainline kernel on android, this patch cause "failed to retrieve pid context" problem.
> 
> 06-14 02:15:51.165  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1682) failed to retrieve pid context.
> 06-14 02:15:51.166  1685  1685 E ServiceManager: add_service('batteryproperties',1) uid=0 - PERMISSION DENIED
> 06-14 02:15:51.166  1682  1682 I ServiceManager: addService() batteryproperties failed (err -1 - no service manager yet?).  Retrying...
> 06-14 02:15:51.197  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1695) failed to retrieve pid context.
> 06-14 02:15:51.197  1685  1685 E ServiceManager: add_service('android.security.keystore',1) uid=1017 - PERMISSION DENIED
> 06-14 02:15:51.198  1695  1695 I ServiceManager: addService() android.security.keystore failed (err -1 - no service manager yet?).  Retrying...
> 06-14 02:15:51.207  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1708) failed to retrieve pid context.
> 06-14 02:15:51.207  1685  1685 E ServiceManager: add_service('android.service.gatekeeper.IGateKeeperService',1) uid=1000 - PERMISSION DENIED
> 06-14 02:15:51.207  1708  1708 I ServiceManager: addService() android.service.gatekeeper.IGateKeeperService failed (err -1 - no service manager yet?).  Retrying...
> 06-14 02:15:51.275  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1693) failed to retrieve pid context.
> 06-14 02:15:51.275  1692  1692 I cameraserver: ServiceManager: 0xf6d309e0
> 06-14 02:15:51.275  1685  1685 E ServiceManager: add_service('drm.drmManager',1) uid=1019 - PERMISSION DENIED
> 06-14 02:15:51.276  1693  1693 I ServiceManager: addService() drm.drmManager failed (err -1 - no service manager yet?).  Retrying...
> 

Argh. Are you able to uncover what userspace is doing here?

So far, my test cases are:

1) self: open, write, close: allowed
2) self: open, clone thread. thread: change privileges, write, close: allowed
3) self: open, give to privileged process. privileged process: write: reject


-- 
Kees Cook

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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-14 15:32   ` Kees Cook
@ 2021-06-14 16:45     ` Kees Cook
  2021-06-14 18:02       ` Linus Torvalds
  2021-06-14 18:46       ` youling 257
  2021-06-14 17:52     ` Casey Schaufler
  1 sibling, 2 replies; 14+ messages in thread
From: Kees Cook @ 2021-06-14 16:45 UTC (permalink / raw)
  To: youling257
  Cc: torvalds, christian.brauner, andrea.righi, linux-kernel, stable,
	regressions, linux-security-module, Paul Moore, Stephen Smalley,
	SElinux list

On Mon, Jun 14, 2021 at 08:32:35AM -0700, Kees Cook wrote:
> On Mon, Jun 14, 2021 at 06:02:34PM +0800, youling257 wrote:
> > I used mainline kernel on android, this patch cause "failed to retrieve pid context" problem.
> > 
> > 06-14 02:15:51.165  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1682) failed to retrieve pid context.

I found getpidcon() in libselinux:
https://github.com/SELinuxProject/selinux/blob/master/libselinux/src/procattr.c#L159

> > 06-14 02:15:51.166  1685  1685 E ServiceManager: add_service('batteryproperties',1) uid=0 - PERMISSION DENIED
> > 06-14 02:15:51.166  1682  1682 I ServiceManager: addService() batteryproperties failed (err -1 - no service manager yet?).  Retrying...
> > 06-14 02:15:51.197  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1695) failed to retrieve pid context.
> > 06-14 02:15:51.197  1685  1685 E ServiceManager: add_service('android.security.keystore',1) uid=1017 - PERMISSION DENIED
> > 06-14 02:15:51.198  1695  1695 I ServiceManager: addService() android.security.keystore failed (err -1 - no service manager yet?).  Retrying...
> > 06-14 02:15:51.207  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1708) failed to retrieve pid context.
> > 06-14 02:15:51.207  1685  1685 E ServiceManager: add_service('android.service.gatekeeper.IGateKeeperService',1) uid=1000 - PERMISSION DENIED
> > 06-14 02:15:51.207  1708  1708 I ServiceManager: addService() android.service.gatekeeper.IGateKeeperService failed (err -1 - no service manager yet?).  Retrying...
> > 06-14 02:15:51.275  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1693) failed to retrieve pid context.
> > 06-14 02:15:51.275  1692  1692 I cameraserver: ServiceManager: 0xf6d309e0
> > 06-14 02:15:51.275  1685  1685 E ServiceManager: add_service('drm.drmManager',1) uid=1019 - PERMISSION DENIED
> > 06-14 02:15:51.276  1693  1693 I ServiceManager: addService() drm.drmManager failed (err -1 - no service manager yet?).  Retrying...
> > 
> 
> Argh. Are you able to uncover what userspace is doing here?

It looks like this is a case of attempting to _read_ the attr file, and
the new opener check was requiring the opener/target relationship pass
the mm_access() checks, which is clearly too strict.

> So far, my test cases are:
> 
> 1) self: open, write, close: allowed
> 2) self: open, clone thread. thread: change privileges, write, close: allowed
> 3) self: open, give to privileged process. privileged process: write: reject

I've now added:

4) self: open privileged process's attr, read, close: allowed

Can folks please test this patch to double-check?


diff --git a/fs/proc/base.c b/fs/proc/base.c
index 7118ebe38fa6..7c55301674e0 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2676,7 +2676,14 @@ static int proc_pident_readdir(struct file *file, struct dir_context *ctx,
 #ifdef CONFIG_SECURITY
 static int proc_pid_attr_open(struct inode *inode, struct file *file)
 {
-	return __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS);
+	struct mm_struct *mm = __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS);
+
+	/* Reads do not require mm_struct access. */
+	if (IS_ERR(mm))
+		mm = NULL;
+
+	file->private_data = mm;
+	return 0;
 }
 
 static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
@@ -2709,7 +2716,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
 	int rv;
 
 	/* A task may only write when it was the opener. */
-	if (file->private_data != current->mm)
+	if (!file->private_data || file->private_data != current->mm)
 		return -EPERM;
 
 	rcu_read_lock();


Wheee.

-- 
Kees Cook

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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-14 15:32   ` Kees Cook
  2021-06-14 16:45     ` Kees Cook
@ 2021-06-14 17:52     ` Casey Schaufler
  1 sibling, 0 replies; 14+ messages in thread
From: Casey Schaufler @ 2021-06-14 17:52 UTC (permalink / raw)
  To: Kees Cook, youling257
  Cc: torvalds, christian.brauner, andrea.righi, linux-kernel, stable,
	regressions, linux-security-module, Paul Moore, Stephen Smalley,
	SElinux list, Casey Schaufler

On 6/14/2021 8:32 AM, Kees Cook wrote:
> On Mon, Jun 14, 2021 at 06:02:34PM +0800, youling257 wrote:
>> I used mainline kernel on android, this patch cause "failed to retrieve pid context" problem.
>>
>> 06-14 02:15:51.165  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1682) failed to retrieve pid context.
>> 06-14 02:15:51.166  1685  1685 E ServiceManager: add_service('batteryproperties',1) uid=0 - PERMISSION DENIED
>> 06-14 02:15:51.166  1682  1682 I ServiceManager: addService() batteryproperties failed (err -1 - no service manager yet?).  Retrying...
>> 06-14 02:15:51.197  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1695) failed to retrieve pid context.
>> 06-14 02:15:51.197  1685  1685 E ServiceManager: add_service('android.security.keystore',1) uid=1017 - PERMISSION DENIED
>> 06-14 02:15:51.198  1695  1695 I ServiceManager: addService() android.security.keystore failed (err -1 - no service manager yet?).  Retrying...
>> 06-14 02:15:51.207  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1708) failed to retrieve pid context.
>> 06-14 02:15:51.207  1685  1685 E ServiceManager: add_service('android.service.gatekeeper.IGateKeeperService',1) uid=1000 - PERMISSION DENIED
>> 06-14 02:15:51.207  1708  1708 I ServiceManager: addService() android.service.gatekeeper.IGateKeeperService failed (err -1 - no service manager yet?).  Retrying...
>> 06-14 02:15:51.275  1685  1685 E ServiceManager: SELinux: getpidcon(pid=1693) failed to retrieve pid context.
>> 06-14 02:15:51.275  1692  1692 I cameraserver: ServiceManager: 0xf6d309e0
>> 06-14 02:15:51.275  1685  1685 E ServiceManager: add_service('drm.drmManager',1) uid=1019 - PERMISSION DENIED
>> 06-14 02:15:51.276  1693  1693 I ServiceManager: addService() drm.drmManager failed (err -1 - no service manager yet?).  Retrying...
>>
> Argh. Are you able to uncover what userspace is doing here?
>
> So far, my test cases are:
>
> 1) self: open, write, close: allowed
> 2) self: open, clone thread. thread: change privileges, write, close: allowed
> 3) self: open, give to privileged process. privileged process: write: reject

I found an issue under Smack where a privileged process opened
/proc/self/attr/smack/current, wrote to it successfully, then tried
to write to it again, which failed because the cred has changed. 
That's not a common use case. The usual case is open, write, close.
If ServiceManager is assuming that it can leave a descriptor open
while manipulations are in progress it could encounter the same kind
of problem.



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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-14 16:45     ` Kees Cook
@ 2021-06-14 18:02       ` Linus Torvalds
  2021-06-14 18:46       ` youling 257
  1 sibling, 0 replies; 14+ messages in thread
From: Linus Torvalds @ 2021-06-14 18:02 UTC (permalink / raw)
  To: Kees Cook
  Cc: youling257, Christian Brauner, Andrea Righi,
	Linux Kernel Mailing List, stable, regressions, LSM List,
	Paul Moore, Stephen Smalley, SElinux list

On Mon, Jun 14, 2021 at 9:45 AM Kees Cook <keescook@chromium.org> wrote:
>
>         /* A task may only write when it was the opener. */
> -       if (file->private_data != current->mm)
> +       if (!file->private_data || file->private_data != current->mm)

I don't think this is necessary.

If file->private_data is NULL, then the old test for private_data !=
current->mm will still work just fine.

Because if you can fool kernel threads to do the write for you, you
have bigger security issues than that test.

               Linus

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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-14 16:45     ` Kees Cook
  2021-06-14 18:02       ` Linus Torvalds
@ 2021-06-14 18:46       ` youling 257
  2021-06-14 22:50         ` Kees Cook
  1 sibling, 1 reply; 14+ messages in thread
From: youling 257 @ 2021-06-14 18:46 UTC (permalink / raw)
  To: Kees Cook
  Cc: torvalds, christian.brauner, andrea.righi, linux-kernel, stable,
	regressions, linux-security-module, Paul Moore, Stephen Smalley,
	SElinux list

[-- Attachment #1: Type: text/plain, Size: 3983 bytes --]

I test this patch cause "init: cannot setexeccon(u:r:ueventd:s0)
operation not permitted.
init ctrl_write_limited.

2021-06-15 0:45 GMT+08:00, Kees Cook <keescook@chromium.org>:
> On Mon, Jun 14, 2021 at 08:32:35AM -0700, Kees Cook wrote:
>> On Mon, Jun 14, 2021 at 06:02:34PM +0800, youling257 wrote:
>> > I used mainline kernel on android, this patch cause "failed to retrieve
>> > pid context" problem.
>> >
>> > 06-14 02:15:51.165  1685  1685 E ServiceManager: SELinux:
>> > getpidcon(pid=1682) failed to retrieve pid context.
>
> I found getpidcon() in libselinux:
> https://github.com/SELinuxProject/selinux/blob/master/libselinux/src/procattr.c#L159
>
>> > 06-14 02:15:51.166  1685  1685 E ServiceManager:
>> > add_service('batteryproperties',1) uid=0 - PERMISSION DENIED
>> > 06-14 02:15:51.166  1682  1682 I ServiceManager: addService()
>> > batteryproperties failed (err -1 - no service manager yet?).
>> > Retrying...
>> > 06-14 02:15:51.197  1685  1685 E ServiceManager: SELinux:
>> > getpidcon(pid=1695) failed to retrieve pid context.
>> > 06-14 02:15:51.197  1685  1685 E ServiceManager:
>> > add_service('android.security.keystore',1) uid=1017 - PERMISSION DENIED
>> > 06-14 02:15:51.198  1695  1695 I ServiceManager: addService()
>> > android.security.keystore failed (err -1 - no service manager yet?).
>> > Retrying...
>> > 06-14 02:15:51.207  1685  1685 E ServiceManager: SELinux:
>> > getpidcon(pid=1708) failed to retrieve pid context.
>> > 06-14 02:15:51.207  1685  1685 E ServiceManager:
>> > add_service('android.service.gatekeeper.IGateKeeperService',1) uid=1000
>> > - PERMISSION DENIED
>> > 06-14 02:15:51.207  1708  1708 I ServiceManager: addService()
>> > android.service.gatekeeper.IGateKeeperService failed (err -1 - no
>> > service manager yet?).  Retrying...
>> > 06-14 02:15:51.275  1685  1685 E ServiceManager: SELinux:
>> > getpidcon(pid=1693) failed to retrieve pid context.
>> > 06-14 02:15:51.275  1692  1692 I cameraserver: ServiceManager:
>> > 0xf6d309e0
>> > 06-14 02:15:51.275  1685  1685 E ServiceManager:
>> > add_service('drm.drmManager',1) uid=1019 - PERMISSION DENIED
>> > 06-14 02:15:51.276  1693  1693 I ServiceManager: addService()
>> > drm.drmManager failed (err -1 - no service manager yet?).  Retrying...
>> >
>>
>> Argh. Are you able to uncover what userspace is doing here?
>
> It looks like this is a case of attempting to _read_ the attr file, and
> the new opener check was requiring the opener/target relationship pass
> the mm_access() checks, which is clearly too strict.
>
>> So far, my test cases are:
>>
>> 1) self: open, write, close: allowed
>> 2) self: open, clone thread. thread: change privileges, write, close:
>> allowed
>> 3) self: open, give to privileged process. privileged process: write:
>> reject
>
> I've now added:
>
> 4) self: open privileged process's attr, read, close: allowed
>
> Can folks please test this patch to double-check?
>
>
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index 7118ebe38fa6..7c55301674e0 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -2676,7 +2676,14 @@ static int proc_pident_readdir(struct file *file,
> struct dir_context *ctx,
>  #ifdef CONFIG_SECURITY
>  static int proc_pid_attr_open(struct inode *inode, struct file *file)
>  {
> -	return __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS);
> +	struct mm_struct *mm = __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS);
> +
> +	/* Reads do not require mm_struct access. */
> +	if (IS_ERR(mm))
> +		mm = NULL;
> +
> +	file->private_data = mm;
> +	return 0;
>  }
>
>  static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
> @@ -2709,7 +2716,7 @@ static ssize_t proc_pid_attr_write(struct file * file,
> const char __user * buf,
>  	int rv;
>
>  	/* A task may only write when it was the opener. */
> -	if (file->private_data != current->mm)
> +	if (!file->private_data || file->private_data != current->mm)
>  		return -EPERM;
>
>  	rcu_read_lock();
>
>
> Wheee.
>
> --
> Kees Cook
>

[-- Attachment #2: wp_ss_20210615_0001.png --]
[-- Type: image/png, Size: 1198107 bytes --]

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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-14 18:46       ` youling 257
@ 2021-06-14 22:50         ` Kees Cook
  2021-06-15  1:55           ` youling 257
  0 siblings, 1 reply; 14+ messages in thread
From: Kees Cook @ 2021-06-14 22:50 UTC (permalink / raw)
  To: youling 257
  Cc: torvalds, christian.brauner, andrea.righi, linux-kernel, stable,
	regressions, linux-security-module, Paul Moore, Stephen Smalley,
	SElinux list

On Tue, Jun 15, 2021 at 02:46:19AM +0800, youling 257 wrote:
> I test this patch cause "init: cannot setexeccon(u:r:ueventd:s0)
> operation not permitted.
> init ctrl_write_limited.

Thanks for testing!

This appears to come from here:
https://github.com/aosp-mirror/platform_system_core/blob/master/init/service.cpp#L242


In setexeccon(), I see (pid=0, attr="exec"):

        fd = openattr(pid, attr, O_RDWR | O_CLOEXEC);
...
                        ret = write(fd, context2, strlen(context2) + 1);
...
        close(fd);


and openattr() is doing:
...
                rc = asprintf(&path, "/proc/thread-self/attr/%s", attr);
                if (rc < 0)
                        return -1;
                fd = open(path, flags | O_CLOEXEC);
...

I'm not sure how the above could fail. (mm_access() always allows
introspection...)

The only way I can understand the check failing is if a process did:

open, exec, write

But setexeccon() is not doing anything between the open and the write...

I will keep looking...

-Kees

-- 
Kees Cook

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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-14 22:50         ` Kees Cook
@ 2021-06-15  1:55           ` youling 257
  2021-06-15 18:19             ` Linus Torvalds
  0 siblings, 1 reply; 14+ messages in thread
From: youling 257 @ 2021-06-15  1:55 UTC (permalink / raw)
  To: Kees Cook
  Cc: torvalds, christian.brauner, andrea.righi, linux-kernel, stable,
	regressions, linux-security-module, Paul Moore, Stephen Smalley,
	SElinux list

if try to find problem on userspace, i used linux 5.13rc6 on old
android 7 cm14.1, not aosp android 11.
http://git.osdn.net/view?p=android-x86/system-core.git;a=blob;f=init/service.cpp;h=a5334f447fc2fc34453d2f6a37523bedccadc690;hb=refs/heads/cm-14.1-x86#l457

 457         if (!seclabel_.empty()) {
 458             if (setexeccon(seclabel_.c_str()) < 0) {
 459                 ERROR("cannot setexeccon('%s'): %s\n",
 460                       seclabel_.c_str(), strerror(errno));
 461                 _exit(127);
 462             }
 463         }

2021-06-15 6:50 GMT+08:00, Kees Cook <keescook@chromium.org>:
> On Tue, Jun 15, 2021 at 02:46:19AM +0800, youling 257 wrote:
>> I test this patch cause "init: cannot setexeccon(u:r:ueventd:s0)
>> operation not permitted.
>> init ctrl_write_limited.
>
> Thanks for testing!
>
> This appears to come from here:
> https://github.com/aosp-mirror/platform_system_core/blob/master/init/service.cpp#L242
>
>
> In setexeccon(), I see (pid=0, attr="exec"):
>
>         fd = openattr(pid, attr, O_RDWR | O_CLOEXEC);
> ...
>                         ret = write(fd, context2, strlen(context2) + 1);
> ...
>         close(fd);
>
>
> and openattr() is doing:
> ...
>                 rc = asprintf(&path, "/proc/thread-self/attr/%s", attr);
>                 if (rc < 0)
>                         return -1;
>                 fd = open(path, flags | O_CLOEXEC);
> ...
>
> I'm not sure how the above could fail. (mm_access() always allows
> introspection...)
>
> The only way I can understand the check failing is if a process did:
>
> open, exec, write
>
> But setexeccon() is not doing anything between the open and the write...
>
> I will keep looking...
>
> -Kees
>
> --
> Kees Cook
>

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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-15  1:55           ` youling 257
@ 2021-06-15 18:19             ` Linus Torvalds
  2021-06-15 21:50               ` Kees Cook
  2021-06-16  5:15               ` youling 257
  0 siblings, 2 replies; 14+ messages in thread
From: Linus Torvalds @ 2021-06-15 18:19 UTC (permalink / raw)
  To: youling 257
  Cc: Kees Cook, Christian Brauner, Andrea Righi,
	Linux Kernel Mailing List, stable, regressions, LSM List,
	Paul Moore, Stephen Smalley, SElinux list

On Mon, Jun 14, 2021 at 6:55 PM youling 257 <youling257@gmail.com> wrote:
>
> if try to find problem on userspace, i used linux 5.13rc6 on old
> android 7 cm14.1, not aosp android 11.
> http://git.osdn.net/view?p=android-x86/system-core.git;a=blob;f=init/service.cpp;h=a5334f447fc2fc34453d2f6a37523bedccadc690;hb=refs/heads/cm-14.1-x86#l457
>
>  457         if (!seclabel_.empty()) {
>  458             if (setexeccon(seclabel_.c_str()) < 0) {
>  459                 ERROR("cannot setexeccon('%s'): %s\n",
>  460                       seclabel_.c_str(), strerror(errno));
>  461                 _exit(127);
>  462             }
>  463         }

I have no idea where the cm14.1 libraries are. Does anybody know where
the matching source code for setexeccon() would be?

For me - obviously not on cm14.1 - all "setexeccon()" does is

   n = openat(AT_FDCWD, "/proc/thread-self/attr/exec", O_RDWR|O_CLOEXEC)
   write(n, string, len)
   close(n)

and if that fails, it would seem to indicate that proc_mem_open()
failed. Which would be mm_access() failing. But I don't see how that
can be the case, because mm_access() explicitly allows "mm ==
current->mm" (which the above clearly should be).

youling, can you double-check with the current -git tree? But as far
as I can tell, my minimal patch is exactly the same as Kees' patch
(just smaller and simpler).

Kees, do you see anything?

           Linus

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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-15 18:19             ` Linus Torvalds
@ 2021-06-15 21:50               ` Kees Cook
  2021-06-16  5:56                 ` Greg KH
  2021-06-16  5:15               ` youling 257
  1 sibling, 1 reply; 14+ messages in thread
From: Kees Cook @ 2021-06-15 21:50 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: youling 257, Christian Brauner, Andrea Righi,
	Linux Kernel Mailing List, stable, regressions, LSM List,
	Paul Moore, Stephen Smalley, SElinux list

On Tue, Jun 15, 2021 at 11:19:04AM -0700, Linus Torvalds wrote:
> On Mon, Jun 14, 2021 at 6:55 PM youling 257 <youling257@gmail.com> wrote:
> >
> > if try to find problem on userspace, i used linux 5.13rc6 on old
> > android 7 cm14.1, not aosp android 11.
> > http://git.osdn.net/view?p=android-x86/system-core.git;a=blob;f=init/service.cpp;h=a5334f447fc2fc34453d2f6a37523bedccadc690;hb=refs/heads/cm-14.1-x86#l457
> >
> >  457         if (!seclabel_.empty()) {
> >  458             if (setexeccon(seclabel_.c_str()) < 0) {
> >  459                 ERROR("cannot setexeccon('%s'): %s\n",
> >  460                       seclabel_.c_str(), strerror(errno));
> >  461                 _exit(127);
> >  462             }
> >  463         }
> 
> I have no idea where the cm14.1 libraries are. Does anybody know where
> the matching source code for setexeccon() would be?
> 
> For me - obviously not on cm14.1 - all "setexeccon()" does is
> 
>    n = openat(AT_FDCWD, "/proc/thread-self/attr/exec", O_RDWR|O_CLOEXEC)
>    write(n, string, len)
>    close(n)
> 
> and if that fails, it would seem to indicate that proc_mem_open()
> failed. Which would be mm_access() failing. But I don't see how that
> can be the case, because mm_access() explicitly allows "mm ==
> current->mm" (which the above clearly should be).

Yeah, that was what I saw too.

> youling, can you double-check with the current -git tree? But as far
> as I can tell, my minimal patch is exactly the same as Kees' patch
> (just smaller and simpler).

FWIW, for that patch:

Acked-by: Kees Cook <keescook@chromium.org>
Cc: stable@vger.kernel.org

> 
> Kees, do you see anything?

No, I haven't been able to reproduce the failure. :(

-- 
Kees Cook

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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-15 18:19             ` Linus Torvalds
  2021-06-15 21:50               ` Kees Cook
@ 2021-06-16  5:15               ` youling 257
  1 sibling, 0 replies; 14+ messages in thread
From: youling 257 @ 2021-06-16  5:15 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Kees Cook, Christian Brauner, Andrea Righi,
	Linux Kernel Mailing List, stable, regressions, LSM List,
	Paul Moore, Stephen Smalley, SElinux list

I test "proc: only require mm_struct for writing" fixed my cm14.1 problem.

2021-06-16 2:19 GMT+08:00, Linus Torvalds <torvalds@linux-foundation.org>:
> On Mon, Jun 14, 2021 at 6:55 PM youling 257 <youling257@gmail.com> wrote:
>>
>> if try to find problem on userspace, i used linux 5.13rc6 on old
>> android 7 cm14.1, not aosp android 11.
>> http://git.osdn.net/view?p=android-x86/system-core.git;a=blob;f=init/service.cpp;h=a5334f447fc2fc34453d2f6a37523bedccadc690;hb=refs/heads/cm-14.1-x86#l457
>>
>>  457         if (!seclabel_.empty()) {
>>  458             if (setexeccon(seclabel_.c_str()) < 0) {
>>  459                 ERROR("cannot setexeccon('%s'): %s\n",
>>  460                       seclabel_.c_str(), strerror(errno));
>>  461                 _exit(127);
>>  462             }
>>  463         }
>
> I have no idea where the cm14.1 libraries are. Does anybody know where
> the matching source code for setexeccon() would be?
>
> For me - obviously not on cm14.1 - all "setexeccon()" does is
>
>    n = openat(AT_FDCWD, "/proc/thread-self/attr/exec", O_RDWR|O_CLOEXEC)
>    write(n, string, len)
>    close(n)
>
> and if that fails, it would seem to indicate that proc_mem_open()
> failed. Which would be mm_access() failing. But I don't see how that
> can be the case, because mm_access() explicitly allows "mm ==
> current->mm" (which the above clearly should be).
>
> youling, can you double-check with the current -git tree? But as far
> as I can tell, my minimal patch is exactly the same as Kees' patch
> (just smaller and simpler).
>
> Kees, do you see anything?
>
>            Linus
>

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

* Re: [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct
  2021-06-15 21:50               ` Kees Cook
@ 2021-06-16  5:56                 ` Greg KH
  0 siblings, 0 replies; 14+ messages in thread
From: Greg KH @ 2021-06-16  5:56 UTC (permalink / raw)
  To: Kees Cook
  Cc: Linus Torvalds, youling 257, Christian Brauner, Andrea Righi,
	Linux Kernel Mailing List, stable, regressions, LSM List,
	Paul Moore, Stephen Smalley, SElinux list

On Tue, Jun 15, 2021 at 02:50:39PM -0700, Kees Cook wrote:
> On Tue, Jun 15, 2021 at 11:19:04AM -0700, Linus Torvalds wrote:
> > On Mon, Jun 14, 2021 at 6:55 PM youling 257 <youling257@gmail.com> wrote:
> > >
> > > if try to find problem on userspace, i used linux 5.13rc6 on old
> > > android 7 cm14.1, not aosp android 11.
> > > http://git.osdn.net/view?p=android-x86/system-core.git;a=blob;f=init/service.cpp;h=a5334f447fc2fc34453d2f6a37523bedccadc690;hb=refs/heads/cm-14.1-x86#l457
> > >
> > >  457         if (!seclabel_.empty()) {
> > >  458             if (setexeccon(seclabel_.c_str()) < 0) {
> > >  459                 ERROR("cannot setexeccon('%s'): %s\n",
> > >  460                       seclabel_.c_str(), strerror(errno));
> > >  461                 _exit(127);
> > >  462             }
> > >  463         }
> > 
> > I have no idea where the cm14.1 libraries are. Does anybody know where
> > the matching source code for setexeccon() would be?
> > 
> > For me - obviously not on cm14.1 - all "setexeccon()" does is
> > 
> >    n = openat(AT_FDCWD, "/proc/thread-self/attr/exec", O_RDWR|O_CLOEXEC)
> >    write(n, string, len)
> >    close(n)
> > 
> > and if that fails, it would seem to indicate that proc_mem_open()
> > failed. Which would be mm_access() failing. But I don't see how that
> > can be the case, because mm_access() explicitly allows "mm ==
> > current->mm" (which the above clearly should be).
> 
> Yeah, that was what I saw too.
> 
> > youling, can you double-check with the current -git tree? But as far
> > as I can tell, my minimal patch is exactly the same as Kees' patch
> > (just smaller and simpler).
> 
> FWIW, for that patch:
> 
> Acked-by: Kees Cook <keescook@chromium.org>
> Cc: stable@vger.kernel.org

Thanks, I'll go pick it up now.

greg k-h

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

end of thread, other threads:[~2021-06-16  5:56 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-08 17:12 [PATCH] proc: Track /proc/$pid/attr/ opener mm_struct Kees Cook
2021-06-09  6:40 ` Christian Brauner
2021-06-14 10:02 ` youling257
2021-06-14 15:32   ` Kees Cook
2021-06-14 16:45     ` Kees Cook
2021-06-14 18:02       ` Linus Torvalds
2021-06-14 18:46       ` youling 257
2021-06-14 22:50         ` Kees Cook
2021-06-15  1:55           ` youling 257
2021-06-15 18:19             ` Linus Torvalds
2021-06-15 21:50               ` Kees Cook
2021-06-16  5:56                 ` Greg KH
2021-06-16  5:15               ` youling 257
2021-06-14 17:52     ` Casey Schaufler

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).