All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [Fwd: type class key]
       [not found]     ` <22421.1194637689@redhat.com>
@ 2007-11-09 19:51       ` Stephen Smalley
  2007-11-09 20:00         ` Stephen Smalley
                           ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Stephen Smalley @ 2007-11-09 19:51 UTC (permalink / raw)
  To: David Howells; +Cc: Stefan Schulze Frielinghaus, selinux

On Fri, 2007-11-09 at 19:48 +0000, David Howells wrote:
> Okay, it looks like it's probably the problem I'm thinking of.  If it is, I
> need to think carefully about how to deal with it.
> 
> Stephen: Would it be possible for me to create the per-UID keyring without
> reference to the security label of the current process?
> 
> The other alternative is to accept that if the label can't be linked because
> of a security label disagreement than that's that, and we don't give an error.
> 
> I don't like that second option, though, because that can seriously limit the
> utility of the per-UID keyring by it being a lottery as to what label it gets
> created with - basically who gets to try creating it first.
> 
> Any suggestions?

(taking discussion back on list)

We already provide a way to create a key with a specified label other
than the current process, via setkeycreatecon(3) aka writing the label
to /proc/self/attr/keycreate before allocating the key.

So why can't the userland code that is allocating these per-uid keyrings
use that interface to set the context appropriately for the actual user
rather than defaulting to its own context?

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-09 19:51       ` [Fwd: type class key] Stephen Smalley
@ 2007-11-09 20:00         ` Stephen Smalley
  2007-11-09 20:35           ` Casey Schaufler
  2007-11-10 12:26         ` David Howells
  2007-11-15 13:08         ` David Howells
  2 siblings, 1 reply; 21+ messages in thread
From: Stephen Smalley @ 2007-11-09 20:00 UTC (permalink / raw)
  To: David Howells; +Cc: Stefan Schulze Frielinghaus, selinux

On Fri, 2007-11-09 at 14:51 -0500, Stephen Smalley wrote:
> On Fri, 2007-11-09 at 19:48 +0000, David Howells wrote:
> > Okay, it looks like it's probably the problem I'm thinking of.  If it is, I
> > need to think carefully about how to deal with it.
> > 
> > Stephen: Would it be possible for me to create the per-UID keyring without
> > reference to the security label of the current process?
> > 
> > The other alternative is to accept that if the label can't be linked because
> > of a security label disagreement than that's that, and we don't give an error.
> > 
> > I don't like that second option, though, because that can seriously limit the
> > utility of the per-UID keyring by it being a lottery as to what label it gets
> > created with - basically who gets to try creating it first.
> > 
> > Any suggestions?
> 
> (taking discussion back on list)
> 
> We already provide a way to create a key with a specified label other
> than the current process, via setkeycreatecon(3) aka writing the label
> to /proc/self/attr/keycreate before allocating the key.
> 
> So why can't the userland code that is allocating these per-uid keyrings
> use that interface to set the context appropriately for the actual user
> rather than defaulting to its own context?

Ah, wait - this is an automatic allocation of a per-uid keyring upon a
setuid() call, right?

So here we have a kernel-internal allocation of the keyring (so userland
doesn't know it needs to setkeycreatecon, and requiring it to do so
seems a bit clunky), yet on the other hand, we don't presently have a
way to map a Linux uid automatically to a SELinux security context in
the kernel - that's managed in userspace, and a single Linux uid might
ultimately have a number of SELinux security contexts running on its
behalf.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-09 20:00         ` Stephen Smalley
@ 2007-11-09 20:35           ` Casey Schaufler
  0 siblings, 0 replies; 21+ messages in thread
From: Casey Schaufler @ 2007-11-09 20:35 UTC (permalink / raw)
  To: Stephen Smalley, David Howells; +Cc: Stefan Schulze Frielinghaus, selinux


--- Stephen Smalley <sds@tycho.nsa.gov> wrote:

> On Fri, 2007-11-09 at 14:51 -0500, Stephen Smalley wrote:
> > On Fri, 2007-11-09 at 19:48 +0000, David Howells wrote:
> > > Okay, it looks like it's probably the problem I'm thinking of.  If it is,
> I
> > > need to think carefully about how to deal with it.
> > > 
> > > Stephen: Would it be possible for me to create the per-UID keyring
> without
> > > reference to the security label of the current process?
> > > 
> > > The other alternative is to accept that if the label can't be linked
> because
> > > of a security label disagreement than that's that, and we don't give an
> error.
> > > 
> > > I don't like that second option, though, because that can seriously limit
> the
> > > utility of the per-UID keyring by it being a lottery as to what label it
> gets
> > > created with - basically who gets to try creating it first.
> > > 
> > > Any suggestions?
> > 
> > (taking discussion back on list)
> > 
> > We already provide a way to create a key with a specified label other
> > than the current process, via setkeycreatecon(3) aka writing the label
> > to /proc/self/attr/keycreate before allocating the key.
> > 
> > So why can't the userland code that is allocating these per-uid keyrings
> > use that interface to set the context appropriately for the actual user
> > rather than defaulting to its own context?
> 
> Ah, wait - this is an automatic allocation of a per-uid keyring upon a
> setuid() call, right?
> 
> So here we have a kernel-internal allocation of the keyring (so userland
> doesn't know it needs to setkeycreatecon, and requiring it to do so
> seems a bit clunky), yet on the other hand, we don't presently have a
> way to map a Linux uid automatically to a SELinux security context in
> the kernel - that's managed in userspace, and a single Linux uid might
> ultimately have a number of SELinux security contexts running on its
> behalf.

This is going to be a problem with any MAC scheme, or at least
any that allows a uid to use more than one label. There is a
faction that will shout "Polyinstantiation!" at this point,
advocating that there be a key for each uid/label pair. I can't
claim to understand how the keyring is used well enough to
say if this is a good idea or a bad one.


Casey Schaufler
casey@schaufler-ca.com

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-09 19:51       ` [Fwd: type class key] Stephen Smalley
  2007-11-09 20:00         ` Stephen Smalley
@ 2007-11-10 12:26         ` David Howells
  2007-11-14 20:23           ` Daniel J Walsh
                             ` (3 more replies)
  2007-11-15 13:08         ` David Howells
  2 siblings, 4 replies; 21+ messages in thread
From: David Howells @ 2007-11-10 12:26 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: dhowells, Stefan Schulze Frielinghaus, selinux

Stephen Smalley <sds@tycho.nsa.gov> wrote:

> Ah, wait - this is an automatic allocation of a per-uid keyring upon a
> setuid() call, right?

Yes.

> and a single Linux uid might ultimately have a number of SELinux security
> contexts running on its behalf.

Indeed.  It's not something that anyone considered at the time, I suppose.

David

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-10 12:26         ` David Howells
@ 2007-11-14 20:23           ` Daniel J Walsh
  2007-11-15 12:17           ` David Howells
                             ` (2 subsequent siblings)
  3 siblings, 0 replies; 21+ messages in thread
From: Daniel J Walsh @ 2007-11-14 20:23 UTC (permalink / raw)
  To: David Howells; +Cc: Stephen Smalley, Stefan Schulze Frielinghaus, selinux

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

