* 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 0 siblings, 1 reply; 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 ` (2 more replies) 0 siblings, 3 replies; 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 2007-11-10 12:26 ` David Howells 2007-11-15 13:08 ` David Howells 2 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 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 13:08 ` David Howells 2 siblings, 1 reply; 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 2007-11-15 14:53 ` David Howells 0 siblings, 2 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-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:53 ` David Howells 1 sibling, 2 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-15 12:17 ` David Howells @ 2007-11-15 13:33 ` Daniel J Walsh 2007-11-15 13:57 ` Stephen Smalley 1 sibling, 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 1 sibling, 1 reply; 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 13:57 ` Stephen Smalley @ 2007-11-15 14:41 ` David Howells 2007-11-15 14:52 ` Stephen Smalley 0 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-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 1 sibling, 2 replies; 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 2007-11-15 14:58 ` David Howells 1 sibling, 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-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 20:40 ` James Morris 1 sibling, 2 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 2007-11-15 20:40 ` James Morris 1 sibling, 1 reply; 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 15:02 ` Stephen Smalley @ 2007-11-15 16:04 ` David Howells 2007-11-15 17:34 ` David Howells 0 siblings, 1 reply; 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 16:04 ` David Howells @ 2007-11-15 17:34 ` David Howells 2007-11-15 18:26 ` Stephen Smalley 2007-11-16 19:53 ` Casey Schaufler 0 siblings, 2 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 1 sibling, 1 reply; 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 18:26 ` Stephen Smalley @ 2007-11-15 19:04 ` David Howells 0 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 17:34 ` David Howells 2007-11-15 18:26 ` Stephen Smalley @ 2007-11-16 19:53 ` Casey Schaufler 1 sibling, 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
* Re: [Fwd: type class key] 2007-11-15 14:58 ` David Howells 2007-11-15 15:02 ` Stephen Smalley @ 2007-11-15 20:40 ` James Morris 1 sibling, 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-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, 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
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.