David Howells wrote:
> Stephen Smalley <sds@tycho.nsa.gov> wrote:
> 
>> Ah, wait - this is an automatic allocation of a per-uid keyring upon a
>> setuid() call, right?
> 
> Yes.
> 
>> and a single Linux uid might ultimately have a number of SELinux security
>> contexts running on its behalf.
> 
> Indeed.  It's not something that anyone considered at the time, I suppose.
> 
> David
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.

David, we need a method of querying the keyring to see what the selinux
context that is associated with it.  For debugging purposes.  Currently
we can not tell whether the policy is correct or not, since we have no
way to ask the keyring for its label.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iD8DBQFHO1korlYvE4MpobMRAoruAKDTG5sR2NohyeorC54htOn9/echHgCfYvKH
JwjEmAskBq6lezg/UfN74D8=
=NQJJ
-----END PGP SIGNATURE-----

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-10 12:26         ` David Howells
  2007-11-14 20:23           ` Daniel J Walsh
@ 2007-11-15 12:17           ` David Howells
  2007-11-15 13:33             ` Daniel J Walsh
                               ` (2 more replies)
  2007-11-15 14:53           ` David Howells
  2007-11-15 14:58           ` David Howells
  3 siblings, 3 replies; 21+ messages in thread
From: David Howells @ 2007-11-15 12:17 UTC (permalink / raw)
  To: Daniel J Walsh
  Cc: dhowells, Stephen Smalley, Stefan Schulze Frielinghaus, selinux

Daniel J Walsh <dwalsh@redhat.com> wrote:

> David, we need a method of querying the keyring to see what the selinux
> context that is associated with it.  For debugging purposes.  Currently
> we can not tell whether the policy is correct or not, since we have no
> way to ask the keyring for its label.

That's probably easy enough.  What form does a context take?

David

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-09 19:51       ` [Fwd: type class key] Stephen Smalley
  2007-11-09 20:00         ` Stephen Smalley
  2007-11-10 12:26         ` David Howells
@ 2007-11-15 13:08         ` David Howells
  2 siblings, 0 replies; 21+ messages in thread
From: David Howells @ 2007-11-15 13:08 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: dhowells, Stefan Schulze Frielinghaus, selinux

Stephen Smalley <sds@tycho.nsa.gov> wrote:

> Ah, wait - this is an automatic allocation of a per-uid keyring upon a
> setuid() call, right?

Maybe that's the solution:  Don't automatically allocate the per-UID keyrings
until someone tries to link to one or put something into one.

Searching the keyrings won't create them - there's no point as they'd be empty
anyway.

The pam_keyinit module could then be made to take a "nouser" argument that
would tell it to avoid making the link from the session keyring it creates to
the user keyring (or conversely a "user" argument that tells it to create the
link).

That way I can arrange for only login processes (login, ssh, kdm, gdm, telnet,
etc) to use the per-UID keyrings.  Things such as dovecot wouldn't then use
it and so wouldn't create it.

David

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 12:17           ` David Howells
@ 2007-11-15 13:33             ` Daniel J Walsh
  2007-11-15 13:57             ` Stephen Smalley
  2007-11-15 14:41             ` David Howells
  2 siblings, 0 replies; 21+ messages in thread
From: Daniel J Walsh @ 2007-11-15 13:33 UTC (permalink / raw)
  To: David Howells; +Cc: Stephen Smalley, Stefan Schulze Frielinghaus, selinux

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

David Howells wrote:
> Daniel J Walsh <dwalsh@redhat.com> wrote:
> 
>> David, we need a method of querying the keyring to see what the selinux
>> context that is associated with it.  For debugging purposes.  Currently
>> we can not tell whether the policy is correct or not, since we have no
>> way to ask the keyring for its label.
> 
> That's probably easy enough.  What form does a context take?
> 
> David
It is just the string associated with the object
probably something like

user_u:object_r:user_t:s0


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iD8DBQFHPErHrlYvE4MpobMRAkt3AKDldaprNVeo+ZEA+Zwv+sylbl89pQCgodZX
a0TNsLL6RjlNvMajn4xz0Ak=
=4xHk
-----END PGP SIGNATURE-----

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 12:17           ` David Howells
  2007-11-15 13:33             ` Daniel J Walsh
@ 2007-11-15 13:57             ` Stephen Smalley
  2007-11-15 14:41             ` David Howells
  2 siblings, 0 replies; 21+ messages in thread
From: Stephen Smalley @ 2007-11-15 13:57 UTC (permalink / raw)
  To: David Howells; +Cc: Daniel J Walsh, Stefan Schulze Frielinghaus, selinux

On Thu, 2007-11-15 at 12:17 +0000, David Howells wrote:
> Daniel J Walsh <dwalsh@redhat.com> wrote:
> 
> > David, we need a method of querying the keyring to see what the selinux
> > context that is associated with it.  For debugging purposes.  Currently
> > we can not tell whether the policy is correct or not, since we have no
> > way to ask the keyring for its label.
> 
> That's probably easy enough.  What form does a context take?

It's a string.  As an example, see the security_inode_getsecurity() LSM
hook and selinux_inode_getsecurity() implementation of it.  But note
that the interface has changed in -mm to avoid the need to pass in an
already appropriately sized buffer.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 12:17           ` David Howells
  2007-11-15 13:33             ` Daniel J Walsh
  2007-11-15 13:57             ` Stephen Smalley
@ 2007-11-15 14:41             ` David Howells
  2007-11-15 14:52               ` Stephen Smalley
  2 siblings, 1 reply; 21+ messages in thread
From: David Howells @ 2007-11-15 14:41 UTC (permalink / raw)
  To: Stephen Smalley
  Cc: dhowells, Daniel J Walsh, Stefan Schulze Frielinghaus, selinux

Stephen Smalley <sds@tycho.nsa.gov> wrote:

> It's a string.  As an example, see the security_inode_getsecurity() LSM
> hook and selinux_inode_getsecurity() implementation of it.

Yeah...  That's along the lines of what I was thinking of.

> But note that the interface has changed in -mm to avoid the need to pass in
> an already appropriately sized buffer.

I'm not sure what you mean by that.  Do you mean the buffer has to be exactly
the right size?

David

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 14:41             ` David Howells
@ 2007-11-15 14:52               ` Stephen Smalley
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Smalley @ 2007-11-15 14:52 UTC (permalink / raw)
  To: David Howells; +Cc: Daniel J Walsh, Stefan Schulze Frielinghaus, selinux

On Thu, 2007-11-15 at 14:41 +0000, David Howells wrote:
> Stephen Smalley <sds@tycho.nsa.gov> wrote:
> 
> > It's a string.  As an example, see the security_inode_getsecurity() LSM
> > hook and selinux_inode_getsecurity() implementation of it.
> 
> Yeah...  That's along the lines of what I was thinking of.
> 
> > But note that the interface has changed in -mm to avoid the need to pass in
> > an already appropriately sized buffer.
> 
> I'm not sure what you mean by that.  Do you mean the buffer has to be exactly
> the right size?

Previously, the caller had to supply a buffer large enough for the
context string, and the hook copied into that buffer.  In -mm, the hook
allocates an appropriately sized buffer and returns the pointer to it to
the caller.

http://marc.info/?l=linux-fsdevel&m=119392810506870&w=2

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-10 12:26         ` David Howells
  2007-11-14 20:23           ` Daniel J Walsh
  2007-11-15 12:17           ` David Howells
@ 2007-11-15 14:53           ` David Howells
  2007-11-15 14:56             ` Stephen Smalley
  2007-11-15 14:58           ` David Howells
  3 siblings, 1 reply; 21+ messages in thread
From: David Howells @ 2007-11-15 14:53 UTC (permalink / raw)
  To: Daniel J Walsh
  Cc: dhowells, Stephen Smalley, Stefan Schulze Frielinghaus, selinux

Daniel J Walsh <dwalsh@redhat.com> wrote:

> David, we need a method of querying the keyring to see what the selinux
> context that is associated with it.  For debugging purposes.  Currently
> we can not tell whether the policy is correct or not, since we have no
> way to ask the keyring for its label.

Does it need to be accessible from kernel space?  Can I pass a userspace
buffer pointer through to the LSM?

David

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 14:53           ` David Howells
@ 2007-11-15 14:56             ` Stephen Smalley
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Smalley @ 2007-11-15 14:56 UTC (permalink / raw)
  To: David Howells; +Cc: Daniel J Walsh, Stefan Schulze Frielinghaus, selinux

On Thu, 2007-11-15 at 14:53 +0000, David Howells wrote:
> Daniel J Walsh <dwalsh@redhat.com> wrote:
> 
> > David, we need a method of querying the keyring to see what the selinux
> > context that is associated with it.  For debugging purposes.  Currently
> > we can not tell whether the policy is correct or not, since we have no
> > way to ask the keyring for its label.
> 
> Does it need to be accessible from kernel space?  Can I pass a userspace
> buffer pointer through to the LSM?

Yes to the first (likely will be wanted for audit eventually), no to the
second (preferably).  getprocattr and inode_getsecurity deal only with
kernel buffers themselves.


-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-10 12:26         ` David Howells
                             ` (2 preceding siblings ...)
  2007-11-15 14:53           ` David Howells
@ 2007-11-15 14:58           ` David Howells
  2007-11-15 15:02             ` Stephen Smalley
                               ` (3 more replies)
  3 siblings, 4 replies; 21+ messages in thread
From: David Howells @ 2007-11-15 14:58 UTC (permalink / raw)
  Cc: dhowells, Daniel J Walsh, Stephen Smalley,
	Stefan Schulze Frielinghaus, selinux

David Howells <dhowells@redhat.com> wrote:

> Does it need to be accessible from kernel space?  Can I pass a userspace
> buffer pointer through to the LSM?

In fact, is the best way to do it to have a prototype like:

	int security_key_getsecurity(struct key *key, char **_buffer);

Where the buffer is allocated by this function and attached to *_buffer and
the length returned if successful (though that last is unnecessary if a
NUL-terminated string is being returned); and if an error occurs, then that is
returned instead.

David

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 14:58           ` David Howells
@ 2007-11-15 15:02             ` Stephen Smalley
  2007-11-15 16:04             ` David Howells
                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 21+ messages in thread
From: Stephen Smalley @ 2007-11-15 15:02 UTC (permalink / raw)
  To: David Howells; +Cc: Daniel J Walsh, Stefan Schulze Frielinghaus, selinux

On Thu, 2007-11-15 at 14:58 +0000, David Howells wrote:
> David Howells <dhowells@redhat.com> wrote:
> 
> > Does it need to be accessible from kernel space?  Can I pass a userspace
> > buffer pointer through to the LSM?
> 
> In fact, is the best way to do it to have a prototype like:
> 
> 	int security_key_getsecurity(struct key *key, char **_buffer);
> 
> Where the buffer is allocated by this function and attached to *_buffer and
> the length returned if successful (though that last is unnecessary if a
> NUL-terminated string is being returned); and if an error occurs, then that is
> returned instead.

Yes, sounds very similar to selinux_getprocattr(), just for keys rather
than tasks and w/o a name distinguisher for multiple attributes on the
task.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 14:58           ` David Howells
  2007-11-15 15:02             ` Stephen Smalley
@ 2007-11-15 16:04             ` David Howells
  2007-11-15 17:34             ` David Howells
  2007-11-15 20:40             ` James Morris
  3 siblings, 0 replies; 21+ messages in thread
From: David Howells @ 2007-11-15 16:04 UTC (permalink / raw)
  To: Stephen Smalley
  Cc: dhowells, Daniel J Walsh, Stefan Schulze Frielinghaus, selinux

Stephen Smalley <sds@tycho.nsa.gov> wrote:

> Yes, sounds very similar to selinux_getprocattr(), just for keys rather
> than tasks and w/o a name distinguisher for multiple attributes on the
> task.

Do I need the name distinguisher?

I've attached the patch I've come up with so far.

David
---
KEYS: Add keyctl function to get a security label

From: David Howells <dhowells@redhat.com>

Add a keyctl() function to get the security label of a key.

The following is added to Documentation/keys.txt:

 (*) Get the LSM security context attached to a key.

	long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
		    size_t buflen)

     This function returns a string that represents the LSM security context
     attached to a key in the buffer provided.

     Unless there's an error, it always returns the amount of data it could
     produce, even if that's too big for the buffer, but it won't copy more
     than requested to userspace. If the buffer pointer is NULL then no copy
     will take place.

     A NUL character is included at the end of the string if the buffer is
     sufficiently big.  This is included in the returned count.  If no LSM is
     in force then an empty string will be returned.

     A process must have view permission on the key for this function to be
     successful.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 Documentation/keys.txt   |   21 ++++++++++++++++
 include/linux/keyctl.h   |    1 +
 include/linux/security.h |   20 ++++++++++++++-
 security/dummy.c         |    8 ++++++
 security/keys/compat.c   |    3 ++
 security/keys/keyctl.c   |   61 ++++++++++++++++++++++++++++++++++++++++++++++
 security/security.c      |    5 ++++
 security/selinux/hooks.c |   21 ++++++++++++++--
 8 files changed, 136 insertions(+), 4 deletions(-)

diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index b82d38d..be424b0 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -711,6 +711,27 @@ The keyctl syscall functions are:
      The assumed authoritative key is inherited across fork and exec.
 
 
+ (*) Get the LSM security context attached to a key.
+
+	long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
+		    size_t buflen)
+
+     This function returns a string that represents the LSM security context
+     attached to a key in the buffer provided.
+
+     Unless there's an error, it always returns the amount of data it could
+     produce, even if that's too big for the buffer, but it won't copy more
+     than requested to userspace. If the buffer pointer is NULL then no copy
+     will take place.
+
+     A NUL character is included at the end of the string if the buffer is
+     sufficiently big.  This is included in the returned count.  If no LSM is
+     in force then an empty string will be returned.
+
+     A process must have view permission on the key for this function to be
+     successful.
+
+
 ===============
 KERNEL SERVICES
 ===============
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
index 3365945..656ee6b 100644
--- a/include/linux/keyctl.h
+++ b/include/linux/keyctl.h
@@ -49,5 +49,6 @@
 #define KEYCTL_SET_REQKEY_KEYRING	14	/* set default request-key keyring */
 #define KEYCTL_SET_TIMEOUT		15	/* set key timeout */
 #define KEYCTL_ASSUME_AUTHORITY		16	/* assume request_key() authorisation */
+#define KEYCTL_GET_SECURITY		17	/* get key security label */
 
 #endif /*  _LINUX_KEYCTL_H */
diff --git a/include/linux/security.h b/include/linux/security.h
index ac05083..8d9e946 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -959,6 +959,17 @@ struct request_sock;
  *	@perm describes the combination of permissions required of this key.
  *	Return 1 if permission granted, 0 if permission denied and -ve it the
  *      normal permissions model should be effected.
+ * @key_getsecurity:
+ *	Get a textual representation of the security context attached to a key
+ *	for the purposes of honouring KEYCTL_GETSECURITY.  This function
+ *	allocates the storage for the NUL-terminated string and the caller
+ *	should free it.
+ *	@key points to the key to be queried.
+ *	@_buffer points to a pointer that should be set to point to the
+ *	 resulting string (if no label or an error occurs).
+ *	Return the length of the string (including terminating NUL) or -ve if
+ *      an error.
+ *	May also return 0 (and a NULL buffer pointer) if there is no label.
  *
  * Security hooks affecting all System V IPC operations.
  *
@@ -1437,7 +1448,7 @@ struct security_operations {
 	int (*key_permission)(key_ref_t key_ref,
 			      struct task_struct *context,
 			      key_perm_t perm);
-
+	int (*key_getsecurity)(struct key *key, char **_buffer);
 #endif	/* CONFIG_KEYS */
 
 };
@@ -2567,6 +2578,7 @@ int security_key_alloc(struct key *key, struct task_struct *tsk, unsigned long f
 void security_key_free(struct key *key);
 int security_key_permission(key_ref_t key_ref,
 			    struct task_struct *context, key_perm_t perm);
+int security_key_getsecurity(struct key *key, char **_buffer);
 
 #else
 
@@ -2588,6 +2600,12 @@ static inline int security_key_permission(key_ref_t key_ref,
 	return 0;
 }
 
+static inline int security_key_getsecurity(struct key *key, char **_buffer)
+{
+	*_buffer = NULL;
+	return 0;
+}
+
 #endif
 #endif /* CONFIG_KEYS */
 
diff --git a/security/dummy.c b/security/dummy.c
index 6d895ad..7993b30 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -949,6 +949,13 @@ static inline int dummy_key_permission(key_ref_t key_ref,
 {
 	return 0;
 }
+
+static int dummy_key_getsecurity(struct key *key, char **_buffer)
+{
+	*_buffer = NULL;
+	return 0;
+}
+
 #endif /* CONFIG_KEYS */
 
 struct security_operations dummy_security_ops;
@@ -1133,6 +1140,7 @@ void security_fixup_ops (struct security_operations *ops)
 	set_to_dummy_if_null(ops, key_alloc);
 	set_to_dummy_if_null(ops, key_free);
 	set_to_dummy_if_null(ops, key_permission);
+	set_to_dummy_if_null(ops, key_getsecurity);
 #endif	/* CONFIG_KEYS */
 
 }
diff --git a/security/keys/compat.c b/security/keys/compat.c
index e10ec99..c766c68 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -79,6 +79,9 @@ asmlinkage long compat_sys_keyctl(u32 option,
 	case KEYCTL_ASSUME_AUTHORITY:
 		return keyctl_assume_authority(arg2);
 
+	case KEYCTL_GET_SECURITY:
+		return keyctl_get_security(arg2, compat_ptr(arg3), arg4);
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 1698bf9..4f71349 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/err.h>
 #include <linux/vmalloc.h>
+#include <linux/security.h>
 #include <asm/uaccess.h>
 #include "internal.h"
 
@@ -1080,6 +1081,66 @@ error:
 
 } /* end keyctl_assume_authority() */
 
+/*
+ * get the security label of a key
+ * - the key must grant us view permission
+ * - if there's a buffer, we place up to buflen bytes of data into it
+ * - unless there's an error, we return the amount of information available,
+ *   irrespective of how much we may have copied (including the terminal NUL)
+ * - implements keyctl(KEYCTL_GET_SECURITY)
+ */
+long keyctl_get_security(key_serial_t keyid,
+			 char __user *buffer,
+			 size_t buflen)
+{
+	struct key *key, *instkey;
+	key_ref_t key_ref;
+	char *context;
+	long ret;
+
+	key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
+	if (IS_ERR(key_ref)) {
+		if (PTR_ERR(key_ref) != -EACCES)
+			return PTR_ERR(key_ref);
+
+		/* viewing a key under construction is also permitted if we
+		 * have the authorisation token handy */
+		instkey = key_get_instantiation_authkey(keyid);
+		if (IS_ERR(instkey))
+			return PTR_ERR(key_ref);
+		key_put(instkey);
+
+		key_ref = lookup_user_key(NULL, keyid, 0, 1, 0);
+		if (IS_ERR(key_ref))
+			return PTR_ERR(key_ref);
+	}
+
+	key = key_ref_to_ptr(key_ref);
+	ret = security_key_getsecurity(key, &context);
+	if (ret == 0) {
+		/* if no information was returned, give userspace an empty
+		 * string */
+		ret = 1;
+		if (buffer && buflen > 0 &&
+		    copy_to_user(buffer, "", 1) != 0)
+			ret = -EFAULT;
+	} else if (ret > 0) {
+		/* return as much data as there's room for */
+		if (buffer && buflen > 0) {
+			if (buflen > ret)
+				buflen = ret;
+
+			if (copy_to_user(buffer, context, buflen) != 0)
+				ret = -EFAULT;
+		}
+
+		kfree(context);
+	}
+
+	key_ref_put(key_ref);
+	return ret;
+}
+
 /*****************************************************************************/
 /*
  * the key control system call
diff --git a/security/security.c b/security/security.c
index 0e1f1f1..16213e3 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1079,4 +1079,9 @@ int security_key_permission(key_ref_t key_ref,
 	return security_ops->key_permission(key_ref, context, perm);
 }
 
+int security_key_getsecurity(struct key *key, char **_buffer)
+{
+	return security_ops->key_getsecurity(key, _buffer);
+}
+
 #endif	/* CONFIG_KEYS */
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9f3124b..bf161f5 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4768,6 +4768,20 @@ static int selinux_key_permission(key_ref_t key_ref,
 			    SECCLASS_KEY, perm, NULL);
 }
 
+static int selinux_key_getsecurity(struct key *key, char **_buffer)
+{
+	struct key_security_struct *ksec = key->security;
+	char *context = NULL;
+	unsigned len;
+	int rc;
+
+	rc = security_sid_to_context(ksec->sid, &context, &len);
+	if (!rc)
+		rc = len;
+	*_buffer = context;
+	return len;
+}
+
 #endif
 
 static struct security_operations selinux_ops = {
@@ -4943,9 +4957,10 @@ static struct security_operations selinux_ops = {
 #endif
 
 #ifdef CONFIG_KEYS
-	.key_alloc =                    selinux_key_alloc,
-	.key_free =                     selinux_key_free,
-	.key_permission =               selinux_key_permission,
+	.key_alloc =			selinux_key_alloc,
+	.key_free =			selinux_key_free,
+	.key_permission =		selinux_key_permission,
+	.key_getsecurity =		selinux_key_getsecurity,
 #endif
 };
 

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 14:58           ` David Howells
  2007-11-15 15:02             ` Stephen Smalley
  2007-11-15 16:04             ` David Howells
@ 2007-11-15 17:34             ` David Howells
  2007-11-15 18:26               ` Stephen Smalley
                                 ` (2 more replies)
  2007-11-15 20:40             ` James Morris
  3 siblings, 3 replies; 21+ messages in thread
From: David Howells @ 2007-11-15 17:34 UTC (permalink / raw)
  Cc: dhowells, Stephen Smalley, Daniel J Walsh,
	Stefan Schulze Frielinghaus, selinux

David Howells <dhowells@redhat.com> wrote:

> I've attached the patch I've come up with so far.

Oops.  One error - I forgot to connect up the new function.

	# LD_PRELOAD=/tmp/libkeyutils-1.2.so /tmp/keyctl add user a a @s
	762693819
	# LD_PRELOAD=/tmp/libkeyutils-1.2.so /tmp/keyctl security 762693819
	root:system_r:unconfined_t:s0-s0:c0.c1023

That what you want?

New patch attached.

David
---
KEYS: Add keyctl function to get a security label

From: David Howells <dhowells@redhat.com>

Add a keyctl() function to get the security label of a key.

The following is added to Documentation/keys.txt:

 (*) Get the LSM security context attached to a key.

	long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
		    size_t buflen)

     This function returns a string that represents the LSM security context
     attached to a key in the buffer provided.

     Unless there's an error, it always returns the amount of data it could
     produce, even if that's too big for the buffer, but it won't copy more
     than requested to userspace. If the buffer pointer is NULL then no copy
     will take place.

     A NUL character is included at the end of the string if the buffer is
     sufficiently big.  This is included in the returned count.  If no LSM is
     in force then an empty string will be returned.

     A process must have view permission on the key for this function to be
     successful.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 Documentation/keys.txt   |   21 +++++++++++++++
 include/linux/keyctl.h   |    1 +
 include/linux/security.h |   20 +++++++++++++-
 security/dummy.c         |    8 ++++++
 security/keys/compat.c   |    3 ++
 security/keys/keyctl.c   |   66 ++++++++++++++++++++++++++++++++++++++++++++++
 security/security.c      |    5 +++
 security/selinux/hooks.c |   21 +++++++++++++--
 8 files changed, 141 insertions(+), 4 deletions(-)

diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index b82d38d..be424b0 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -711,6 +711,27 @@ The keyctl syscall functions are:
      The assumed authoritative key is inherited across fork and exec.
 
 
+ (*) Get the LSM security context attached to a key.
+
+	long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
+		    size_t buflen)
+
+     This function returns a string that represents the LSM security context
+     attached to a key in the buffer provided.
+
+     Unless there's an error, it always returns the amount of data it could
+     produce, even if that's too big for the buffer, but it won't copy more
+     than requested to userspace. If the buffer pointer is NULL then no copy
+     will take place.
+
+     A NUL character is included at the end of the string if the buffer is
+     sufficiently big.  This is included in the returned count.  If no LSM is
+     in force then an empty string will be returned.
+
+     A process must have view permission on the key for this function to be
+     successful.
+
+
 ===============
 KERNEL SERVICES
 ===============
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
index 3365945..656ee6b 100644
--- a/include/linux/keyctl.h
+++ b/include/linux/keyctl.h
@@ -49,5 +49,6 @@
 #define KEYCTL_SET_REQKEY_KEYRING	14	/* set default request-key keyring */
 #define KEYCTL_SET_TIMEOUT		15	/* set key timeout */
 #define KEYCTL_ASSUME_AUTHORITY		16	/* assume request_key() authorisation */
+#define KEYCTL_GET_SECURITY		17	/* get key security label */
 
 #endif /*  _LINUX_KEYCTL_H */
diff --git a/include/linux/security.h b/include/linux/security.h
index ac05083..8d9e946 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -959,6 +959,17 @@ struct request_sock;
  *	@perm describes the combination of permissions required of this key.
  *	Return 1 if permission granted, 0 if permission denied and -ve it the
  *      normal permissions model should be effected.
+ * @key_getsecurity:
+ *	Get a textual representation of the security context attached to a key
+ *	for the purposes of honouring KEYCTL_GETSECURITY.  This function
+ *	allocates the storage for the NUL-terminated string and the caller
+ *	should free it.
+ *	@key points to the key to be queried.
+ *	@_buffer points to a pointer that should be set to point to the
+ *	 resulting string (if no label or an error occurs).
+ *	Return the length of the string (including terminating NUL) or -ve if
+ *      an error.
+ *	May also return 0 (and a NULL buffer pointer) if there is no label.
  *
  * Security hooks affecting all System V IPC operations.
  *
@@ -1437,7 +1448,7 @@ struct security_operations {
 	int (*key_permission)(key_ref_t key_ref,
 			      struct task_struct *context,
 			      key_perm_t perm);
-
+	int (*key_getsecurity)(struct key *key, char **_buffer);
 #endif	/* CONFIG_KEYS */
 
 };
@@ -2567,6 +2578,7 @@ int security_key_alloc(struct key *key, struct task_struct *tsk, unsigned long f
 void security_key_free(struct key *key);
 int security_key_permission(key_ref_t key_ref,
 			    struct task_struct *context, key_perm_t perm);
+int security_key_getsecurity(struct key *key, char **_buffer);
 
 #else
 
@@ -2588,6 +2600,12 @@ static inline int security_key_permission(key_ref_t key_ref,
 	return 0;
 }
 
+static inline int security_key_getsecurity(struct key *key, char **_buffer)
+{
+	*_buffer = NULL;
+	return 0;
+}
+
 #endif
 #endif /* CONFIG_KEYS */
 
diff --git a/security/dummy.c b/security/dummy.c
index 6d895ad..7993b30 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -949,6 +949,13 @@ static inline int dummy_key_permission(key_ref_t key_ref,
 {
 	return 0;
 }
+
+static int dummy_key_getsecurity(struct key *key, char **_buffer)
+{
+	*_buffer = NULL;
+	return 0;
+}
+
 #endif /* CONFIG_KEYS */
 
 struct security_operations dummy_security_ops;
@@ -1133,6 +1140,7 @@ void security_fixup_ops (struct security_operations *ops)
 	set_to_dummy_if_null(ops, key_alloc);
 	set_to_dummy_if_null(ops, key_free);
 	set_to_dummy_if_null(ops, key_permission);
+	set_to_dummy_if_null(ops, key_getsecurity);
 #endif	/* CONFIG_KEYS */
 
 }
diff --git a/security/keys/compat.c b/security/keys/compat.c
index e10ec99..c766c68 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -79,6 +79,9 @@ asmlinkage long compat_sys_keyctl(u32 option,
 	case KEYCTL_ASSUME_AUTHORITY:
 		return keyctl_assume_authority(arg2);
 
+	case KEYCTL_GET_SECURITY:
+		return keyctl_get_security(arg2, compat_ptr(arg3), arg4);
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 1698bf9..56e963b 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/err.h>
 #include <linux/vmalloc.h>
+#include <linux/security.h>
 #include <asm/uaccess.h>
 #include "internal.h"
 
@@ -1080,6 +1081,66 @@ error:
 
 } /* end keyctl_assume_authority() */
 
+/*
+ * get the security label of a key
+ * - the key must grant us view permission
+ * - if there's a buffer, we place up to buflen bytes of data into it
+ * - unless there's an error, we return the amount of information available,
+ *   irrespective of how much we may have copied (including the terminal NUL)
+ * - implements keyctl(KEYCTL_GET_SECURITY)
+ */
+long keyctl_get_security(key_serial_t keyid,
+			 char __user *buffer,
+			 size_t buflen)
+{
+	struct key *key, *instkey;
+	key_ref_t key_ref;
+	char *context;
+	long ret;
+
+	key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
+	if (IS_ERR(key_ref)) {
+		if (PTR_ERR(key_ref) != -EACCES)
+			return PTR_ERR(key_ref);
+
+		/* viewing a key under construction is also permitted if we
+		 * have the authorisation token handy */
+		instkey = key_get_instantiation_authkey(keyid);
+		if (IS_ERR(instkey))
+			return PTR_ERR(key_ref);
+		key_put(instkey);
+
+		key_ref = lookup_user_key(NULL, keyid, 0, 1, 0);
+		if (IS_ERR(key_ref))
+			return PTR_ERR(key_ref);
+	}
+
+	key = key_ref_to_ptr(key_ref);
+	ret = security_key_getsecurity(key, &context);
+	if (ret == 0) {
+		/* if no information was returned, give userspace an empty
+		 * string */
+		ret = 1;
+		if (buffer && buflen > 0 &&
+		    copy_to_user(buffer, "", 1) != 0)
+			ret = -EFAULT;
+	} else if (ret > 0) {
+		/* return as much data as there's room for */
+		if (buffer && buflen > 0) {
+			if (buflen > ret)
+				buflen = ret;
+
+			if (copy_to_user(buffer, context, buflen) != 0)
+				ret = -EFAULT;
+		}
+
+		kfree(context);
+	}
+
+	key_ref_put(key_ref);
+	return ret;
+}
+
 /*****************************************************************************/
 /*
  * the key control system call
@@ -1160,6 +1221,11 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
 	case KEYCTL_ASSUME_AUTHORITY:
 		return keyctl_assume_authority((key_serial_t) arg2);
 
+	case KEYCTL_GET_SECURITY:
+		return keyctl_get_security((key_serial_t) arg2,
+					   (char *) arg3,
+					   (size_t) arg4);
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/security/security.c b/security/security.c
index 0e1f1f1..16213e3 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1079,4 +1079,9 @@ int security_key_permission(key_ref_t key_ref,
 	return security_ops->key_permission(key_ref, context, perm);
 }
 
+int security_key_getsecurity(struct key *key, char **_buffer)
+{
+	return security_ops->key_getsecurity(key, _buffer);
+}
+
 #endif	/* CONFIG_KEYS */
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9f3124b..bf161f5 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4768,6 +4768,20 @@ static int selinux_key_permission(key_ref_t key_ref,
 			    SECCLASS_KEY, perm, NULL);
 }
 
+static int selinux_key_getsecurity(struct key *key, char **_buffer)
+{
+	struct key_security_struct *ksec = key->security;
+	char *context = NULL;
+	unsigned len;
+	int rc;
+
+	rc = security_sid_to_context(ksec->sid, &context, &len);
+	if (!rc)
+		rc = len;
+	*_buffer = context;
+	return len;
+}
+
 #endif
 
 static struct security_operations selinux_ops = {
@@ -4943,9 +4957,10 @@ static struct security_operations selinux_ops = {
 #endif
 
 #ifdef CONFIG_KEYS
-	.key_alloc =                    selinux_key_alloc,
-	.key_free =                     selinux_key_free,
-	.key_permission =               selinux_key_permission,
+	.key_alloc =			selinux_key_alloc,
+	.key_free =			selinux_key_free,
+	.key_permission =		selinux_key_permission,
+	.key_getsecurity =		selinux_key_getsecurity,
 #endif
 };
 

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 17:34             ` David Howells
@ 2007-11-15 18:26               ` Stephen Smalley
  2007-11-15 19:04               ` David Howells
  2007-11-16 19:53               ` Casey Schaufler
  2 siblings, 0 replies; 21+ messages in thread
From: Stephen Smalley @ 2007-11-15 18:26 UTC (permalink / raw)
  To: David Howells; +Cc: Daniel J Walsh, Stefan Schulze Frielinghaus, selinux

On Thu, 2007-11-15 at 17:34 +0000, David Howells wrote:
> David Howells <dhowells@redhat.com> wrote:
> 
> > I've attached the patch I've come up with so far.
> 
> Oops.  One error - I forgot to connect up the new function.
> 
> 	# LD_PRELOAD=/tmp/libkeyutils-1.2.so /tmp/keyctl add user a a @s
> 	762693819
> 	# LD_PRELOAD=/tmp/libkeyutils-1.2.so /tmp/keyctl security 762693819
> 	root:system_r:unconfined_t:s0-s0:c0.c1023
> 
> That what you want?
> 
> New patch attached.
> 
> David
> ---
> KEYS: Add keyctl function to get a security label
> 
> From: David Howells <dhowells@redhat.com>
> 
> Add a keyctl() function to get the security label of a key.
> 
> The following is added to Documentation/keys.txt:
> 
>  (*) Get the LSM security context attached to a key.
> 
> 	long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
> 		    size_t buflen)
> 
>      This function returns a string that represents the LSM security context
>      attached to a key in the buffer provided.
> 
>      Unless there's an error, it always returns the amount of data it could
>      produce, even if that's too big for the buffer, but it won't copy more
>      than requested to userspace. If the buffer pointer is NULL then no copy
>      will take place.
> 
>      A NUL character is included at the end of the string if the buffer is
>      sufficiently big.  This is included in the returned count.  If no LSM is
>      in force then an empty string will be returned.
> 
>      A process must have view permission on the key for this function to be
>      successful.
> 
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
> 
>  Documentation/keys.txt   |   21 +++++++++++++++
>  include/linux/keyctl.h   |    1 +
>  include/linux/security.h |   20 +++++++++++++-
>  security/dummy.c         |    8 ++++++
>  security/keys/compat.c   |    3 ++
>  security/keys/keyctl.c   |   66 ++++++++++++++++++++++++++++++++++++++++++++++
>  security/security.c      |    5 +++
>  security/selinux/hooks.c |   21 +++++++++++++--
>  8 files changed, 141 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/keys.txt b/Documentation/keys.txt
> index b82d38d..be424b0 100644
> --- a/Documentation/keys.txt
> +++ b/Documentation/keys.txt
> @@ -711,6 +711,27 @@ The keyctl syscall functions are:
>       The assumed authoritative key is inherited across fork and exec.
>  
> 
> + (*) Get the LSM security context attached to a key.
> +
> +	long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
> +		    size_t buflen)
> +
> +     This function returns a string that represents the LSM security context
> +     attached to a key in the buffer provided.
> +
> +     Unless there's an error, it always returns the amount of data it could
> +     produce, even if that's too big for the buffer, but it won't copy more
> +     than requested to userspace. If the buffer pointer is NULL then no copy
> +     will take place.
> +
> +     A NUL character is included at the end of the string if the buffer is
> +     sufficiently big.  This is included in the returned count.  If no LSM is
> +     in force then an empty string will be returned.
> +
> +     A process must have view permission on the key for this function to be
> +     successful.
> +
> +
>  ===============
>  KERNEL SERVICES
>  ===============
> diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
> index 3365945..656ee6b 100644
> --- a/include/linux/keyctl.h
> +++ b/include/linux/keyctl.h
> @@ -49,5 +49,6 @@
>  #define KEYCTL_SET_REQKEY_KEYRING	14	/* set default request-key keyring */
>  #define KEYCTL_SET_TIMEOUT		15	/* set key timeout */
>  #define KEYCTL_ASSUME_AUTHORITY		16	/* assume request_key() authorisation */
> +#define KEYCTL_GET_SECURITY		17	/* get key security label */
>  
>  #endif /*  _LINUX_KEYCTL_H */
> diff --git a/include/linux/security.h b/include/linux/security.h
> index ac05083..8d9e946 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -959,6 +959,17 @@ struct request_sock;
>   *	@perm describes the combination of permissions required of this key.
>   *	Return 1 if permission granted, 0 if permission denied and -ve it the
>   *      normal permissions model should be effected.
> + * @key_getsecurity:
> + *	Get a textual representation of the security context attached to a key
> + *	for the purposes of honouring KEYCTL_GETSECURITY.  This function
> + *	allocates the storage for the NUL-terminated string and the caller
> + *	should free it.
> + *	@key points to the key to be queried.
> + *	@_buffer points to a pointer that should be set to point to the
> + *	 resulting string (if no label or an error occurs).
> + *	Return the length of the string (including terminating NUL) or -ve if
> + *      an error.
> + *	May also return 0 (and a NULL buffer pointer) if there is no label.
>   *
>   * Security hooks affecting all System V IPC operations.
>   *
> @@ -1437,7 +1448,7 @@ struct security_operations {
>  	int (*key_permission)(key_ref_t key_ref,
>  			      struct task_struct *context,
>  			      key_perm_t perm);
> -
> +	int (*key_getsecurity)(struct key *key, char **_buffer);
>  #endif	/* CONFIG_KEYS */
>  
>  };
> @@ -2567,6 +2578,7 @@ int security_key_alloc(struct key *key, struct task_struct *tsk, unsigned long f
>  void security_key_free(struct key *key);
>  int security_key_permission(key_ref_t key_ref,
>  			    struct task_struct *context, key_perm_t perm);
> +int security_key_getsecurity(struct key *key, char **_buffer);
>  
>  #else
>  
> @@ -2588,6 +2600,12 @@ static inline int security_key_permission(key_ref_t key_ref,
>  	return 0;
>  }
>  
> +static inline int security_key_getsecurity(struct key *key, char **_buffer)
> +{
> +	*_buffer = NULL;
> +	return 0;
> +}
> +
>  #endif
>  #endif /* CONFIG_KEYS */
>  
> diff --git a/security/dummy.c b/security/dummy.c
> index 6d895ad..7993b30 100644
> --- a/security/dummy.c
> +++ b/security/dummy.c
> @@ -949,6 +949,13 @@ static inline int dummy_key_permission(key_ref_t key_ref,
>  {
>  	return 0;
>  }
> +
> +static int dummy_key_getsecurity(struct key *key, char **_buffer)
> +{
> +	*_buffer = NULL;
> +	return 0;
> +}
> +
>  #endif /* CONFIG_KEYS */
>  
>  struct security_operations dummy_security_ops;
> @@ -1133,6 +1140,7 @@ void security_fixup_ops (struct security_operations *ops)
>  	set_to_dummy_if_null(ops, key_alloc);
>  	set_to_dummy_if_null(ops, key_free);
>  	set_to_dummy_if_null(ops, key_permission);
> +	set_to_dummy_if_null(ops, key_getsecurity);
>  #endif	/* CONFIG_KEYS */
>  
>  }
> diff --git a/security/keys/compat.c b/security/keys/compat.c
> index e10ec99..c766c68 100644
> --- a/security/keys/compat.c
> +++ b/security/keys/compat.c
> @@ -79,6 +79,9 @@ asmlinkage long compat_sys_keyctl(u32 option,
>  	case KEYCTL_ASSUME_AUTHORITY:
>  		return keyctl_assume_authority(arg2);
>  
> +	case KEYCTL_GET_SECURITY:
> +		return keyctl_get_security(arg2, compat_ptr(arg3), arg4);
> +
>  	default:
>  		return -EOPNOTSUPP;
>  	}
> diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
> index 1698bf9..56e963b 100644
> --- a/security/keys/keyctl.c
> +++ b/security/keys/keyctl.c
> @@ -20,6 +20,7 @@
>  #include <linux/string.h>
>  #include <linux/err.h>
>  #include <linux/vmalloc.h>
> +#include <linux/security.h>
>  #include <asm/uaccess.h>
>  #include "internal.h"
>  
> @@ -1080,6 +1081,66 @@ error:
>  
>  } /* end keyctl_assume_authority() */
>  
> +/*
> + * get the security label of a key
> + * - the key must grant us view permission
> + * - if there's a buffer, we place up to buflen bytes of data into it
> + * - unless there's an error, we return the amount of information available,
> + *   irrespective of how much we may have copied (including the terminal NUL)
> + * - implements keyctl(KEYCTL_GET_SECURITY)
> + */
> +long keyctl_get_security(key_serial_t keyid,
> +			 char __user *buffer,
> +			 size_t buflen)
> +{
> +	struct key *key, *instkey;
> +	key_ref_t key_ref;
> +	char *context;
> +	long ret;
> +
> +	key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
> +	if (IS_ERR(key_ref)) {
> +		if (PTR_ERR(key_ref) != -EACCES)
> +			return PTR_ERR(key_ref);
> +
> +		/* viewing a key under construction is also permitted if we
> +		 * have the authorisation token handy */
> +		instkey = key_get_instantiation_authkey(keyid);
> +		if (IS_ERR(instkey))
> +			return PTR_ERR(key_ref);
> +		key_put(instkey);
> +
> +		key_ref = lookup_user_key(NULL, keyid, 0, 1, 0);
> +		if (IS_ERR(key_ref))
> +			return PTR_ERR(key_ref);
> +	}
> +
> +	key = key_ref_to_ptr(key_ref);
> +	ret = security_key_getsecurity(key, &context);
> +	if (ret == 0) {
> +		/* if no information was returned, give userspace an empty
> +		 * string */
> +		ret = 1;
> +		if (buffer && buflen > 0 &&
> +		    copy_to_user(buffer, "", 1) != 0)
> +			ret = -EFAULT;
> +	} else if (ret > 0) {
> +		/* return as much data as there's room for */
> +		if (buffer && buflen > 0) {
> +			if (buflen > ret)
> +				buflen = ret;
> +
> +			if (copy_to_user(buffer, context, buflen) != 0)
> +				ret = -EFAULT;
> +		}
> +
> +		kfree(context);
> +	}
> +
> +	key_ref_put(key_ref);
> +	return ret;
> +}
> +
>  /*****************************************************************************/
>  /*
>   * the key control system call
> @@ -1160,6 +1221,11 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
>  	case KEYCTL_ASSUME_AUTHORITY:
>  		return keyctl_assume_authority((key_serial_t) arg2);
>  
> +	case KEYCTL_GET_SECURITY:
> +		return keyctl_get_security((key_serial_t) arg2,
> +					   (char *) arg3,
> +					   (size_t) arg4);
> +
>  	default:
>  		return -EOPNOTSUPP;
>  	}
> diff --git a/security/security.c b/security/security.c
> index 0e1f1f1..16213e3 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -1079,4 +1079,9 @@ int security_key_permission(key_ref_t key_ref,
>  	return security_ops->key_permission(key_ref, context, perm);
>  }
>  
> +int security_key_getsecurity(struct key *key, char **_buffer)
> +{
> +	return security_ops->key_getsecurity(key, _buffer);
> +}
> +
>  #endif	/* CONFIG_KEYS */
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 9f3124b..bf161f5 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -4768,6 +4768,20 @@ static int selinux_key_permission(key_ref_t key_ref,
>  			    SECCLASS_KEY, perm, NULL);
>  }
>  
> +static int selinux_key_getsecurity(struct key *key, char **_buffer)
> +{
> +	struct key_security_struct *ksec = key->security;
> +	char *context = NULL;
> +	unsigned len;
> +	int rc;
> +
> +	rc = security_sid_to_context(ksec->sid, &context, &len);
> +	if (!rc)
> +		rc = len;
> +	*_buffer = context;
> +	return len;

return rc?

> +}
> +
>  #endif
>  
>  static struct security_operations selinux_ops = {
> @@ -4943,9 +4957,10 @@ static struct security_operations selinux_ops = {
>  #endif
>  
>  #ifdef CONFIG_KEYS
> -	.key_alloc =                    selinux_key_alloc,
> -	.key_free =                     selinux_key_free,
> -	.key_permission =               selinux_key_permission,
> +	.key_alloc =			selinux_key_alloc,
> +	.key_free =			selinux_key_free,
> +	.key_permission =		selinux_key_permission,
> +	.key_getsecurity =		selinux_key_getsecurity,
>  #endif
>  };
>  
-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 17:34             ` David Howells
  2007-11-15 18:26               ` Stephen Smalley
@ 2007-11-15 19:04               ` David Howells
  2007-11-16 19:53               ` Casey Schaufler
  2 siblings, 0 replies; 21+ messages in thread
From: David Howells @ 2007-11-15 19:04 UTC (permalink / raw)
  To: Stephen Smalley
  Cc: dhowells, Daniel J Walsh, Stefan Schulze Frielinghaus, selinux

Stephen Smalley <sds@tycho.nsa.gov> wrote:

> > +	rc = security_sid_to_context(ksec->sid, &context, &len);
> > +	if (!rc)
> > +		rc = len;
> > +	*_buffer = context;
> > +	return len;
> 
> return rc?

Good point.

David

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 14:58           ` David Howells
                               ` (2 preceding siblings ...)
  2007-11-15 17:34             ` David Howells
@ 2007-11-15 20:40             ` James Morris
  3 siblings, 0 replies; 21+ messages in thread
From: James Morris @ 2007-11-15 20:40 UTC (permalink / raw)
  To: David Howells
  Cc: Daniel J Walsh, Stephen Smalley, Stefan Schulze Frielinghaus, selinux

btw, please cc linux-security-module@vger.kernel.org with any patches 
which touch code outside of the selinux directory.


-- 
James Morris
<jmorris@namei.org>

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [Fwd: type class key]
  2007-11-15 17:34             ` David Howells
  2007-11-15 18:26               ` Stephen Smalley
  2007-11-15 19:04               ` David Howells
@ 2007-11-16 19:53               ` Casey Schaufler
  2 siblings, 0 replies; 21+ messages in thread
From: Casey Schaufler @ 2007-11-16 19:53 UTC (permalink / raw)
  To: David Howells
  Cc: dhowells, Stephen Smalley, Daniel J Walsh,
	Stefan Schulze Frielinghaus, selinux


--- David Howells <dhowells@redhat.com> wrote:

> David Howells <dhowells@redhat.com> wrote:
> 
> > I've attached the patch I've come up with so far.
> 
> Oops.  One error - I forgot to connect up the new function.
> 
> 	# LD_PRELOAD=/tmp/libkeyutils-1.2.so /tmp/keyctl add user a a @s
> 	762693819
> 	# LD_PRELOAD=/tmp/libkeyutils-1.2.so /tmp/keyctl security 762693819
> 	root:system_r:unconfined_t:s0-s0:c0.c1023
> 
> That what you want?
> 
> New patch attached.
> 
> David
> ---
> KEYS: Add keyctl function to get a security label
> 
> From: David Howells <dhowells@redhat.com>
> 
> Add a keyctl() function to get the security label of a key.
> 
> The following is added to Documentation/keys.txt:
> 
>  (*) Get the LSM security context attached to a key.
> 
> 	long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
> 		    size_t buflen)
> 
>      This function returns a string that represents the LSM security context
>      attached to a key in the buffer provided.
> 
>      Unless there's an error, it always returns the amount of data it could
>      produce, even if that's too big for the buffer, but it won't copy more
>      than requested to userspace. If the buffer pointer is NULL then no copy
>      will take place.
> 
>      A NUL character is included at the end of the string if the buffer is
>      sufficiently big.  This is included in the returned count.  If no LSM is
>      in force then an empty string will be returned.
> 
>      A process must have view permission on the key for this function to be
>      successful.
> 
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
> 
>  Documentation/keys.txt   |   21 +++++++++++++++
>  include/linux/keyctl.h   |    1 +
>  include/linux/security.h |   20 +++++++++++++-
>  security/dummy.c         |    8 ++++++
>  security/keys/compat.c   |    3 ++
>  security/keys/keyctl.c   |   66
> ++++++++++++++++++++++++++++++++++++++++++++++
>  security/security.c      |    5 +++
>  security/selinux/hooks.c |   21 +++++++++++++--
>  8 files changed, 141 insertions(+), 4 deletions(-)

If you're changing the LSM interface you should cross post this to
the LSM list.


Casey Schaufler
casey@schaufler-ca.com

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

end of thread, other threads:[~2007-11-16 19:54 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1194628263.3630.14.camel@vogon>
     [not found] ` <1194554589.3198.24.camel@moss-spartans.epoch.ncsc.mil>
     [not found]   ` <24708.1194612682@redhat.com>
     [not found]     ` <22421.1194637689@redhat.com>
2007-11-09 19:51       ` [Fwd: type class key] Stephen Smalley
2007-11-09 20:00         ` Stephen Smalley
2007-11-09 20:35           ` Casey Schaufler
2007-11-10 12:26         ` David Howells
2007-11-14 20:23           ` Daniel J Walsh
2007-11-15 12:17           ` David Howells
2007-11-15 13:33             ` Daniel J Walsh
2007-11-15 13:57             ` Stephen Smalley
2007-11-15 14:41             ` David Howells
2007-11-15 14:52               ` Stephen Smalley
2007-11-15 14:53           ` David Howells
2007-11-15 14:56             ` Stephen Smalley
2007-11-15 14:58           ` David Howells
2007-11-15 15:02             ` Stephen Smalley
2007-11-15 16:04             ` David Howells
2007-11-15 17:34             ` David Howells
2007-11-15 18:26               ` Stephen Smalley
2007-11-15 19:04               ` David Howells
2007-11-16 19:53               ` Casey Schaufler
2007-11-15 20:40             ` James Morris
2007-11-15 13:08         ` David Howells

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.