Re: [PATCH 2/3] selinux: add checksum to policydb

2017-04-27 Thread Stephen Smalley
On Thu, 2017-04-27 at 19:12 +0200, Sebastien Buisson wrote:
> 2017-04-27 17:18 GMT+02:00 Stephen Smalley :
> > Ok, that should work as long as you just want to validate that all
> > the
> > clients loaded the same policy file, and aren't concerned about
> > non-
> > persistent policy boolean changes.
> 
> As far as I understand, non-persistent policy boolean changes can
> affect the way the policy is enforced. So that is a problem if the
> checksum does not reflect it. We want to protect against someone
> tampering the policy locally on a Lustre client, even if it does not
> survive a reboot.

A boolean change can affect which TE rules in the policy are
enabled/disabled, but only in ways that are defined by the original
policy.  You can't add arbitrary TE rules that way, just enable/disable
blocks that were defined conditionally in the policy.  It also has no
effect on MLS enforcement, for example.  So it depends on your goals.

> I just checked, with the method of computing the checksum on a (data,
> len) pair on entry to security_load_policy() the checksum does not
> change after using setsebool. So it seems I would need to call
> security_read_policy() to retrieve the binary representation of the
> policy as currently enforced by the kernel. Unless you can see
> another
> way?

I don't think that's a viable option, since security_read_policy() is
going to be expensive in order to generate a full policy image, while
security_set_bools() is supposed to be substantially cheaper than a
full policy load.

Also, the advantage of taking the hash of the original input file is
that you can independently compute a reference hash offline or on the
server from the same policy file and compare them and you can identify
which policy file was loaded based on the hash.

If you care about the active boolean state, then I'd suggest hashing
the active boolean state separately and storing that after the policy
hash.  You can do that in both security_load_policy() and
security_set_bools().  Just iterate through the bools like
security_set_bools() does, write the ->state of each boolean into a
buffer, and then hash that buffer.

> > You needed to get (global) enforcing mode too, didn't you?  That's
> > separate from the policy.
> 
> Exactly, I also need to rework the patch I proposed about this, in
> light of the comments I received.

So perhaps what you really want is a hook interface and a selinuxfs
interface that returns a single string that encodes all of the policy
properties that you care about?  Rather than separate hooks and
interfaces?  You could embed the enforcing status in the string too. 
Should probably include checkreqprot as well since that affects
enforcement of mmap/mprotect checks.

> > Make sure you make the hash algorithm explicit in both what is
> > returned
> > by the hook to lustre and by what is exported via selinuxfs.  Can
> > likely just encode the hash algorithm name in the string when you
> > generate it.
> 
> Sure, I will add "sha256:" at the beginning of the string.


Re: [PATCH 2/3] selinux: add checksum to policydb

2017-04-27 Thread Stephen Smalley
On Thu, 2017-04-27 at 10:41 +0200, Sebastien Buisson wrote:
> 2017-04-26 20:30 GMT+02:00 Stephen Smalley <s...@tycho.nsa.gov>:
> > This seems like an odd place to trigger the computation.
> 
> I noticed that the policy as exposed via /sys/fs/selinux/policy can
> also be modified in security_set_bools().

That's true, but does that matter for your use case?  Do you care about
non-persistent boolean changes? What is the property you want to
ensure?

>  So in order to limit the
> places from where to compute the policy checksum, I moved the call to
> checksum computation to selinux_lsm_notifier_avc_callback().
> That being said, maybe the hash of /sys/fs/selinux/policy is not the
> checksum we want. See your comments and my answers below.
> 
> > Why aren't you
> > just computing it when the policy is loaded directly in
> > security_load_policy()?  You already have the (data, len) on entry
> > to
> > that function.  Just compute it at load time, save it, and be
> > done.  No
> > need for a notifier then for your use case unless I am missing
> > something.
> 
> You are right. Getting from the Lustre client code the SELinux
> internally computed checksum is cheap, so no need to be notified
> every
> time the policy changes, and no need to store the checksum in Lustre
> at that time.
> I will drop the "Implement LSM notification system" patch from this
> series, as I cannot justify its usefulness from a Lustre client
> standpoint anymore.
> 
> > I suppose the question is which checksum do you want - the hash of
> > the
> > policy file that was written to /sys/fs/selinux/load by userspace,
> > or
> > the hash of the policy file that the kernel generates on demand if
> > you
> > open /sys/fs/selinux/policy.  Those can differ in non-semantic ways
> > due
> > to ordering differences, for example.  I think the former is more
> > likely to be of interest to userspace (e.g. to compare the hash
> > value
> > against the hash of the policy file), and is cheaper since you
> > already
> > have a (data, len) pair on entry to security_load_policy() that you
> > can
> > hash immediately rather than requiring the kernel to regenerate the
> > image from the policydb.
> 
> OK, I understand now why I was seeing differences between the
> checksum
> computed on a (data, len) pair on entry to security_load_policy(),
> and
> the checksum computed on a (data, len) pair got from
> security_read_policy().
> I thought it was a problem to have a difference between the
> internally
> computed checksum and the one a user can get by calling sha256sum on
> /sys/fs/selinux/policy. But now I see it makes sense to reflect what
> was loaded by userspace. So I will simplify this patch accordingly.

Ok, that should work as long as you just want to validate that all the
clients loaded the same policy file, and aren't concerned about non-
persistent policy boolean changes.

You needed to get (global) enforcing mode too, didn't you?  That's
separate from the policy.

Make sure you make the hash algorithm explicit in both what is returned
by the hook to lustre and by what is exported via selinuxfs.  Can
likely just encode the hash algorithm name in the string when you
generate it.



Re: [PATCH 2/3] selinux: add checksum to policydb

2017-04-27 Thread Stephen Smalley
On Thu, 2017-04-27 at 10:41 +0200, Sebastien Buisson wrote:
> 2017-04-26 20:30 GMT+02:00 Stephen Smalley :
> > This seems like an odd place to trigger the computation.
> 
> I noticed that the policy as exposed via /sys/fs/selinux/policy can
> also be modified in security_set_bools().

That's true, but does that matter for your use case?  Do you care about
non-persistent boolean changes? What is the property you want to
ensure?

>  So in order to limit the
> places from where to compute the policy checksum, I moved the call to
> checksum computation to selinux_lsm_notifier_avc_callback().
> That being said, maybe the hash of /sys/fs/selinux/policy is not the
> checksum we want. See your comments and my answers below.
> 
> > Why aren't you
> > just computing it when the policy is loaded directly in
> > security_load_policy()?  You already have the (data, len) on entry
> > to
> > that function.  Just compute it at load time, save it, and be
> > done.  No
> > need for a notifier then for your use case unless I am missing
> > something.
> 
> You are right. Getting from the Lustre client code the SELinux
> internally computed checksum is cheap, so no need to be notified
> every
> time the policy changes, and no need to store the checksum in Lustre
> at that time.
> I will drop the "Implement LSM notification system" patch from this
> series, as I cannot justify its usefulness from a Lustre client
> standpoint anymore.
> 
> > I suppose the question is which checksum do you want - the hash of
> > the
> > policy file that was written to /sys/fs/selinux/load by userspace,
> > or
> > the hash of the policy file that the kernel generates on demand if
> > you
> > open /sys/fs/selinux/policy.  Those can differ in non-semantic ways
> > due
> > to ordering differences, for example.  I think the former is more
> > likely to be of interest to userspace (e.g. to compare the hash
> > value
> > against the hash of the policy file), and is cheaper since you
> > already
> > have a (data, len) pair on entry to security_load_policy() that you
> > can
> > hash immediately rather than requiring the kernel to regenerate the
> > image from the policydb.
> 
> OK, I understand now why I was seeing differences between the
> checksum
> computed on a (data, len) pair on entry to security_load_policy(),
> and
> the checksum computed on a (data, len) pair got from
> security_read_policy().
> I thought it was a problem to have a difference between the
> internally
> computed checksum and the one a user can get by calling sha256sum on
> /sys/fs/selinux/policy. But now I see it makes sense to reflect what
> was loaded by userspace. So I will simplify this patch accordingly.

Ok, that should work as long as you just want to validate that all the
clients loaded the same policy file, and aren't concerned about non-
persistent policy boolean changes.

You needed to get (global) enforcing mode too, didn't you?  That's
separate from the policy.

Make sure you make the hash algorithm explicit in both what is returned
by the hook to lustre and by what is exported via selinuxfs.  Can
likely just encode the hash algorithm name in the string when you
generate it.



Re: [PATCH 3/3] selinux: expose policy SHA256 checksum via selinuxfs

2017-04-26 Thread Stephen Smalley
On Thu, 2017-04-27 at 00:02 +0900, Sebastien Buisson wrote:
> Expose policy SHA256 checksum via selinuxfs.
> 
> Signed-off-by: Sebastien Buisson 
> ---
>  security/selinux/selinuxfs.c | 20 
>  1 file changed, 20 insertions(+)
> 
> diff --git a/security/selinux/selinuxfs.c
> b/security/selinux/selinuxfs.c
> index ce71718..b2d5deb 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -30,6 +30,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  /* selinuxfs pseudo filesystem for exporting the security policy
> API.
> Based on the proc code and the fs/nfsd/nfsctl.c code. */
> @@ -99,6 +100,7 @@ enum sel_inos {
>   SEL_STATUS, /* export current status using mmap() */
>   SEL_POLICY, /* allow userspace to read the in kernel
> policy */
>   SEL_VALIDATE_TRANS, /* compute validatetrans decision */
> + SEL_POLICYCKSUM,/* return policy SHA256 checkum */
>   SEL_INO_NEXT,   /* The next inode number to use */
>  };
>  
> @@ -313,6 +315,22 @@ static ssize_t sel_read_policyvers(struct file
> *filp, char __user *buf,
>   .llseek = generic_file_llseek,
>  };
>  
> +static ssize_t sel_read_policycksum(struct file *filp, char __user
> *buf,
> + size_t count, loff_t *ppos)
> +{
> + size_t tmpbuflen = SHA256_DIGEST_SIZE*2 + 1;
> + char tmpbuf[tmpbuflen];
> + ssize_t length;
> +
> + length = security_policydb_cksum(tmpbuf, tmpbuflen);
> + return simple_read_from_buffer(buf, count, ppos, tmpbuf,
> length);
> +}

Should we also include information about the hash used, in case it
changes in the future?

> +
> +static const struct file_operations sel_policycksum_ops = {
> + .read   = sel_read_policycksum,
> + .llseek = generic_file_llseek,
> +};
> +
>  /* declaration for sel_write_load */
>  static int sel_make_bools(void);
>  static int sel_make_classes(void);
> @@ -1825,6 +1843,8 @@ static int sel_fill_super(struct super_block
> *sb, void *data, int silent)
>   [SEL_POLICY] = {"policy", _policy_ops, S_IRUGO},
>   [SEL_VALIDATE_TRANS] = {"validatetrans",
> _transition_ops,
>   S_IWUGO},
> + [SEL_POLICYCKSUM] = {"policycksum",
> _policycksum_ops,
> +  S_IRUGO},
>   /* last one */ {""}
>   };
>   ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);


Re: [PATCH 3/3] selinux: expose policy SHA256 checksum via selinuxfs

2017-04-26 Thread Stephen Smalley
On Thu, 2017-04-27 at 00:02 +0900, Sebastien Buisson wrote:
> Expose policy SHA256 checksum via selinuxfs.
> 
> Signed-off-by: Sebastien Buisson 
> ---
>  security/selinux/selinuxfs.c | 20 
>  1 file changed, 20 insertions(+)
> 
> diff --git a/security/selinux/selinuxfs.c
> b/security/selinux/selinuxfs.c
> index ce71718..b2d5deb 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -30,6 +30,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  /* selinuxfs pseudo filesystem for exporting the security policy
> API.
> Based on the proc code and the fs/nfsd/nfsctl.c code. */
> @@ -99,6 +100,7 @@ enum sel_inos {
>   SEL_STATUS, /* export current status using mmap() */
>   SEL_POLICY, /* allow userspace to read the in kernel
> policy */
>   SEL_VALIDATE_TRANS, /* compute validatetrans decision */
> + SEL_POLICYCKSUM,/* return policy SHA256 checkum */
>   SEL_INO_NEXT,   /* The next inode number to use */
>  };
>  
> @@ -313,6 +315,22 @@ static ssize_t sel_read_policyvers(struct file
> *filp, char __user *buf,
>   .llseek = generic_file_llseek,
>  };
>  
> +static ssize_t sel_read_policycksum(struct file *filp, char __user
> *buf,
> + size_t count, loff_t *ppos)
> +{
> + size_t tmpbuflen = SHA256_DIGEST_SIZE*2 + 1;
> + char tmpbuf[tmpbuflen];
> + ssize_t length;
> +
> + length = security_policydb_cksum(tmpbuf, tmpbuflen);
> + return simple_read_from_buffer(buf, count, ppos, tmpbuf,
> length);
> +}

Should we also include information about the hash used, in case it
changes in the future?

> +
> +static const struct file_operations sel_policycksum_ops = {
> + .read   = sel_read_policycksum,
> + .llseek = generic_file_llseek,
> +};
> +
>  /* declaration for sel_write_load */
>  static int sel_make_bools(void);
>  static int sel_make_classes(void);
> @@ -1825,6 +1843,8 @@ static int sel_fill_super(struct super_block
> *sb, void *data, int silent)
>   [SEL_POLICY] = {"policy", _policy_ops, S_IRUGO},
>   [SEL_VALIDATE_TRANS] = {"validatetrans",
> _transition_ops,
>   S_IWUGO},
> + [SEL_POLICYCKSUM] = {"policycksum",
> _policycksum_ops,
> +  S_IRUGO},
>   /* last one */ {""}
>   };
>   ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);


Re: [PATCH 2/3] selinux: add checksum to policydb

2017-04-26 Thread Stephen Smalley
On Thu, 2017-04-27 at 00:02 +0900, Sebastien Buisson wrote:
> Add policycksum field to struct policydb. It holds the sha256
> checksum computed on the binary policy every time the notifier is
> called after a policy change.
> Add security_policy_cksum hook to give access to policy checksum to
> the rest of the kernel. Lustre client makes use of this information.
> 
> Signed-off-by: Sebastien Buisson 
> ---
>  include/linux/lsm_hooks.h   |  2 +
>  include/linux/security.h|  7 +++
>  security/security.c |  6 +++
>  security/selinux/hooks.c| 12 -
>  security/selinux/include/security.h |  2 +
>  security/selinux/ss/policydb.h  |  4 ++
>  security/selinux/ss/services.c  | 91
> +
>  7 files changed, 123 insertions(+), 1 deletion(-)
> 

> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index a4d36f8..3759198 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -173,8 +173,11 @@ static int selinux_netcache_avc_callback(u32
> event)
>  
>  static int selinux_lsm_notifier_avc_callback(u32 event)
>  {
> - if (event == AVC_CALLBACK_RESET)
> + if (event == AVC_CALLBACK_RESET) {
> + if (security_policydb_compute_cksum() != 0)
> + printk(KERN_ERR "Failed to compute policydb
> cksum\n");

This seems like an odd place to trigger the computation. Why aren't you
just computing it when the policy is loaded directly in
security_load_policy()?  You already have the (data, len) on entry to
that function.  Just compute it at load time, save it, and be done.  No
need for a notifier then for your use case unless I am missing
something.

I suppose the question is which checksum do you want - the hash of the
policy file that was written to /sys/fs/selinux/load by userspace, or
the hash of the policy file that the kernel generates on demand if you
open /sys/fs/selinux/policy.  Those can differ in non-semantic ways due
to ordering differences, for example.  I think the former is more
likely to be of interest to userspace (e.g. to compare the hash value
against the hash of the policy file), and is cheaper since you already
have a (data, len) pair on entry to security_load_policy() that you can
hash immediately rather than requiring the kernel to regenerate the
image from the policydb.

>   call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
> + }
>  
>   return 0;
>  }
> 

> diff --git a/security/selinux/ss/services.c
> b/security/selinux/ss/services.c
> index 60d9b02..a35d294 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -53,6 +53,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  
>  #include "flask.h"
>  #include "avc.h"
> @@ -2170,6 +2172,95 @@ size_t security_policydb_len(void)
>  }
>  
>  /**
> + * security_policydb_cksum - Get policydb checksum.
> + * @cksum: string to store checksum to
> + * @len: length of checksum
> + */
> +ssize_t security_policydb_cksum(char *cksum, size_t len)
> +{
> + int rc;
> +
> + read_lock(_rwlock);
> + if (strlcpy(cksum, policydb.policycksum, len) >= len)
> + rc = -ENAMETOOLONG;
> + rc = policydb.policycksum_len;

Obviously you'll clobber -ENAMETOOLONG here.

> + read_unlock(_rwlock);
> +
> + return rc;
> +}

You are requiring all callers to know that they are dealing with a
sha256 hash string in order to provide an adequately sized buffer.
So we either ought to make that evident in the interface, or make the
interface more flexible/general.  The latter is imho preferable.  We
could simply allocate a buffer of the right length and return it, like
selinux_inode_getsecurity() does.

> +
> +/**
> + * security_policydb_compute_cksum - Compute checksum of a policy
> database.
> + */
> +int security_policydb_compute_cksum(void)
> +{
> + struct crypto_ahash *tfm;
> + struct ahash_request *req;
> + struct scatterlist sl;
> + char hashval[SHA256_DIGEST_SIZE];
> + int idx;
> + unsigned char *p;
> + size_t len;
> + void *data;
> + int rc;
> +
> + rc = security_read_policy(, );
> + if (rc) {
> + printk(KERN_ERR "Failed to read security policy\n");
> + return rc;
> + }

This requires regenerating the policy image from the policydb; simpler
if we can just hash what we were given in security_load_policy() and
save it at that time.

> +
> + tfm = crypto_alloc_ahash("sha256", 0, CRYPTO_ALG_ASYNC);

Why are you using the async interface?

> + if (IS_ERR(tfm)) {
> + printk(KERN_ERR "Failed to alloc crypto hash
> sha256\n");
> + vfree(data);
> + rc = PTR_ERR(tfm);
> + return rc;
> + }
> +
> + req = ahash_request_alloc(tfm, GFP_KERNEL);
> + if (!req) {
> + printk(KERN_ERR "Failed to alloc ahash_request for
> sha256\n");
> + crypto_free_ahash(tfm);
> +

Re: [PATCH 2/3] selinux: add checksum to policydb

2017-04-26 Thread Stephen Smalley
On Thu, 2017-04-27 at 00:02 +0900, Sebastien Buisson wrote:
> Add policycksum field to struct policydb. It holds the sha256
> checksum computed on the binary policy every time the notifier is
> called after a policy change.
> Add security_policy_cksum hook to give access to policy checksum to
> the rest of the kernel. Lustre client makes use of this information.
> 
> Signed-off-by: Sebastien Buisson 
> ---
>  include/linux/lsm_hooks.h   |  2 +
>  include/linux/security.h|  7 +++
>  security/security.c |  6 +++
>  security/selinux/hooks.c| 12 -
>  security/selinux/include/security.h |  2 +
>  security/selinux/ss/policydb.h  |  4 ++
>  security/selinux/ss/services.c  | 91
> +
>  7 files changed, 123 insertions(+), 1 deletion(-)
> 

> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index a4d36f8..3759198 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -173,8 +173,11 @@ static int selinux_netcache_avc_callback(u32
> event)
>  
>  static int selinux_lsm_notifier_avc_callback(u32 event)
>  {
> - if (event == AVC_CALLBACK_RESET)
> + if (event == AVC_CALLBACK_RESET) {
> + if (security_policydb_compute_cksum() != 0)
> + printk(KERN_ERR "Failed to compute policydb
> cksum\n");

This seems like an odd place to trigger the computation. Why aren't you
just computing it when the policy is loaded directly in
security_load_policy()?  You already have the (data, len) on entry to
that function.  Just compute it at load time, save it, and be done.  No
need for a notifier then for your use case unless I am missing
something.

I suppose the question is which checksum do you want - the hash of the
policy file that was written to /sys/fs/selinux/load by userspace, or
the hash of the policy file that the kernel generates on demand if you
open /sys/fs/selinux/policy.  Those can differ in non-semantic ways due
to ordering differences, for example.  I think the former is more
likely to be of interest to userspace (e.g. to compare the hash value
against the hash of the policy file), and is cheaper since you already
have a (data, len) pair on entry to security_load_policy() that you can
hash immediately rather than requiring the kernel to regenerate the
image from the policydb.

>   call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
> + }
>  
>   return 0;
>  }
> 

> diff --git a/security/selinux/ss/services.c
> b/security/selinux/ss/services.c
> index 60d9b02..a35d294 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -53,6 +53,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  
>  #include "flask.h"
>  #include "avc.h"
> @@ -2170,6 +2172,95 @@ size_t security_policydb_len(void)
>  }
>  
>  /**
> + * security_policydb_cksum - Get policydb checksum.
> + * @cksum: string to store checksum to
> + * @len: length of checksum
> + */
> +ssize_t security_policydb_cksum(char *cksum, size_t len)
> +{
> + int rc;
> +
> + read_lock(_rwlock);
> + if (strlcpy(cksum, policydb.policycksum, len) >= len)
> + rc = -ENAMETOOLONG;
> + rc = policydb.policycksum_len;

Obviously you'll clobber -ENAMETOOLONG here.

> + read_unlock(_rwlock);
> +
> + return rc;
> +}

You are requiring all callers to know that they are dealing with a
sha256 hash string in order to provide an adequately sized buffer.
So we either ought to make that evident in the interface, or make the
interface more flexible/general.  The latter is imho preferable.  We
could simply allocate a buffer of the right length and return it, like
selinux_inode_getsecurity() does.

> +
> +/**
> + * security_policydb_compute_cksum - Compute checksum of a policy
> database.
> + */
> +int security_policydb_compute_cksum(void)
> +{
> + struct crypto_ahash *tfm;
> + struct ahash_request *req;
> + struct scatterlist sl;
> + char hashval[SHA256_DIGEST_SIZE];
> + int idx;
> + unsigned char *p;
> + size_t len;
> + void *data;
> + int rc;
> +
> + rc = security_read_policy(, );
> + if (rc) {
> + printk(KERN_ERR "Failed to read security policy\n");
> + return rc;
> + }

This requires regenerating the policy image from the policydb; simpler
if we can just hash what we were given in security_load_policy() and
save it at that time.

> +
> + tfm = crypto_alloc_ahash("sha256", 0, CRYPTO_ALG_ASYNC);

Why are you using the async interface?

> + if (IS_ERR(tfm)) {
> + printk(KERN_ERR "Failed to alloc crypto hash
> sha256\n");
> + vfree(data);
> + rc = PTR_ERR(tfm);
> + return rc;
> + }
> +
> + req = ahash_request_alloc(tfm, GFP_KERNEL);
> + if (!req) {
> + printk(KERN_ERR "Failed to alloc ahash_request for
> sha256\n");
> + crypto_free_ahash(tfm);
> + 

Re: [PATCH 1/3] selinux: Implement LSM notification system

2017-04-26 Thread Stephen Smalley
On Wed, 2017-04-26 at 08:38 -0700, Casey Schaufler wrote:
> On 4/26/2017 8:02 AM, Sebastien Buisson wrote:
> > From: Daniel Jurgens 
> > 
> > Add a generic notification mechanism in the LSM. Interested
> > consumers
> > can register a callback with the LSM and security modules can
> > produce
> > events.
> 
> Why is this a generic mechanism? Do you ever see anyone
> other than SELinux using it?

I do - any security module that wants to support access control over
Lustre filesystems or Infiniband. Seems ironic for you to be arguing
for a SELinux-specific interface rather than a LSM interface.

> 
> > Add a call to the notification mechanism from SELinux when the AVC
> > cache changes.
> 
> This seems like a whole lot of mechanism for
> something you could accomplish with a log message.
> What am I missing?

It's a notification to a kernel subsystem that policy has changed so
that the subsystem can update any cached state.

> 
> > 
> > Signed-off-by: Daniel Jurgens 
> > Signed-off-by: Sebastien Buisson 
> > ---
> >  include/linux/security.h | 23 +++
> >  security/security.c  | 20 
> >  security/selinux/hooks.c | 12 
> >  3 files changed, 55 insertions(+)
> > 
> > diff --git a/include/linux/security.h b/include/linux/security.h
> > index af675b5..73a9c93 100644
> > --- a/include/linux/security.h
> > +++ b/include/linux/security.h
> > @@ -68,6 +68,10 @@
> >  struct user_namespace;
> >  struct timezone;
> >  
> > +enum lsm_event {
> > +   LSM_POLICY_CHANGE,
> > +};
> > +
> >  /* These functions are in security/commoncap.c */
> >  extern int cap_capable(const struct cred *cred, struct
> > user_namespace *ns,
> >        int cap, int audit);
> > @@ -163,6 +167,10 @@ struct security_mnt_opts {
> >     int num_mnt_opts;
> >  };
> >  
> > +int call_lsm_notifier(enum lsm_event event, void *data);
> > +int register_lsm_notifier(struct notifier_block *nb);
> > +int unregister_lsm_notifier(struct notifier_block *nb);
> > +
> >  static inline void security_init_mnt_opts(struct security_mnt_opts
> > *opts)
> >  {
> >     opts->mnt_opts = NULL;
> > @@ -381,6 +389,21 @@ int security_sem_semop(struct sem_array *sma,
> > struct sembuf *sops,
> >  struct security_mnt_opts {
> >  };
> >  
> > +static inline int call_lsm_notifier(enum lsm_event event, void
> > *data)
> > +{
> > +   return 0;
> > +}
> > +
> > +static inline int register_lsm_notifier(struct notifier_block *nb)
> > +{
> > +   return 0;
> > +}
> > +
> > +static inline  int unregister_lsm_notifier(struct notifier_block
> > *nb)
> > +{
> > +   return 0;
> > +}
> > +
> >  static inline void security_init_mnt_opts(struct security_mnt_opts
> > *opts)
> >  {
> >  }
> > diff --git a/security/security.c b/security/security.c
> > index b9fea39..ef9d9e1 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -32,6 +32,8 @@
> >  /* Maximum number of letters for an LSM name string */
> >  #define SECURITY_NAME_MAX  10
> >  
> > +static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
> > +
> >  struct security_hook_heads security_hook_heads
> > __lsm_ro_after_init;
> >  char *lsm_names;
> >  /* Boot-time LSM user choice */
> > @@ -146,6 +148,24 @@ void __init security_add_hooks(struct
> > security_hook_list *hooks, int count,
> >     panic("%s - Cannot get early memory.\n",
> > __func__);
> >  }
> >  
> > +int call_lsm_notifier(enum lsm_event event, void *data)
> > +{
> > +   return atomic_notifier_call_chain(_notifier_chain,
> > event, data);
> > +}
> > +EXPORT_SYMBOL(call_lsm_notifier);
> > +
> > +int register_lsm_notifier(struct notifier_block *nb)
> > +{
> > +   return atomic_notifier_chain_register(_notifier_chain,
> > nb);
> > +}
> > +EXPORT_SYMBOL(register_lsm_notifier);
> > +
> > +int unregister_lsm_notifier(struct notifier_block *nb)
> > +{
> > +   return
> > atomic_notifier_chain_unregister(_notifier_chain, nb);
> > +}
> > +EXPORT_SYMBOL(unregister_lsm_notifier);
> > +
> >  /*
> >   * Hook list operation macros.
> >   *
> > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> > index e67a526..a4d36f8 100644
> > --- a/security/selinux/hooks.c
> > +++ b/security/selinux/hooks.c
> > @@ -171,6 +171,14 @@ static int selinux_netcache_avc_callback(u32
> > event)
> >     return 0;
> >  }
> >  
> > +static int selinux_lsm_notifier_avc_callback(u32 event)
> > +{
> > +   if (event == AVC_CALLBACK_RESET)
> > +   call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
> > +
> > +   return 0;
> > +}
> > +
> >  /*
> >   * initialise the security for the init task
> >   */
> > @@ -6379,6 +6387,10 @@ static __init int selinux_init(void)
> >     if (avc_add_callback(selinux_netcache_avc_callback,
> > AVC_CALLBACK_RESET))
> >     panic("SELinux: Unable to register AVC netcache
> > callback\n");
> >  
> > +   if (avc_add_callback(selinux_lsm_notifier_avc_callback,
> > +    AVC_CALLBACK_RESET))
> > +  

Re: [PATCH 1/3] selinux: Implement LSM notification system

2017-04-26 Thread Stephen Smalley
On Wed, 2017-04-26 at 08:38 -0700, Casey Schaufler wrote:
> On 4/26/2017 8:02 AM, Sebastien Buisson wrote:
> > From: Daniel Jurgens 
> > 
> > Add a generic notification mechanism in the LSM. Interested
> > consumers
> > can register a callback with the LSM and security modules can
> > produce
> > events.
> 
> Why is this a generic mechanism? Do you ever see anyone
> other than SELinux using it?

I do - any security module that wants to support access control over
Lustre filesystems or Infiniband. Seems ironic for you to be arguing
for a SELinux-specific interface rather than a LSM interface.

> 
> > Add a call to the notification mechanism from SELinux when the AVC
> > cache changes.
> 
> This seems like a whole lot of mechanism for
> something you could accomplish with a log message.
> What am I missing?

It's a notification to a kernel subsystem that policy has changed so
that the subsystem can update any cached state.

> 
> > 
> > Signed-off-by: Daniel Jurgens 
> > Signed-off-by: Sebastien Buisson 
> > ---
> >  include/linux/security.h | 23 +++
> >  security/security.c  | 20 
> >  security/selinux/hooks.c | 12 
> >  3 files changed, 55 insertions(+)
> > 
> > diff --git a/include/linux/security.h b/include/linux/security.h
> > index af675b5..73a9c93 100644
> > --- a/include/linux/security.h
> > +++ b/include/linux/security.h
> > @@ -68,6 +68,10 @@
> >  struct user_namespace;
> >  struct timezone;
> >  
> > +enum lsm_event {
> > +   LSM_POLICY_CHANGE,
> > +};
> > +
> >  /* These functions are in security/commoncap.c */
> >  extern int cap_capable(const struct cred *cred, struct
> > user_namespace *ns,
> >        int cap, int audit);
> > @@ -163,6 +167,10 @@ struct security_mnt_opts {
> >     int num_mnt_opts;
> >  };
> >  
> > +int call_lsm_notifier(enum lsm_event event, void *data);
> > +int register_lsm_notifier(struct notifier_block *nb);
> > +int unregister_lsm_notifier(struct notifier_block *nb);
> > +
> >  static inline void security_init_mnt_opts(struct security_mnt_opts
> > *opts)
> >  {
> >     opts->mnt_opts = NULL;
> > @@ -381,6 +389,21 @@ int security_sem_semop(struct sem_array *sma,
> > struct sembuf *sops,
> >  struct security_mnt_opts {
> >  };
> >  
> > +static inline int call_lsm_notifier(enum lsm_event event, void
> > *data)
> > +{
> > +   return 0;
> > +}
> > +
> > +static inline int register_lsm_notifier(struct notifier_block *nb)
> > +{
> > +   return 0;
> > +}
> > +
> > +static inline  int unregister_lsm_notifier(struct notifier_block
> > *nb)
> > +{
> > +   return 0;
> > +}
> > +
> >  static inline void security_init_mnt_opts(struct security_mnt_opts
> > *opts)
> >  {
> >  }
> > diff --git a/security/security.c b/security/security.c
> > index b9fea39..ef9d9e1 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -32,6 +32,8 @@
> >  /* Maximum number of letters for an LSM name string */
> >  #define SECURITY_NAME_MAX  10
> >  
> > +static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
> > +
> >  struct security_hook_heads security_hook_heads
> > __lsm_ro_after_init;
> >  char *lsm_names;
> >  /* Boot-time LSM user choice */
> > @@ -146,6 +148,24 @@ void __init security_add_hooks(struct
> > security_hook_list *hooks, int count,
> >     panic("%s - Cannot get early memory.\n",
> > __func__);
> >  }
> >  
> > +int call_lsm_notifier(enum lsm_event event, void *data)
> > +{
> > +   return atomic_notifier_call_chain(_notifier_chain,
> > event, data);
> > +}
> > +EXPORT_SYMBOL(call_lsm_notifier);
> > +
> > +int register_lsm_notifier(struct notifier_block *nb)
> > +{
> > +   return atomic_notifier_chain_register(_notifier_chain,
> > nb);
> > +}
> > +EXPORT_SYMBOL(register_lsm_notifier);
> > +
> > +int unregister_lsm_notifier(struct notifier_block *nb)
> > +{
> > +   return
> > atomic_notifier_chain_unregister(_notifier_chain, nb);
> > +}
> > +EXPORT_SYMBOL(unregister_lsm_notifier);
> > +
> >  /*
> >   * Hook list operation macros.
> >   *
> > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> > index e67a526..a4d36f8 100644
> > --- a/security/selinux/hooks.c
> > +++ b/security/selinux/hooks.c
> > @@ -171,6 +171,14 @@ static int selinux_netcache_avc_callback(u32
> > event)
> >     return 0;
> >  }
> >  
> > +static int selinux_lsm_notifier_avc_callback(u32 event)
> > +{
> > +   if (event == AVC_CALLBACK_RESET)
> > +   call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
> > +
> > +   return 0;
> > +}
> > +
> >  /*
> >   * initialise the security for the init task
> >   */
> > @@ -6379,6 +6387,10 @@ static __init int selinux_init(void)
> >     if (avc_add_callback(selinux_netcache_avc_callback,
> > AVC_CALLBACK_RESET))
> >     panic("SELinux: Unable to register AVC netcache
> > callback\n");
> >  
> > +   if (avc_add_callback(selinux_lsm_notifier_avc_callback,
> > +    AVC_CALLBACK_RESET))
> > +   panic("SELinux: Unable to register AVC LSM
> > notifier 

Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 19:07 +0200, Sebastien Buisson wrote:
> 2017-04-12 18:24 GMT+02:00 Stephen Smalley <s...@tycho.nsa.gov>:
> > Maybe you want to register a notifier callback on policy reload?
> > See
> > the archives for the SELinux support for Infiniband RDMA patches
> > (which
> > seem to have stalled), which included LSM hooks and SELinux
> > implementation to support notifications on policy reloads.
> 
> I need to have a look indeed. So it is a callback in kernelspace?

Yes, see:
https://patchwork.kernel.org/patch/9443417/

> 
> > > As I understand it, a userspace program can directly read the
> > > policy
> > > info exposed by the kernel by reading this file. But how about
> > > reading it from kernelspace?
> > 
> > This seems very inefficient though for your purposes.  Wouldn't it
> > be
> > better to just extend SELinux to compute the checksum from the
> > original
> > image when the policy is loaded, save that checksum in the
> > policydb,
> > and provide you with a way to fetch the already computed
> > checksum?  The
> > computation would be done in security_load_policy() and saved in
> > the
> > policydb.  Then you could introduce a function and a LSM hook to
> > export
> > it to your code. We would probably want to also expose it via a
> > selinuxfs node to userspace.
> 
> This is an excellent suggestion. It makes much more sense to have the
> checksum computed on SELinux side when a policy is loaded. And then
> just read this checksum when needed, both from kernel and userspace.
>
> > This however only works for checking that you have a completely
> > identical policy built in exactly the same way.  You could have
> > semantically identical policies that still differ in the binary
> > policy
> > file, or policies with minor local customizations that aren't
> > significant.  But perhaps that isn't an issue for Lustre
> > environments.
> 
> If we can protect against local customizations this is great. What
> could be the other scenario leading to different binary policies
> while
> being semantically identical?

There can be ordering or optimization differences, depending on the
policy compiler toolchain and build process. Probably not a concern if
they are all running the same distro with the same policy package,
built in the same build environment.



Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 19:07 +0200, Sebastien Buisson wrote:
> 2017-04-12 18:24 GMT+02:00 Stephen Smalley :
> > Maybe you want to register a notifier callback on policy reload?
> > See
> > the archives for the SELinux support for Infiniband RDMA patches
> > (which
> > seem to have stalled), which included LSM hooks and SELinux
> > implementation to support notifications on policy reloads.
> 
> I need to have a look indeed. So it is a callback in kernelspace?

Yes, see:
https://patchwork.kernel.org/patch/9443417/

> 
> > > As I understand it, a userspace program can directly read the
> > > policy
> > > info exposed by the kernel by reading this file. But how about
> > > reading it from kernelspace?
> > 
> > This seems very inefficient though for your purposes.  Wouldn't it
> > be
> > better to just extend SELinux to compute the checksum from the
> > original
> > image when the policy is loaded, save that checksum in the
> > policydb,
> > and provide you with a way to fetch the already computed
> > checksum?  The
> > computation would be done in security_load_policy() and saved in
> > the
> > policydb.  Then you could introduce a function and a LSM hook to
> > export
> > it to your code. We would probably want to also expose it via a
> > selinuxfs node to userspace.
> 
> This is an excellent suggestion. It makes much more sense to have the
> checksum computed on SELinux side when a policy is loaded. And then
> just read this checksum when needed, both from kernel and userspace.
>
> > This however only works for checking that you have a completely
> > identical policy built in exactly the same way.  You could have
> > semantically identical policies that still differ in the binary
> > policy
> > file, or policies with minor local customizations that aren't
> > significant.  But perhaps that isn't an issue for Lustre
> > environments.
> 
> If we can protect against local customizations this is great. What
> could be the other scenario leading to different binary policies
> while
> being semantically identical?

There can be ordering or optimization differences, depending on the
policy compiler toolchain and build process. Probably not a concern if
they are all running the same distro with the same policy package,
built in the same build environment.



Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 17:19 +0200, Sebastien Buisson wrote:
> 2017-04-12 15:58 GMT+02:00 Stephen Smalley <s...@tycho.nsa.gov>:
> > Even your usage of selinux_is_enabled() looks suspect; that should
> > probably go away.  Only other user of it seems to be some cred
> > validity
> > checking that could be dropped as well.
> 
> Well the main reason for calling selinux_is_enabled() is performance
> optimization.
> Should I propose a patch to add a new security_is_enabled() function
> at the LSM abstraction layer? Or do you consider we should not test
> security enabled at all?

It isn't clear what "is enabled" means in general, particularly with
stacking. I would either drop it or replace it with a LSM hook that is
more precise.  For example, NFSv4 introduced a security_ismaclabel()
hook so that it could test whether a given security.* xattr is a MAC
label.



Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 17:19 +0200, Sebastien Buisson wrote:
> 2017-04-12 15:58 GMT+02:00 Stephen Smalley :
> > Even your usage of selinux_is_enabled() looks suspect; that should
> > probably go away.  Only other user of it seems to be some cred
> > validity
> > checking that could be dropped as well.
> 
> Well the main reason for calling selinux_is_enabled() is performance
> optimization.
> Should I propose a patch to add a new security_is_enabled() function
> at the LSM abstraction layer? Or do you consider we should not test
> security enabled at all?

It isn't clear what "is enabled" means in general, particularly with
stacking. I would either drop it or replace it with a LSM hook that is
more precise.  For example, NFSv4 introduced a security_ismaclabel()
hook so that it could test whether a given security.* xattr is a MAC
label.



Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 17:11 +0200, Sebastien Buisson wrote:
> 2017-04-12 16:35 GMT+02:00 Stephen Smalley <s...@tycho.nsa.gov>:
> > How are you using this SELinux information in the kernel and/or in
> > userspace?  What's the purpose of it?  What are you comparing it
> > against?  Why do you care if it changes?
> 
> Enforcement status and policy version are compared to their
> previously
> stored value. If they differ, then it means we need to call a
> userland
> helper from Lustre client kernelspace to read the currently loaded
> policy (reading it will let us know if the Lustre client node is
> conforming to the Lustre-wide security policy).
> As calling the userland helper is costly, we do it only when it is
> necessary by retrieving some SELinux key information directly from
> kernelspace.

Maybe you want to register a notifier callback on policy reload? See
the archives for the SELinux support for Infiniband RDMA patches (which
seem to have stalled), which included LSM hooks and SELinux
implementation to support notifications on policy reloads.

> 
> > Note btw that the notion of a policy name/type and the policy file
> > path
> > is purely a userspace construct and shouldn't be embedded in your
> > kernel code.  Android for example doesn't follow that convention at
> > all; their SELinux policy file is simply /sepolicy.  On modern
> > kernels,
> > you can always read the currently loaded policy from the kernel
> > itself
> > via /sys/fs/selinux/policy (formerly just /selinux/policy).
> 
> As I understand it, a userspace program can directly read the policy
> info exposed by the kernel by reading this file. But how about
> reading
> it from kernelspace?

In SELinux, the underlying kernel function is security_read_policy();
you'd have to wrap it with a LSM hook interface, and generalize it a
bit wrt whether to use vmalloc_user() or not.

This seems very inefficient though for your purposes.  Wouldn't it be
better to just extend SELinux to compute the checksum from the original
image when the policy is loaded, save that checksum in the policydb,
and provide you with a way to fetch the already computed checksum?  The
computation would be done in security_load_policy() and saved in the
policydb.  Then you could introduce a function and a LSM hook to export
it to your code. We would probably want to also expose it via a
selinuxfs node to userspace.

This however only works for checking that you have a completely
identical policy built in exactly the same way.  You could have
semantically identical policies that still differ in the binary policy
file, or policies with minor local customizations that aren't
significant.  But perhaps that isn't an issue for Lustre environments.



Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 17:11 +0200, Sebastien Buisson wrote:
> 2017-04-12 16:35 GMT+02:00 Stephen Smalley :
> > How are you using this SELinux information in the kernel and/or in
> > userspace?  What's the purpose of it?  What are you comparing it
> > against?  Why do you care if it changes?
> 
> Enforcement status and policy version are compared to their
> previously
> stored value. If they differ, then it means we need to call a
> userland
> helper from Lustre client kernelspace to read the currently loaded
> policy (reading it will let us know if the Lustre client node is
> conforming to the Lustre-wide security policy).
> As calling the userland helper is costly, we do it only when it is
> necessary by retrieving some SELinux key information directly from
> kernelspace.

Maybe you want to register a notifier callback on policy reload? See
the archives for the SELinux support for Infiniband RDMA patches (which
seem to have stalled), which included LSM hooks and SELinux
implementation to support notifications on policy reloads.

> 
> > Note btw that the notion of a policy name/type and the policy file
> > path
> > is purely a userspace construct and shouldn't be embedded in your
> > kernel code.  Android for example doesn't follow that convention at
> > all; their SELinux policy file is simply /sepolicy.  On modern
> > kernels,
> > you can always read the currently loaded policy from the kernel
> > itself
> > via /sys/fs/selinux/policy (formerly just /selinux/policy).
> 
> As I understand it, a userspace program can directly read the policy
> info exposed by the kernel by reading this file. But how about
> reading
> it from kernelspace?

In SELinux, the underlying kernel function is security_read_policy();
you'd have to wrap it with a LSM hook interface, and generalize it a
bit wrt whether to use vmalloc_user() or not.

This seems very inefficient though for your purposes.  Wouldn't it be
better to just extend SELinux to compute the checksum from the original
image when the policy is loaded, save that checksum in the policydb,
and provide you with a way to fetch the already computed checksum?  The
computation would be done in security_load_policy() and saved in the
policydb.  Then you could introduce a function and a LSM hook to export
it to your code. We would probably want to also expose it via a
selinuxfs node to userspace.

This however only works for checking that you have a completely
identical policy built in exactly the same way.  You could have
semantically identical policies that still differ in the binary policy
file, or policies with minor local customizations that aren't
significant.  But perhaps that isn't an issue for Lustre environments.



Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 15:30 +0200, Sebastien Buisson wrote:
> 2017-04-12 13:55 GMT+02:00 Paul Moore :
> > As currently written this code isn't something we would want to
> > merge
> > upstream for two important reasons:
> > 
> > * No clear user of this functionality.  There needs to be a well
> > defined user of this functionality in the kernel.
> 
> The use case for this new functionality (and the other one) is
> getting
> SELinux information from the Lustre client code in kernel space.
> Latest patch can be accessed at:
> https://review.whamcloud.com/24421
> Actual user is sptlrpc_get_sepol() function in
> lustre/lustre/ptlrpc/sec.c file.
> This code will be pushed to the upstream kernel as soon as it is
> landed into Lustre master branch.

How are you using this SELinux information in the kernel and/or in
userspace?  What's the purpose of it?  What are you comparing it
against?  Why do you care if it changes?

Note btw that the notion of a policy name/type and the policy file path
is purely a userspace construct and shouldn't be embedded in your
kernel code.  Android for example doesn't follow that convention at
all; their SELinux policy file is simply /sepolicy.  On modern kernels,
you can always read the currently loaded policy from the kernel itself
via /sys/fs/selinux/policy (formerly just /selinux/policy).






Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 15:30 +0200, Sebastien Buisson wrote:
> 2017-04-12 13:55 GMT+02:00 Paul Moore :
> > As currently written this code isn't something we would want to
> > merge
> > upstream for two important reasons:
> > 
> > * No clear user of this functionality.  There needs to be a well
> > defined user of this functionality in the kernel.
> 
> The use case for this new functionality (and the other one) is
> getting
> SELinux information from the Lustre client code in kernel space.
> Latest patch can be accessed at:
> https://review.whamcloud.com/24421
> Actual user is sptlrpc_get_sepol() function in
> lustre/lustre/ptlrpc/sec.c file.
> This code will be pushed to the upstream kernel as soon as it is
> landed into Lustre master branch.

How are you using this SELinux information in the kernel and/or in
userspace?  What's the purpose of it?  What are you comparing it
against?  Why do you care if it changes?

Note btw that the notion of a policy name/type and the policy file path
is purely a userspace construct and shouldn't be embedded in your
kernel code.  Android for example doesn't follow that convention at
all; their SELinux policy file is simply /sepolicy.  On modern kernels,
you can always read the currently loaded policy from the kernel itself
via /sys/fs/selinux/policy (formerly just /selinux/policy).






Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 15:30 +0200, Sebastien Buisson wrote:
> 2017-04-12 13:55 GMT+02:00 Paul Moore :
> > As currently written this code isn't something we would want to
> > merge
> > upstream for two important reasons:
> > 
> > * No abstraction layer at the LSM interface.  The core kernel code
> > should not call directly into any specific LSM, all interaction
> > should
> > go through the LSM hooks.
> 
> The idea behind this patch and the other one was to replicate what is
> done with selinux_is_enabled(). As I understand it now,
> selinux_is_enabled() should remain the only exception to the LSM
> hooks.
> So do you agree if I propose a new security_is_enforced() function at
> the LSM abstraction layer, which will be hooked to a
> selinux_is_enforced() function defined inside the SELinux LSM?

Even your usage of selinux_is_enabled() looks suspect; that should
probably go away.  Only other user of it seems to be some cred validity
checking that could be dropped as well.  The include/linux/selinux.h
interfaces were originally for use by audit and secmark when there were
no other LSMs and have gradually been removed.




Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 15:30 +0200, Sebastien Buisson wrote:
> 2017-04-12 13:55 GMT+02:00 Paul Moore :
> > As currently written this code isn't something we would want to
> > merge
> > upstream for two important reasons:
> > 
> > * No abstraction layer at the LSM interface.  The core kernel code
> > should not call directly into any specific LSM, all interaction
> > should
> > go through the LSM hooks.
> 
> The idea behind this patch and the other one was to replicate what is
> done with selinux_is_enabled(). As I understand it now,
> selinux_is_enabled() should remain the only exception to the LSM
> hooks.
> So do you agree if I propose a new security_is_enforced() function at
> the LSM abstraction layer, which will be hooked to a
> selinux_is_enforced() function defined inside the SELinux LSM?

Even your usage of selinux_is_enabled() looks suspect; that should
probably go away.  Only other user of it seems to be some cred validity
checking that could be dropped as well.  The include/linux/selinux.h
interfaces were originally for use by audit and secmark when there were
no other LSMs and have gradually been removed.




Re: [PATCH] selinux: add selinux_status_get_seq() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 18:12 +0900, Sebastien Buisson wrote:
> Add selinux_status_get_seq() function to give access to sequence
> number of current SELinux policy loaded to the rest of the kernel.
> 
> Signed-off-by: Sebastien Buisson 
> ---
>  include/linux/selinux.h  |  7 +++
>  security/selinux/ss/status.c | 21 +
>  2 files changed, 28 insertions(+)
> 
> diff --git a/include/linux/selinux.h b/include/linux/selinux.h
> index 44f4596..926f9f0 100644
> --- a/include/linux/selinux.h
> +++ b/include/linux/selinux.h
> @@ -24,12 +24,19 @@
>   * selinux_is_enabled - is SELinux enabled?
>   */
>  bool selinux_is_enabled(void);
> +u32 selinux_status_get_seq(void);
>  #else
>  
>  static inline bool selinux_is_enabled(void)
>  {
>   return false;
>  }
> +
> +static inline u32 selinux_status_get_seq(void)
> +{
> + return 0;
> +}
> +
>  #endif   /* CONFIG_SECURITY_SELINUX */
>  
>  #endif /* _LINUX_SELINUX_H */
> diff --git a/security/selinux/ss/status.c
> b/security/selinux/ss/status.c
> index d982365..a0670d3 100644
> --- a/security/selinux/ss/status.c
> +++ b/security/selinux/ss/status.c
> @@ -124,3 +124,24 @@ void selinux_status_update_policyload(int seqno)
>   }
>   mutex_unlock(_status_lock);
>  }
> +
> +/*
> + * selinux_status_get_seq
> + *
> + * It gets current sequence of policy loaded.
> + */
> +u32 selinux_status_get_seq(void)
> +{
> + struct selinux_kernel_status   *status;
> + u32 seq = 0;
> +
> + mutex_lock(_status_lock);
> + if (selinux_status_page) {
> + status = page_address(selinux_status_page);
> + seq = status->sequence;
> + }
> + mutex_unlock(_status_lock);
> +
> + return seq;
> +}
> +EXPORT_SYMBOL_GPL(selinux_status_get_seq);

status->sequence is a sequence number for the seqlock logic, not the
policy sequence number.  You likely want avc_policy_seqno() instead,
although I can't tell without seeing the user of this function. 
Regardless, as with the other patch, there needs to be an in-tree user
and a LSM hook interface to use this outside of the SELinux code
itself.



Re: [PATCH] selinux: add selinux_status_get_seq() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 18:12 +0900, Sebastien Buisson wrote:
> Add selinux_status_get_seq() function to give access to sequence
> number of current SELinux policy loaded to the rest of the kernel.
> 
> Signed-off-by: Sebastien Buisson 
> ---
>  include/linux/selinux.h  |  7 +++
>  security/selinux/ss/status.c | 21 +
>  2 files changed, 28 insertions(+)
> 
> diff --git a/include/linux/selinux.h b/include/linux/selinux.h
> index 44f4596..926f9f0 100644
> --- a/include/linux/selinux.h
> +++ b/include/linux/selinux.h
> @@ -24,12 +24,19 @@
>   * selinux_is_enabled - is SELinux enabled?
>   */
>  bool selinux_is_enabled(void);
> +u32 selinux_status_get_seq(void);
>  #else
>  
>  static inline bool selinux_is_enabled(void)
>  {
>   return false;
>  }
> +
> +static inline u32 selinux_status_get_seq(void)
> +{
> + return 0;
> +}
> +
>  #endif   /* CONFIG_SECURITY_SELINUX */
>  
>  #endif /* _LINUX_SELINUX_H */
> diff --git a/security/selinux/ss/status.c
> b/security/selinux/ss/status.c
> index d982365..a0670d3 100644
> --- a/security/selinux/ss/status.c
> +++ b/security/selinux/ss/status.c
> @@ -124,3 +124,24 @@ void selinux_status_update_policyload(int seqno)
>   }
>   mutex_unlock(_status_lock);
>  }
> +
> +/*
> + * selinux_status_get_seq
> + *
> + * It gets current sequence of policy loaded.
> + */
> +u32 selinux_status_get_seq(void)
> +{
> + struct selinux_kernel_status   *status;
> + u32 seq = 0;
> +
> + mutex_lock(_status_lock);
> + if (selinux_status_page) {
> + status = page_address(selinux_status_page);
> + seq = status->sequence;
> + }
> + mutex_unlock(_status_lock);
> +
> + return seq;
> +}
> +EXPORT_SYMBOL_GPL(selinux_status_get_seq);

status->sequence is a sequence number for the seqlock logic, not the
policy sequence number.  You likely want avc_policy_seqno() instead,
although I can't tell without seeing the user of this function. 
Regardless, as with the other patch, there needs to be an in-tree user
and a LSM hook interface to use this outside of the SELinux code
itself.



Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 18:06 +0900, Sebastien Buisson wrote:
> Add selinux_is_enforced() function to give access to SELinux
> enforcement to the rest of the kernel.
> 
> Signed-off-by: Sebastien Buisson 
> ---
>  include/linux/selinux.h | 5 +
>  security/selinux/exports.c  | 6 ++
>  security/selinux/hooks.c| 2 ++
>  security/selinux/include/avc.h  | 6 --
>  security/selinux/include/security.h | 1 +
>  5 files changed, 14 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/selinux.h b/include/linux/selinux.h
> index 44f4596..1007321 100644
> --- a/include/linux/selinux.h
> +++ b/include/linux/selinux.h
> @@ -24,12 +24,17 @@
>   * selinux_is_enabled - is SELinux enabled?
>   */
>  bool selinux_is_enabled(void);
> +bool selinux_is_enforced(void);
>  #else
>  
>  static inline bool selinux_is_enabled(void)
>  {
>   return false;
>  }
> +static inline bool selinux_is_enforced(void)
> +{
> + return false;
> +}
>  #endif   /* CONFIG_SECURITY_SELINUX */
>  
>  #endif /* _LINUX_SELINUX_H */
> diff --git a/security/selinux/exports.c b/security/selinux/exports.c
> index e75dd94..016f1e2 100644
> --- a/security/selinux/exports.c
> +++ b/security/selinux/exports.c
> @@ -21,3 +21,9 @@ bool selinux_is_enabled(void)
>   return selinux_enabled;
>  }
>  EXPORT_SYMBOL_GPL(selinux_is_enabled);
> +
> +bool selinux_is_enforced(void)
> +{
> + return selinux_enforcing;
> +}
> +EXPORT_SYMBOL_GPL(selinux_is_enforced);
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index e67a526..da2baeb 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -109,6 +109,8 @@ static int __init enforcing_setup(char *str)
>   return 1;
>  }
>  __setup("enforcing=", enforcing_setup);
> +#else
> +int selinux_enforcing;
>  #endif
>  
>  #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
> diff --git a/security/selinux/include/avc.h
> b/security/selinux/include/avc.h
> index 0999df0..ff98351 100644
> --- a/security/selinux/include/avc.h
> +++ b/security/selinux/include/avc.h
> @@ -19,12 +19,6 @@
>  #include "av_permissions.h"
>  #include "security.h"
>  
> -#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
> -extern int selinux_enforcing;
> -#else
> -#define selinux_enforcing 1
> -#endif

If CONFIG_SECURITY_SELINUX_DEVELOP=n, then selinux_enforcing is
supposed to always be 1, i.e. global permissive mode is not supported. 
Your patch breaks that.  That's in addition to the points raised by
others about needing an in-tree user and use of a LSM hook interface
instead.

> -
>  /*
>   * An entry in the AVC.
>   */
> diff --git a/security/selinux/include/security.h
> b/security/selinux/include/security.h
> index f979c35..1e67e268 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -64,6 +64,7 @@
>  struct netlbl_lsm_secattr;
>  
>  extern int selinux_enabled;
> +extern int selinux_enforcing;
>  
>  /* Policy capabilities */
>  enum {


Re: [PATCH] selinux: add selinux_is_enforced() function

2017-04-12 Thread Stephen Smalley
On Wed, 2017-04-12 at 18:06 +0900, Sebastien Buisson wrote:
> Add selinux_is_enforced() function to give access to SELinux
> enforcement to the rest of the kernel.
> 
> Signed-off-by: Sebastien Buisson 
> ---
>  include/linux/selinux.h | 5 +
>  security/selinux/exports.c  | 6 ++
>  security/selinux/hooks.c| 2 ++
>  security/selinux/include/avc.h  | 6 --
>  security/selinux/include/security.h | 1 +
>  5 files changed, 14 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/selinux.h b/include/linux/selinux.h
> index 44f4596..1007321 100644
> --- a/include/linux/selinux.h
> +++ b/include/linux/selinux.h
> @@ -24,12 +24,17 @@
>   * selinux_is_enabled - is SELinux enabled?
>   */
>  bool selinux_is_enabled(void);
> +bool selinux_is_enforced(void);
>  #else
>  
>  static inline bool selinux_is_enabled(void)
>  {
>   return false;
>  }
> +static inline bool selinux_is_enforced(void)
> +{
> + return false;
> +}
>  #endif   /* CONFIG_SECURITY_SELINUX */
>  
>  #endif /* _LINUX_SELINUX_H */
> diff --git a/security/selinux/exports.c b/security/selinux/exports.c
> index e75dd94..016f1e2 100644
> --- a/security/selinux/exports.c
> +++ b/security/selinux/exports.c
> @@ -21,3 +21,9 @@ bool selinux_is_enabled(void)
>   return selinux_enabled;
>  }
>  EXPORT_SYMBOL_GPL(selinux_is_enabled);
> +
> +bool selinux_is_enforced(void)
> +{
> + return selinux_enforcing;
> +}
> +EXPORT_SYMBOL_GPL(selinux_is_enforced);
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index e67a526..da2baeb 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -109,6 +109,8 @@ static int __init enforcing_setup(char *str)
>   return 1;
>  }
>  __setup("enforcing=", enforcing_setup);
> +#else
> +int selinux_enforcing;
>  #endif
>  
>  #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
> diff --git a/security/selinux/include/avc.h
> b/security/selinux/include/avc.h
> index 0999df0..ff98351 100644
> --- a/security/selinux/include/avc.h
> +++ b/security/selinux/include/avc.h
> @@ -19,12 +19,6 @@
>  #include "av_permissions.h"
>  #include "security.h"
>  
> -#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
> -extern int selinux_enforcing;
> -#else
> -#define selinux_enforcing 1
> -#endif

If CONFIG_SECURITY_SELINUX_DEVELOP=n, then selinux_enforcing is
supposed to always be 1, i.e. global permissive mode is not supported. 
Your patch breaks that.  That's in addition to the points raised by
others about needing an in-tree user and use of a LSM hook interface
instead.

> -
>  /*
>   * An entry in the AVC.
>   */
> diff --git a/security/selinux/include/security.h
> b/security/selinux/include/security.h
> index f979c35..1e67e268 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -64,6 +64,7 @@
>  struct netlbl_lsm_secattr;
>  
>  extern int selinux_enabled;
> +extern int selinux_enforcing;
>  
>  /* Policy capabilities */
>  enum {


Re: [PATCH] selinux: Fix SBLABEL_MNT for NFS mounts

2017-03-30 Thread Stephen Smalley
On Thu, 2017-03-30 at 13:41 -0400, J. Bruce Fields wrote:
> On Thu, Mar 30, 2017 at 01:27:07PM -0400, Stephen Smalley wrote:
> > On Thu, 2017-03-30 at 09:49 +0200, Tomeu Vizoso wrote:
> > > On 29 March 2017 at 23:34, J. Bruce Fields <bfie...@redhat.com>
> > > wrote:
> > > > On Wed, Mar 29, 2017 at 05:27:23PM +0200, Tomeu Vizoso wrote:
> > > > > Labelling of files in a NFSv4.2 currently fails with ENOTSUPP
> > > > > because
> > > > > the mount point doesn't have SBLABEL_MNT.
> > > > > 
> > > > > Add specific condition for NFS4 filesystems so it gets
> > > > > correctly
> > > > > labeled.
> > > > 
> > > > Huh.  Looking at the code, I think this is meant to be handled
> > > > by
> > > > the
> > > > SECURITY_FS_USE_NATIVE case--there was a similar failure fixed
> > > > some
> > > > time
> > > > ago by 9fc2b4b436cf.  What kernel are you seeing this on?  Is
> > > > it a
> > > > recent regression (in which case, what's the latest kernel that
> > > > worked
> > > > for you)?
> > > 
> > > I have seen this on 4.11-rc4, but I never tried to get this
> > > working
> > > before.
> > > 
> > > I will try to find time to see why SECURITY_FS_USE_NATIVE isn't
> > > working here.
> > 
> > Does your exports file specify the "security_label" option, e.g.
> > /path/to/dir example.com(rw,security_label)
> 
> Oops, right, that should have been the first thing I asked about
> 
> > It appears that with recent kernels that is now required;
> > otherwise,
> > the mount defaults to not enabling native labeling and all of the
> > files
> > are treated as having a single, fixed label defined by the client
> > policy (and hence setxattr is not supported).  This was kernel
> > commit
> > 32ddd944a056c786f6acdd95ed29e994adc613a2.  I don't recall seeing
> > any
> > discussion of this on selinux list.  I understand the rationale,
> > but it
> > seems like a user-visible regression
> 
> It is.  I also want to keep new protocol upgrades free of user
> regressions, which the 4.1->4.2 upgrade is in most cases if we turn
> on
> security labeling by default.  So I was stuck choosing between two
> regresisons, and figured 4.2 user depending on security labeling was
> still the much rarer case.
> 
> So I'd like to keep security labeling off by default, but if there's
> anything I can do to smooth the transition obviously that's good.

Yes, I understand - wish though that it could have been communicated
better, e.g. on selinux list (unless I just missed it somehow).

> 
> > and at the very least, it seems odd that they didn't just use
> > "seclabel" as the kernel does in /proc/mounts to signify a
> > filesystem
> > that supports security labeling by userspace.
> 
> I see logic in sb_finish_set_opts() that sets SBLABEL_MNT in the
> selinux_is_sblabel_mnt() case.  Doesn't that mean "seclabel" shows up
> in
> /proc/mounts when we nfs sets SECURITY_LSM_NATIVE_LABELS?
> 
> I may not understand your comment, I'm pretty unfamiliar with this
> area.

Correct, I just meant it seems potentially confusing to users to use
"security_label" in exports when we show it as "seclabel" in
/proc/mounts.  I know, they are totally different namespaces (in the
conventional sense), but consistency might have been more user-
friendly.




Re: [PATCH] selinux: Fix SBLABEL_MNT for NFS mounts

2017-03-30 Thread Stephen Smalley
On Thu, 2017-03-30 at 13:41 -0400, J. Bruce Fields wrote:
> On Thu, Mar 30, 2017 at 01:27:07PM -0400, Stephen Smalley wrote:
> > On Thu, 2017-03-30 at 09:49 +0200, Tomeu Vizoso wrote:
> > > On 29 March 2017 at 23:34, J. Bruce Fields 
> > > wrote:
> > > > On Wed, Mar 29, 2017 at 05:27:23PM +0200, Tomeu Vizoso wrote:
> > > > > Labelling of files in a NFSv4.2 currently fails with ENOTSUPP
> > > > > because
> > > > > the mount point doesn't have SBLABEL_MNT.
> > > > > 
> > > > > Add specific condition for NFS4 filesystems so it gets
> > > > > correctly
> > > > > labeled.
> > > > 
> > > > Huh.  Looking at the code, I think this is meant to be handled
> > > > by
> > > > the
> > > > SECURITY_FS_USE_NATIVE case--there was a similar failure fixed
> > > > some
> > > > time
> > > > ago by 9fc2b4b436cf.  What kernel are you seeing this on?  Is
> > > > it a
> > > > recent regression (in which case, what's the latest kernel that
> > > > worked
> > > > for you)?
> > > 
> > > I have seen this on 4.11-rc4, but I never tried to get this
> > > working
> > > before.
> > > 
> > > I will try to find time to see why SECURITY_FS_USE_NATIVE isn't
> > > working here.
> > 
> > Does your exports file specify the "security_label" option, e.g.
> > /path/to/dir example.com(rw,security_label)
> 
> Oops, right, that should have been the first thing I asked about
> 
> > It appears that with recent kernels that is now required;
> > otherwise,
> > the mount defaults to not enabling native labeling and all of the
> > files
> > are treated as having a single, fixed label defined by the client
> > policy (and hence setxattr is not supported).  This was kernel
> > commit
> > 32ddd944a056c786f6acdd95ed29e994adc613a2.  I don't recall seeing
> > any
> > discussion of this on selinux list.  I understand the rationale,
> > but it
> > seems like a user-visible regression
> 
> It is.  I also want to keep new protocol upgrades free of user
> regressions, which the 4.1->4.2 upgrade is in most cases if we turn
> on
> security labeling by default.  So I was stuck choosing between two
> regresisons, and figured 4.2 user depending on security labeling was
> still the much rarer case.
> 
> So I'd like to keep security labeling off by default, but if there's
> anything I can do to smooth the transition obviously that's good.

Yes, I understand - wish though that it could have been communicated
better, e.g. on selinux list (unless I just missed it somehow).

> 
> > and at the very least, it seems odd that they didn't just use
> > "seclabel" as the kernel does in /proc/mounts to signify a
> > filesystem
> > that supports security labeling by userspace.
> 
> I see logic in sb_finish_set_opts() that sets SBLABEL_MNT in the
> selinux_is_sblabel_mnt() case.  Doesn't that mean "seclabel" shows up
> in
> /proc/mounts when we nfs sets SECURITY_LSM_NATIVE_LABELS?
> 
> I may not understand your comment, I'm pretty unfamiliar with this
> area.

Correct, I just meant it seems potentially confusing to users to use
"security_label" in exports when we show it as "seclabel" in
/proc/mounts.  I know, they are totally different namespaces (in the
conventional sense), but consistency might have been more user-
friendly.




Re: [PATCH] selinux: Fix SBLABEL_MNT for NFS mounts

2017-03-30 Thread Stephen Smalley
On Thu, 2017-03-30 at 09:49 +0200, Tomeu Vizoso wrote:
> On 29 March 2017 at 23:34, J. Bruce Fields 
> wrote:
> > On Wed, Mar 29, 2017 at 05:27:23PM +0200, Tomeu Vizoso wrote:
> > > Labelling of files in a NFSv4.2 currently fails with ENOTSUPP
> > > because
> > > the mount point doesn't have SBLABEL_MNT.
> > > 
> > > Add specific condition for NFS4 filesystems so it gets correctly
> > > labeled.
> > 
> > Huh.  Looking at the code, I think this is meant to be handled by
> > the
> > SECURITY_FS_USE_NATIVE case--there was a similar failure fixed some
> > time
> > ago by 9fc2b4b436cf.  What kernel are you seeing this on?  Is it a
> > recent regression (in which case, what's the latest kernel that
> > worked
> > for you)?
> 
> I have seen this on 4.11-rc4, but I never tried to get this working
> before.
> 
> I will try to find time to see why SECURITY_FS_USE_NATIVE isn't
> working here.

Does your exports file specify the "security_label" option, e.g.
/path/to/dir example.com(rw,security_label)

It appears that with recent kernels that is now required; otherwise,
the mount defaults to not enabling native labeling and all of the files
are treated as having a single, fixed label defined by the client
policy (and hence setxattr is not supported).  This was kernel commit
32ddd944a056c786f6acdd95ed29e994adc613a2.  I don't recall seeing any
discussion of this on selinux list.  I understand the rationale, but it
seems like a user-visible regression and at the very least, it seems
odd that they didn't just use "seclabel" as the kernel does in
/proc/mounts to signify a filesystem that supports security labeling by
userspace.


Re: [PATCH] selinux: Fix SBLABEL_MNT for NFS mounts

2017-03-30 Thread Stephen Smalley
On Thu, 2017-03-30 at 09:49 +0200, Tomeu Vizoso wrote:
> On 29 March 2017 at 23:34, J. Bruce Fields 
> wrote:
> > On Wed, Mar 29, 2017 at 05:27:23PM +0200, Tomeu Vizoso wrote:
> > > Labelling of files in a NFSv4.2 currently fails with ENOTSUPP
> > > because
> > > the mount point doesn't have SBLABEL_MNT.
> > > 
> > > Add specific condition for NFS4 filesystems so it gets correctly
> > > labeled.
> > 
> > Huh.  Looking at the code, I think this is meant to be handled by
> > the
> > SECURITY_FS_USE_NATIVE case--there was a similar failure fixed some
> > time
> > ago by 9fc2b4b436cf.  What kernel are you seeing this on?  Is it a
> > recent regression (in which case, what's the latest kernel that
> > worked
> > for you)?
> 
> I have seen this on 4.11-rc4, but I never tried to get this working
> before.
> 
> I will try to find time to see why SECURITY_FS_USE_NATIVE isn't
> working here.

Does your exports file specify the "security_label" option, e.g.
/path/to/dir example.com(rw,security_label)

It appears that with recent kernels that is now required; otherwise,
the mount defaults to not enabling native labeling and all of the files
are treated as having a single, fixed label defined by the client
policy (and hence setxattr is not supported).  This was kernel commit
32ddd944a056c786f6acdd95ed29e994adc613a2.  I don't recall seeing any
discussion of this on selinux list.  I understand the rationale, but it
seems like a user-visible regression and at the very least, it seems
odd that they didn't just use "seclabel" as the kernel does in
/proc/mounts to signify a filesystem that supports security labeling by
userspace.


Re: [PATCH] security: selinux: allow per-file labeling for cgroupfs

2017-03-10 Thread Stephen Smalley
On Fri, 2017-03-10 at 15:01 -0500, Paul Moore wrote:
> On Thu, Feb 9, 2017 at 10:58 AM, Antonio Murdaca  > wrote:
> > 
> > This patch allows genfscon per-file labeling for cgroupfs. For
> > instance,
> > this allows to label the "release_agent" file within each
> > cgroup mount and limit writes to it.
> > 
> > Signed-off-by: Antonio Murdaca 
> > ---
> >  security/selinux/hooks.c | 2 ++
> >  1 file changed, 2 insertions(+)
> 
> Now that the merge window is behind us, let's get this merged, but
> could you update it to use the selinux_policycap_cgroupseclabel
> policy
> capability?  See 2651225b5ebcdde ("selinux: wrap cgroup seclabel
> support with its own policy capability") for more information.

I don't think that is necessary.  This change unlike the other one
should not yield any difference in behavior with existing policy; it
just allows one to specify fine-grained labeling for cgroup nodes in
future policy.  It doesn't affect any userspace interface.


> Also, how goes the testing?
> 
> > 
> > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> > index 9a8f12f..5a3138e 100644
> > --- a/security/selinux/hooks.c
> > +++ b/security/selinux/hooks.c
> > @@ -808,6 +808,8 @@ static int selinux_set_mnt_opts(struct
> > super_block *sb,
> > 
> > if (!strcmp(sb->s_type->name, "debugfs") ||
> > !strcmp(sb->s_type->name, "sysfs") ||
> > +   !strcmp(sb->s_type->name, "cgroup") ||
> > +   !strcmp(sb->s_type->name, "cgroup2") ||
> > !strcmp(sb->s_type->name, "pstore"))
> > sbsec->flags |= SE_SBGENFS;
> > 
> > --
> > 2.9.3
> > 
> > ___
> > Selinux mailing list
> > seli...@tycho.nsa.gov
> > To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
> > To get help, send an email containing "help" to Selinux-request@tyc
> > ho.nsa.gov.
> 


Re: [PATCH] security: selinux: allow per-file labeling for cgroupfs

2017-03-10 Thread Stephen Smalley
On Fri, 2017-03-10 at 15:01 -0500, Paul Moore wrote:
> On Thu, Feb 9, 2017 at 10:58 AM, Antonio Murdaca  > wrote:
> > 
> > This patch allows genfscon per-file labeling for cgroupfs. For
> > instance,
> > this allows to label the "release_agent" file within each
> > cgroup mount and limit writes to it.
> > 
> > Signed-off-by: Antonio Murdaca 
> > ---
> >  security/selinux/hooks.c | 2 ++
> >  1 file changed, 2 insertions(+)
> 
> Now that the merge window is behind us, let's get this merged, but
> could you update it to use the selinux_policycap_cgroupseclabel
> policy
> capability?  See 2651225b5ebcdde ("selinux: wrap cgroup seclabel
> support with its own policy capability") for more information.

I don't think that is necessary.  This change unlike the other one
should not yield any difference in behavior with existing policy; it
just allows one to specify fine-grained labeling for cgroup nodes in
future policy.  It doesn't affect any userspace interface.


> Also, how goes the testing?
> 
> > 
> > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> > index 9a8f12f..5a3138e 100644
> > --- a/security/selinux/hooks.c
> > +++ b/security/selinux/hooks.c
> > @@ -808,6 +808,8 @@ static int selinux_set_mnt_opts(struct
> > super_block *sb,
> > 
> > if (!strcmp(sb->s_type->name, "debugfs") ||
> > !strcmp(sb->s_type->name, "sysfs") ||
> > +   !strcmp(sb->s_type->name, "cgroup") ||
> > +   !strcmp(sb->s_type->name, "cgroup2") ||
> > !strcmp(sb->s_type->name, "pstore"))
> > sbsec->flags |= SE_SBGENFS;
> > 
> > --
> > 2.9.3
> > 
> > ___
> > Selinux mailing list
> > seli...@tycho.nsa.gov
> > To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
> > To get help, send an email containing "help" to Selinux-request@tyc
> > ho.nsa.gov.
> 


[PATCH] fs: switch order of CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH checks

2017-03-10 Thread Stephen Smalley
generic_permission() presently checks CAP_DAC_OVERRIDE prior to
CAP_DAC_READ_SEARCH.  This can cause misleading audit messages when
using a LSM such as SELinux or AppArmor, since CAP_DAC_OVERRIDE
may not be required for the operation.  Flip the order of the
tests so that CAP_DAC_OVERRIDE is only checked when required for
the operation.

Signed-off-by: Stephen Smalley <s...@tycho.nsa.gov>
---
 fs/namei.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index d41fab7..482414a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -340,22 +340,14 @@ int generic_permission(struct inode *inode, int mask)
 
if (S_ISDIR(inode->i_mode)) {
/* DACs are overridable for directories */
-   if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
-   return 0;
if (!(mask & MAY_WRITE))
if (capable_wrt_inode_uidgid(inode,
 CAP_DAC_READ_SEARCH))
return 0;
-   return -EACCES;
-   }
-   /*
-* Read/write DACs are always overridable.
-* Executable DACs are overridable when there is
-* at least one exec bit set.
-*/
-   if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
return 0;
+   return -EACCES;
+   }
 
/*
 * Searching includes executable on directories, else just read.
@@ -364,6 +356,14 @@ int generic_permission(struct inode *inode, int mask)
if (mask == MAY_READ)
if (capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
return 0;
+   /*
+* Read/write DACs are always overridable.
+* Executable DACs are overridable when there is
+* at least one exec bit set.
+*/
+   if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
+   if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
+   return 0;
 
return -EACCES;
 }
-- 
2.7.4



[PATCH] fs: switch order of CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH checks

2017-03-10 Thread Stephen Smalley
generic_permission() presently checks CAP_DAC_OVERRIDE prior to
CAP_DAC_READ_SEARCH.  This can cause misleading audit messages when
using a LSM such as SELinux or AppArmor, since CAP_DAC_OVERRIDE
may not be required for the operation.  Flip the order of the
tests so that CAP_DAC_OVERRIDE is only checked when required for
the operation.

Signed-off-by: Stephen Smalley 
---
 fs/namei.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index d41fab7..482414a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -340,22 +340,14 @@ int generic_permission(struct inode *inode, int mask)
 
if (S_ISDIR(inode->i_mode)) {
/* DACs are overridable for directories */
-   if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
-   return 0;
if (!(mask & MAY_WRITE))
if (capable_wrt_inode_uidgid(inode,
 CAP_DAC_READ_SEARCH))
return 0;
-   return -EACCES;
-   }
-   /*
-* Read/write DACs are always overridable.
-* Executable DACs are overridable when there is
-* at least one exec bit set.
-*/
-   if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
return 0;
+   return -EACCES;
+   }
 
/*
 * Searching includes executable on directories, else just read.
@@ -364,6 +356,14 @@ int generic_permission(struct inode *inode, int mask)
if (mask == MAY_READ)
if (capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
return 0;
+   /*
+* Read/write DACs are always overridable.
+* Executable DACs are overridable when there is
+* at least one exec bit set.
+*/
+   if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
+   if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
+   return 0;
 
return -EACCES;
 }
-- 
2.7.4



Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-03-09 Thread Stephen Smalley
On Thu, 2017-03-09 at 18:28 +0100, Greg KH wrote:
> On Mon, Feb 27, 2017 at 04:23:28PM -0500, Stephen Smalley wrote:
> > 
> > On Mon, 2017-02-27 at 12:48 -0800, Nick Kralevich wrote:
> > > 
> > > On Mon, Feb 27, 2017 at 11:53 AM, Stephen Smalley <s...@tycho.nsa.
> > > gov>
> > > wrote:
> > > > 
> > > > 
> > > > > 
> > > > > 
> > > > > I can reproduce it on angler (with a back-port of just that
> > > > > patch),
> > > > > although I am unclear on the cause.  The patch is only
> > > > > supposed
> > > > > to
> > > > > enable explicit setting of security labels by userspace on
> > > > > cgroup
> > > > > files, so it isn't supposed to cause any breakage under
> > > > > existing
> > > > > policy.  Prior to the patch, the kernel would always just
> > > > > return
> > > > > -1
> > > > > with errno EOPNOTSUPP upon attempts to set security labels on
> > > > > cgroup
> > > > > files; with the patch, the kernel may instead return -1 with
> > > > > errno
> > > > > EACCES if not allowed.  So I suppose if userspace was
> > > > > explicitly
> > > > > testing for EOPNOTSUPP and not failing hard in that case, it
> > > > > might
> > > > > cause breakage.  Not sure why existing userspace would be
> > > > > trying
> > > > > to
> > > > > relabel cgroup files, unless it is just a recursive
> > > > > restorecon
> > > > > that
> > > > > happens to traverse into a cgroup mount (and in that case,
> > > > > not
> > > > > sure
> > > > > why
> > > > > it would be fatal).  Other possible interaction would be use
> > > > > of
> > > > > setfscreatecon() prior to creating a file in cgroup.
> > > > 
> > > > Oh, I see - it is the latter.
> > > > 
> > > > For example, init.rc does mkdir /dev/cpuctl/bg_non_interactive,
> > > > which
> > > > internally looks up the context for that directory from
> > > > file_contexts
> > > > and does a setfscreatecon() followed by a mkdir().  Previously,
> > > > that
> > > > was ignored because cgroup did not support anything other than
> > > > the
> > > > policy-defined label.  But now it will try to use that label,
> > > > which
> > > > in
> > > > turn will trigger a denial in enforcing mode and the create
> > > > will
> > > > fail.
> > > > 
> > > > So this is an incompatible change and needs to be reverted.
> > > > We'll need to wrap it up with a policy capability or something
> > > > to
> > > > allow
> > > > it to be enabled only if the policy correctly supports
> > > > it.  Even
> > > > better, we should instead just allow the policy to specify
> > > > which
> > > > filesystems should support this behavior (already on the issues
> > > > list).
> > > > 
> > > 
> > > If Android is the only system affected by this bug, I would
> > > prefer to
> > > just fix Android to allow for this patch, rather than having
> > > additional kernel complexity.
> > 
> > Well, it does break userspace (even if it happens to only affect
> > Android, which isn't clear, e.g. possibly a distribution would
> > likewise
> > suffer breakage under a tighter policy), and we already have a
> > long-
> > standing open issue to replace the current set of whitelisted
> > filesystem types with something configuration-driven.  So I'm ok
> > with
> > reverting it and requiring it to be done in a more general way.
> >  The
> > latter is something we want regardless.
> > 
> 
> Please revert this, it's not ok to break working userspace
> code.  I've
> gotten a few off-line queries as to why this ended up being merged
> when
> it was known to break Android.

It should be fixed by commit 2651225b5ebcdde60f684c4db8ec7e9e3800a74f
("selinux: wrap cgroup seclabel support with its own policy
capability").



Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-03-09 Thread Stephen Smalley
On Thu, 2017-03-09 at 18:28 +0100, Greg KH wrote:
> On Mon, Feb 27, 2017 at 04:23:28PM -0500, Stephen Smalley wrote:
> > 
> > On Mon, 2017-02-27 at 12:48 -0800, Nick Kralevich wrote:
> > > 
> > > On Mon, Feb 27, 2017 at 11:53 AM, Stephen Smalley  > > gov>
> > > wrote:
> > > > 
> > > > 
> > > > > 
> > > > > 
> > > > > I can reproduce it on angler (with a back-port of just that
> > > > > patch),
> > > > > although I am unclear on the cause.  The patch is only
> > > > > supposed
> > > > > to
> > > > > enable explicit setting of security labels by userspace on
> > > > > cgroup
> > > > > files, so it isn't supposed to cause any breakage under
> > > > > existing
> > > > > policy.  Prior to the patch, the kernel would always just
> > > > > return
> > > > > -1
> > > > > with errno EOPNOTSUPP upon attempts to set security labels on
> > > > > cgroup
> > > > > files; with the patch, the kernel may instead return -1 with
> > > > > errno
> > > > > EACCES if not allowed.  So I suppose if userspace was
> > > > > explicitly
> > > > > testing for EOPNOTSUPP and not failing hard in that case, it
> > > > > might
> > > > > cause breakage.  Not sure why existing userspace would be
> > > > > trying
> > > > > to
> > > > > relabel cgroup files, unless it is just a recursive
> > > > > restorecon
> > > > > that
> > > > > happens to traverse into a cgroup mount (and in that case,
> > > > > not
> > > > > sure
> > > > > why
> > > > > it would be fatal).  Other possible interaction would be use
> > > > > of
> > > > > setfscreatecon() prior to creating a file in cgroup.
> > > > 
> > > > Oh, I see - it is the latter.
> > > > 
> > > > For example, init.rc does mkdir /dev/cpuctl/bg_non_interactive,
> > > > which
> > > > internally looks up the context for that directory from
> > > > file_contexts
> > > > and does a setfscreatecon() followed by a mkdir().  Previously,
> > > > that
> > > > was ignored because cgroup did not support anything other than
> > > > the
> > > > policy-defined label.  But now it will try to use that label,
> > > > which
> > > > in
> > > > turn will trigger a denial in enforcing mode and the create
> > > > will
> > > > fail.
> > > > 
> > > > So this is an incompatible change and needs to be reverted.
> > > > We'll need to wrap it up with a policy capability or something
> > > > to
> > > > allow
> > > > it to be enabled only if the policy correctly supports
> > > > it.  Even
> > > > better, we should instead just allow the policy to specify
> > > > which
> > > > filesystems should support this behavior (already on the issues
> > > > list).
> > > > 
> > > 
> > > If Android is the only system affected by this bug, I would
> > > prefer to
> > > just fix Android to allow for this patch, rather than having
> > > additional kernel complexity.
> > 
> > Well, it does break userspace (even if it happens to only affect
> > Android, which isn't clear, e.g. possibly a distribution would
> > likewise
> > suffer breakage under a tighter policy), and we already have a
> > long-
> > standing open issue to replace the current set of whitelisted
> > filesystem types with something configuration-driven.  So I'm ok
> > with
> > reverting it and requiring it to be done in a more general way.
> >  The
> > latter is something we want regardless.
> > 
> 
> Please revert this, it's not ok to break working userspace
> code.  I've
> gotten a few off-line queries as to why this ended up being merged
> when
> it was known to break Android.

It should be fixed by commit 2651225b5ebcdde60f684c4db8ec7e9e3800a74f
("selinux: wrap cgroup seclabel support with its own policy
capability").



[tip:timers/urgent] timerfd: Only check CAP_WAKE_ALARM when it is needed

2017-03-01 Thread tip-bot for Stephen Smalley
Commit-ID:  25b68a8f0ab13a98de02650208ec927796659898
Gitweb: http://git.kernel.org/tip/25b68a8f0ab13a98de02650208ec927796659898
Author: Stephen Smalley <s...@tycho.nsa.gov>
AuthorDate: Fri, 17 Feb 2017 10:13:59 -0500
Committer:  Thomas Gleixner <t...@linutronix.de>
CommitDate: Wed, 1 Mar 2017 12:53:44 +0100

timerfd: Only check CAP_WAKE_ALARM when it is needed

timerfd_create() and do_timerfd_settime() evaluate capable(CAP_WAKE_ALARM)
unconditionally although CAP_WAKE_ALARM is only required for
CLOCK_REALTIME_ALARM and CLOCK_BOOTTIME_ALARM.

This can cause extraneous audit messages when using a LSM such as SELinux,
incorrectly causes PF_SUPERPRIV to be set even when no privilege was
exercised, and is inefficient.

Flip the order of the tests in both functions so that we only call
capable() if the capability is truly required for the operation.

Signed-off-by: Stephen Smalley <s...@tycho.nsa.gov>
Cc: linux-security-mod...@vger.kernel.org
Cc: seli...@tycho.nsa.gov
Link: 
http://lkml.kernel.org/r/1487344439-22293-1-git-send-email-...@tycho.nsa.gov
Signed-off-by: Thomas Gleixner <t...@linutronix.de>

---
 fs/timerfd.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/timerfd.c b/fs/timerfd.c
index 384fa75..c543cdb 100644
--- a/fs/timerfd.c
+++ b/fs/timerfd.c
@@ -400,9 +400,9 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
 clockid != CLOCK_BOOTTIME_ALARM))
return -EINVAL;
 
-   if (!capable(CAP_WAKE_ALARM) &&
-   (clockid == CLOCK_REALTIME_ALARM ||
-clockid == CLOCK_BOOTTIME_ALARM))
+   if ((clockid == CLOCK_REALTIME_ALARM ||
+clockid == CLOCK_BOOTTIME_ALARM) &&
+   !capable(CAP_WAKE_ALARM))
return -EPERM;
 
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -449,7 +449,7 @@ static int do_timerfd_settime(int ufd, int flags,
return ret;
ctx = f.file->private_data;
 
-   if (!capable(CAP_WAKE_ALARM) && isalarm(ctx)) {
+   if (isalarm(ctx) && !capable(CAP_WAKE_ALARM)) {
fdput(f);
return -EPERM;
}


[tip:timers/urgent] timerfd: Only check CAP_WAKE_ALARM when it is needed

2017-03-01 Thread tip-bot for Stephen Smalley
Commit-ID:  25b68a8f0ab13a98de02650208ec927796659898
Gitweb: http://git.kernel.org/tip/25b68a8f0ab13a98de02650208ec927796659898
Author: Stephen Smalley 
AuthorDate: Fri, 17 Feb 2017 10:13:59 -0500
Committer:  Thomas Gleixner 
CommitDate: Wed, 1 Mar 2017 12:53:44 +0100

timerfd: Only check CAP_WAKE_ALARM when it is needed

timerfd_create() and do_timerfd_settime() evaluate capable(CAP_WAKE_ALARM)
unconditionally although CAP_WAKE_ALARM is only required for
CLOCK_REALTIME_ALARM and CLOCK_BOOTTIME_ALARM.

This can cause extraneous audit messages when using a LSM such as SELinux,
incorrectly causes PF_SUPERPRIV to be set even when no privilege was
exercised, and is inefficient.

Flip the order of the tests in both functions so that we only call
capable() if the capability is truly required for the operation.

Signed-off-by: Stephen Smalley 
Cc: linux-security-mod...@vger.kernel.org
Cc: seli...@tycho.nsa.gov
Link: 
http://lkml.kernel.org/r/1487344439-22293-1-git-send-email-...@tycho.nsa.gov
Signed-off-by: Thomas Gleixner 

---
 fs/timerfd.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/timerfd.c b/fs/timerfd.c
index 384fa75..c543cdb 100644
--- a/fs/timerfd.c
+++ b/fs/timerfd.c
@@ -400,9 +400,9 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
 clockid != CLOCK_BOOTTIME_ALARM))
return -EINVAL;
 
-   if (!capable(CAP_WAKE_ALARM) &&
-   (clockid == CLOCK_REALTIME_ALARM ||
-clockid == CLOCK_BOOTTIME_ALARM))
+   if ((clockid == CLOCK_REALTIME_ALARM ||
+clockid == CLOCK_BOOTTIME_ALARM) &&
+   !capable(CAP_WAKE_ALARM))
return -EPERM;
 
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -449,7 +449,7 @@ static int do_timerfd_settime(int ufd, int flags,
return ret;
ctx = f.file->private_data;
 
-   if (!capable(CAP_WAKE_ALARM) && isalarm(ctx)) {
+   if (isalarm(ctx) && !capable(CAP_WAKE_ALARM)) {
fdput(f);
return -EPERM;
}


Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-02-28 Thread Stephen Smalley
On Mon, 2017-02-27 at 19:18 -0500, Paul Moore wrote:
> On Mon, Feb 27, 2017 at 4:23 PM, Stephen Smalley <s...@tycho.nsa.gov>
> wrote:
> > 
> > On Mon, 2017-02-27 at 12:48 -0800, Nick Kralevich wrote:
> > > 
> > > On Mon, Feb 27, 2017 at 11:53 AM, Stephen Smalley <s...@tycho.nsa.
> > > gov>
> > > wrote:
> > > > 
> > > > 
> > > > > 
> > > > > 
> > > > > I can reproduce it on angler (with a back-port of just that
> > > > > patch),
> > > > > although I am unclear on the cause.  The patch is only
> > > > > supposed
> > > > > to
> > > > > enable explicit setting of security labels by userspace on
> > > > > cgroup
> > > > > files, so it isn't supposed to cause any breakage under
> > > > > existing
> > > > > policy.  Prior to the patch, the kernel would always just
> > > > > return
> > > > > -1
> > > > > with errno EOPNOTSUPP upon attempts to set security labels on
> > > > > cgroup
> > > > > files; with the patch, the kernel may instead return -1 with
> > > > > errno
> > > > > EACCES if not allowed.  So I suppose if userspace was
> > > > > explicitly
> > > > > testing for EOPNOTSUPP and not failing hard in that case, it
> > > > > might
> > > > > cause breakage.  Not sure why existing userspace would be
> > > > > trying
> > > > > to
> > > > > relabel cgroup files, unless it is just a recursive
> > > > > restorecon
> > > > > that
> > > > > happens to traverse into a cgroup mount (and in that case,
> > > > > not
> > > > > sure
> > > > > why
> > > > > it would be fatal).  Other possible interaction would be use
> > > > > of
> > > > > setfscreatecon() prior to creating a file in cgroup.
> > > > 
> > > > Oh, I see - it is the latter.
> > > > 
> > > > For example, init.rc does mkdir /dev/cpuctl/bg_non_interactive,
> > > > which
> > > > internally looks up the context for that directory from
> > > > file_contexts
> > > > and does a setfscreatecon() followed by a mkdir().  Previously,
> > > > that
> > > > was ignored because cgroup did not support anything other than
> > > > the
> > > > policy-defined label.  But now it will try to use that label,
> > > > which
> > > > in
> > > > turn will trigger a denial in enforcing mode and the create
> > > > will
> > > > fail.
> > > > 
> > > > So this is an incompatible change and needs to be reverted.
> > > > We'll need to wrap it up with a policy capability or something
> > > > to
> > > > allow
> > > > it to be enabled only if the policy correctly supports
> > > > it.  Even
> > > > better, we should instead just allow the policy to specify
> > > > which
> > > > filesystems should support this behavior (already on the issues
> > > > list).
> > > > 
> > > 
> > > If Android is the only system affected by this bug, I would
> > > prefer to
> > > just fix Android to allow for this patch, rather than having
> > > additional kernel complexity.
> > 
> > Well, it does break userspace (even if it happens to only affect
> > Android, which isn't clear, e.g. possibly a distribution would
> > likewise
> > suffer breakage under a tighter policy), and we already have a
> > long-
> > standing open issue to replace the current set of whitelisted
> > filesystem types with something configuration-driven.  So I'm ok
> > with
> > reverting it and requiring it to be done in a more general
> > way.  The
> > latter is something we want regardless.
> 
> This went up to Linus during the current merge window via the
> stable-4.11 branch and I know the container guys really want this so
> I'd prefer to fix this up in 4.11 with a policy capability if
> possible
> (and I believe it should be).  I agree with Stephen that we need a
> better long term solution, but I think a policy capability should
> work
> in the short term.
> 
> Who wants to send me a patch? ;)

So, there are a couple of caveats with doing that:

1) It still requires the container folks to update their kernel,
libsepol, and policy in order to make use of the new policy capability.

2) The determination of whether a given mount should be assigned this
flag is made at mount time, so you can't simply reload policy with a
policy that defines this capability and have it automatically applied
to existing cgroup mounts.  You'd have to unmount and re-mount them
(more likely reboot).

Not saying you can't do that, just understand what is required.



Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-02-28 Thread Stephen Smalley
On Mon, 2017-02-27 at 19:18 -0500, Paul Moore wrote:
> On Mon, Feb 27, 2017 at 4:23 PM, Stephen Smalley 
> wrote:
> > 
> > On Mon, 2017-02-27 at 12:48 -0800, Nick Kralevich wrote:
> > > 
> > > On Mon, Feb 27, 2017 at 11:53 AM, Stephen Smalley  > > gov>
> > > wrote:
> > > > 
> > > > 
> > > > > 
> > > > > 
> > > > > I can reproduce it on angler (with a back-port of just that
> > > > > patch),
> > > > > although I am unclear on the cause.  The patch is only
> > > > > supposed
> > > > > to
> > > > > enable explicit setting of security labels by userspace on
> > > > > cgroup
> > > > > files, so it isn't supposed to cause any breakage under
> > > > > existing
> > > > > policy.  Prior to the patch, the kernel would always just
> > > > > return
> > > > > -1
> > > > > with errno EOPNOTSUPP upon attempts to set security labels on
> > > > > cgroup
> > > > > files; with the patch, the kernel may instead return -1 with
> > > > > errno
> > > > > EACCES if not allowed.  So I suppose if userspace was
> > > > > explicitly
> > > > > testing for EOPNOTSUPP and not failing hard in that case, it
> > > > > might
> > > > > cause breakage.  Not sure why existing userspace would be
> > > > > trying
> > > > > to
> > > > > relabel cgroup files, unless it is just a recursive
> > > > > restorecon
> > > > > that
> > > > > happens to traverse into a cgroup mount (and in that case,
> > > > > not
> > > > > sure
> > > > > why
> > > > > it would be fatal).  Other possible interaction would be use
> > > > > of
> > > > > setfscreatecon() prior to creating a file in cgroup.
> > > > 
> > > > Oh, I see - it is the latter.
> > > > 
> > > > For example, init.rc does mkdir /dev/cpuctl/bg_non_interactive,
> > > > which
> > > > internally looks up the context for that directory from
> > > > file_contexts
> > > > and does a setfscreatecon() followed by a mkdir().  Previously,
> > > > that
> > > > was ignored because cgroup did not support anything other than
> > > > the
> > > > policy-defined label.  But now it will try to use that label,
> > > > which
> > > > in
> > > > turn will trigger a denial in enforcing mode and the create
> > > > will
> > > > fail.
> > > > 
> > > > So this is an incompatible change and needs to be reverted.
> > > > We'll need to wrap it up with a policy capability or something
> > > > to
> > > > allow
> > > > it to be enabled only if the policy correctly supports
> > > > it.  Even
> > > > better, we should instead just allow the policy to specify
> > > > which
> > > > filesystems should support this behavior (already on the issues
> > > > list).
> > > > 
> > > 
> > > If Android is the only system affected by this bug, I would
> > > prefer to
> > > just fix Android to allow for this patch, rather than having
> > > additional kernel complexity.
> > 
> > Well, it does break userspace (even if it happens to only affect
> > Android, which isn't clear, e.g. possibly a distribution would
> > likewise
> > suffer breakage under a tighter policy), and we already have a
> > long-
> > standing open issue to replace the current set of whitelisted
> > filesystem types with something configuration-driven.  So I'm ok
> > with
> > reverting it and requiring it to be done in a more general
> > way.  The
> > latter is something we want regardless.
> 
> This went up to Linus during the current merge window via the
> stable-4.11 branch and I know the container guys really want this so
> I'd prefer to fix this up in 4.11 with a policy capability if
> possible
> (and I believe it should be).  I agree with Stephen that we need a
> better long term solution, but I think a policy capability should
> work
> in the short term.
> 
> Who wants to send me a patch? ;)

So, there are a couple of caveats with doing that:

1) It still requires the container folks to update their kernel,
libsepol, and policy in order to make use of the new policy capability.

2) The determination of whether a given mount should be assigned this
flag is made at mount time, so you can't simply reload policy with a
policy that defines this capability and have it automatically applied
to existing cgroup mounts.  You'd have to unmount and re-mount them
(more likely reboot).

Not saying you can't do that, just understand what is required.



Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-02-27 Thread Stephen Smalley
On Mon, 2017-02-27 at 14:42 -0500, Stephen Smalley wrote:
> On Thu, 2017-02-23 at 19:01 -0500, Paul Moore wrote:
> > 
> > On Thu, Feb 23, 2017 at 1:43 PM, John Stultz <john.stu...@linaro.or
> > g>
> > wrote:
> > > 
> > > 
> > > Hey folks,
> > >    I've not been able to figure out why yet, but I wanted to
> > > raise
> > > the
> > > issue that last night I found I couldn't boot Android on my Hikey
> > > board with Linus' HEAD kernel. It seems to cause logd to crash
> > > repeatedly so I'm not able to get debug info from logcat.
> > > 
> > > I do see the following over and over on the console:
> > > 
> > > [   12.505838] init: computing context for service 'logd'
> > > [   12.506355] init: starting service 'logd'...
> > > [   12.507683] init: property_set("ro.boottime.logd",
> > > "12500792498")
> > > failed: property already set
> > > [   12.508701] init: Created socket '/dev/socket/logd', mode 666,
> > > user
> > > 1036, group 1036
> > > [   12.509294] init: Created socket '/dev/socket/logdr', mode
> > > 666,
> > > user 1036, group 1036
> > > [   12.509891] init: Created socket '/dev/socket/logdw', mode
> > > 222,
> > > user 1036, group 1036
> > > [   12.510132] init: Opened file '/proc/kmsg', flags 0
> > > [   12.510187] init: Opened file '/dev/kmsg', flags 1
> > > [   12.510353] init: couldn't write 1941 to
> > > /dev/cpuset/system-background/tasks: No such file or directory
> > > [   12.533046] init: Service 'logd' (pid 1941) exited with status
> > > 255
> > > 
> > > 
> > > I did some bisection and narrowed it down to 1ea0ce4069
> > > ("selinux:
> > > allow changing labels for cgroupfs"), which was merged in
> > > yesterday.
> > > I've not yet been able to figure out the root cause, but
> > > reverting
> > > that patch makes things work again.
> > > 
> > > So I wanted to raise the issue here so folks were aware.
> > > 
> > > If there is anything folks want me to test or try, please let me
> > > know.
> > 
> > Unfortunately I don't have an Android test system to play with,
> > have
> > any of the SEAndroid folks on the To/CC line seen a similar
> > problem?
> 
> I can reproduce it on angler (with a back-port of just that patch),
> although I am unclear on the cause.  The patch is only supposed to
> enable explicit setting of security labels by userspace on cgroup
> files, so it isn't supposed to cause any breakage under existing
> policy.  Prior to the patch, the kernel would always just return -1
> with errno EOPNOTSUPP upon attempts to set security labels on cgroup
> files; with the patch, the kernel may instead return -1 with errno
> EACCES if not allowed.  So I suppose if userspace was explicitly
> testing for EOPNOTSUPP and not failing hard in that case, it might
> cause breakage.  Not sure why existing userspace would be trying to
> relabel cgroup files, unless it is just a recursive restorecon that
> happens to traverse into a cgroup mount (and in that case, not sure
> why
> it would be fatal).  Other possible interaction would be use of
> setfscreatecon() prior to creating a file in cgroup.

Oh, I see - it is the latter.

For example, init.rc does mkdir /dev/cpuctl/bg_non_interactive, which
internally looks up the context for that directory from file_contexts
and does a setfscreatecon() followed by a mkdir().  Previously, that
was ignored because cgroup did not support anything other than the
policy-defined label.  But now it will try to use that label, which in
turn will trigger a denial in enforcing mode and the create will fail.

So this is an incompatible change and needs to be reverted.
We'll need to wrap it up with a policy capability or something to allow
it to be enabled only if the policy correctly supports it.  Even
better, we should instead just allow the policy to specify which
filesystems should support this behavior (already on the issues list).



Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-02-27 Thread Stephen Smalley
On Mon, 2017-02-27 at 14:42 -0500, Stephen Smalley wrote:
> On Thu, 2017-02-23 at 19:01 -0500, Paul Moore wrote:
> > 
> > On Thu, Feb 23, 2017 at 1:43 PM, John Stultz  > g>
> > wrote:
> > > 
> > > 
> > > Hey folks,
> > >    I've not been able to figure out why yet, but I wanted to
> > > raise
> > > the
> > > issue that last night I found I couldn't boot Android on my Hikey
> > > board with Linus' HEAD kernel. It seems to cause logd to crash
> > > repeatedly so I'm not able to get debug info from logcat.
> > > 
> > > I do see the following over and over on the console:
> > > 
> > > [   12.505838] init: computing context for service 'logd'
> > > [   12.506355] init: starting service 'logd'...
> > > [   12.507683] init: property_set("ro.boottime.logd",
> > > "12500792498")
> > > failed: property already set
> > > [   12.508701] init: Created socket '/dev/socket/logd', mode 666,
> > > user
> > > 1036, group 1036
> > > [   12.509294] init: Created socket '/dev/socket/logdr', mode
> > > 666,
> > > user 1036, group 1036
> > > [   12.509891] init: Created socket '/dev/socket/logdw', mode
> > > 222,
> > > user 1036, group 1036
> > > [   12.510132] init: Opened file '/proc/kmsg', flags 0
> > > [   12.510187] init: Opened file '/dev/kmsg', flags 1
> > > [   12.510353] init: couldn't write 1941 to
> > > /dev/cpuset/system-background/tasks: No such file or directory
> > > [   12.533046] init: Service 'logd' (pid 1941) exited with status
> > > 255
> > > 
> > > 
> > > I did some bisection and narrowed it down to 1ea0ce4069
> > > ("selinux:
> > > allow changing labels for cgroupfs"), which was merged in
> > > yesterday.
> > > I've not yet been able to figure out the root cause, but
> > > reverting
> > > that patch makes things work again.
> > > 
> > > So I wanted to raise the issue here so folks were aware.
> > > 
> > > If there is anything folks want me to test or try, please let me
> > > know.
> > 
> > Unfortunately I don't have an Android test system to play with,
> > have
> > any of the SEAndroid folks on the To/CC line seen a similar
> > problem?
> 
> I can reproduce it on angler (with a back-port of just that patch),
> although I am unclear on the cause.  The patch is only supposed to
> enable explicit setting of security labels by userspace on cgroup
> files, so it isn't supposed to cause any breakage under existing
> policy.  Prior to the patch, the kernel would always just return -1
> with errno EOPNOTSUPP upon attempts to set security labels on cgroup
> files; with the patch, the kernel may instead return -1 with errno
> EACCES if not allowed.  So I suppose if userspace was explicitly
> testing for EOPNOTSUPP and not failing hard in that case, it might
> cause breakage.  Not sure why existing userspace would be trying to
> relabel cgroup files, unless it is just a recursive restorecon that
> happens to traverse into a cgroup mount (and in that case, not sure
> why
> it would be fatal).  Other possible interaction would be use of
> setfscreatecon() prior to creating a file in cgroup.

Oh, I see - it is the latter.

For example, init.rc does mkdir /dev/cpuctl/bg_non_interactive, which
internally looks up the context for that directory from file_contexts
and does a setfscreatecon() followed by a mkdir().  Previously, that
was ignored because cgroup did not support anything other than the
policy-defined label.  But now it will try to use that label, which in
turn will trigger a denial in enforcing mode and the create will fail.

So this is an incompatible change and needs to be reverted.
We'll need to wrap it up with a policy capability or something to allow
it to be enabled only if the policy correctly supports it.  Even
better, we should instead just allow the policy to specify which
filesystems should support this behavior (already on the issues list).



Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-02-27 Thread Stephen Smalley
On Mon, 2017-02-27 at 12:48 -0800, Nick Kralevich wrote:
> On Mon, Feb 27, 2017 at 11:53 AM, Stephen Smalley <s...@tycho.nsa.gov>
> wrote:
> > 
> > > 
> > > I can reproduce it on angler (with a back-port of just that
> > > patch),
> > > although I am unclear on the cause.  The patch is only supposed
> > > to
> > > enable explicit setting of security labels by userspace on cgroup
> > > files, so it isn't supposed to cause any breakage under existing
> > > policy.  Prior to the patch, the kernel would always just return
> > > -1
> > > with errno EOPNOTSUPP upon attempts to set security labels on
> > > cgroup
> > > files; with the patch, the kernel may instead return -1 with
> > > errno
> > > EACCES if not allowed.  So I suppose if userspace was explicitly
> > > testing for EOPNOTSUPP and not failing hard in that case, it
> > > might
> > > cause breakage.  Not sure why existing userspace would be trying
> > > to
> > > relabel cgroup files, unless it is just a recursive restorecon
> > > that
> > > happens to traverse into a cgroup mount (and in that case, not
> > > sure
> > > why
> > > it would be fatal).  Other possible interaction would be use of
> > > setfscreatecon() prior to creating a file in cgroup.
> > 
> > Oh, I see - it is the latter.
> > 
> > For example, init.rc does mkdir /dev/cpuctl/bg_non_interactive,
> > which
> > internally looks up the context for that directory from
> > file_contexts
> > and does a setfscreatecon() followed by a mkdir().  Previously,
> > that
> > was ignored because cgroup did not support anything other than the
> > policy-defined label.  But now it will try to use that label, which
> > in
> > turn will trigger a denial in enforcing mode and the create will
> > fail.
> > 
> > So this is an incompatible change and needs to be reverted.
> > We'll need to wrap it up with a policy capability or something to
> > allow
> > it to be enabled only if the policy correctly supports it.  Even
> > better, we should instead just allow the policy to specify which
> > filesystems should support this behavior (already on the issues
> > list).
> > 
> 
> If Android is the only system affected by this bug, I would prefer to
> just fix Android to allow for this patch, rather than having
> additional kernel complexity.

Well, it does break userspace (even if it happens to only affect
Android, which isn't clear, e.g. possibly a distribution would likewise
suffer breakage under a tighter policy), and we already have a long-
standing open issue to replace the current set of whitelisted
filesystem types with something configuration-driven.  So I'm ok with
reverting it and requiring it to be done in a more general way.  The
latter is something we want regardless.



Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-02-27 Thread Stephen Smalley
On Mon, 2017-02-27 at 12:48 -0800, Nick Kralevich wrote:
> On Mon, Feb 27, 2017 at 11:53 AM, Stephen Smalley 
> wrote:
> > 
> > > 
> > > I can reproduce it on angler (with a back-port of just that
> > > patch),
> > > although I am unclear on the cause.  The patch is only supposed
> > > to
> > > enable explicit setting of security labels by userspace on cgroup
> > > files, so it isn't supposed to cause any breakage under existing
> > > policy.  Prior to the patch, the kernel would always just return
> > > -1
> > > with errno EOPNOTSUPP upon attempts to set security labels on
> > > cgroup
> > > files; with the patch, the kernel may instead return -1 with
> > > errno
> > > EACCES if not allowed.  So I suppose if userspace was explicitly
> > > testing for EOPNOTSUPP and not failing hard in that case, it
> > > might
> > > cause breakage.  Not sure why existing userspace would be trying
> > > to
> > > relabel cgroup files, unless it is just a recursive restorecon
> > > that
> > > happens to traverse into a cgroup mount (and in that case, not
> > > sure
> > > why
> > > it would be fatal).  Other possible interaction would be use of
> > > setfscreatecon() prior to creating a file in cgroup.
> > 
> > Oh, I see - it is the latter.
> > 
> > For example, init.rc does mkdir /dev/cpuctl/bg_non_interactive,
> > which
> > internally looks up the context for that directory from
> > file_contexts
> > and does a setfscreatecon() followed by a mkdir().  Previously,
> > that
> > was ignored because cgroup did not support anything other than the
> > policy-defined label.  But now it will try to use that label, which
> > in
> > turn will trigger a denial in enforcing mode and the create will
> > fail.
> > 
> > So this is an incompatible change and needs to be reverted.
> > We'll need to wrap it up with a policy capability or something to
> > allow
> > it to be enabled only if the policy correctly supports it.  Even
> > better, we should instead just allow the policy to specify which
> > filesystems should support this behavior (already on the issues
> > list).
> > 
> 
> If Android is the only system affected by this bug, I would prefer to
> just fix Android to allow for this patch, rather than having
> additional kernel complexity.

Well, it does break userspace (even if it happens to only affect
Android, which isn't clear, e.g. possibly a distribution would likewise
suffer breakage under a tighter policy), and we already have a long-
standing open issue to replace the current set of whitelisted
filesystem types with something configuration-driven.  So I'm ok with
reverting it and requiring it to be done in a more general way.  The
latter is something we want regardless.



Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-02-27 Thread Stephen Smalley
On Mon, 2017-02-27 at 16:23 -0500, Stephen Smalley wrote:
> On Mon, 2017-02-27 at 12:48 -0800, Nick Kralevich wrote:
> > 
> > On Mon, Feb 27, 2017 at 11:53 AM, Stephen Smalley <s...@tycho.nsa.go
> > v>
> > wrote:
> > > 
> > > 
> > > > 
> > > > 
> > > > I can reproduce it on angler (with a back-port of just that
> > > > patch),
> > > > although I am unclear on the cause.  The patch is only supposed
> > > > to
> > > > enable explicit setting of security labels by userspace on
> > > > cgroup
> > > > files, so it isn't supposed to cause any breakage under
> > > > existing
> > > > policy.  Prior to the patch, the kernel would always just
> > > > return
> > > > -1
> > > > with errno EOPNOTSUPP upon attempts to set security labels on
> > > > cgroup
> > > > files; with the patch, the kernel may instead return -1 with
> > > > errno
> > > > EACCES if not allowed.  So I suppose if userspace was
> > > > explicitly
> > > > testing for EOPNOTSUPP and not failing hard in that case, it
> > > > might
> > > > cause breakage.  Not sure why existing userspace would be
> > > > trying
> > > > to
> > > > relabel cgroup files, unless it is just a recursive restorecon
> > > > that
> > > > happens to traverse into a cgroup mount (and in that case, not
> > > > sure
> > > > why
> > > > it would be fatal).  Other possible interaction would be use of
> > > > setfscreatecon() prior to creating a file in cgroup.
> > > 
> > > Oh, I see - it is the latter.
> > > 
> > > For example, init.rc does mkdir /dev/cpuctl/bg_non_interactive,
> > > which
> > > internally looks up the context for that directory from
> > > file_contexts
> > > and does a setfscreatecon() followed by a mkdir().  Previously,
> > > that
> > > was ignored because cgroup did not support anything other than
> > > the
> > > policy-defined label.  But now it will try to use that label,
> > > which
> > > in
> > > turn will trigger a denial in enforcing mode and the create will
> > > fail.
> > > 
> > > So this is an incompatible change and needs to be reverted.
> > > We'll need to wrap it up with a policy capability or something to
> > > allow
> > > it to be enabled only if the policy correctly supports it.  Even
> > > better, we should instead just allow the policy to specify which
> > > filesystems should support this behavior (already on the issues
> > > list).
> > > 
> > 
> > If Android is the only system affected by this bug, I would prefer
> > to
> > just fix Android to allow for this patch, rather than having
> > additional kernel complexity.
> 
> Well, it does break userspace (even if it happens to only affect
> Android, which isn't clear, e.g. possibly a distribution would
> likewise
> suffer breakage under a tighter policy), and we already have a long-
> standing open issue to replace the current set of whitelisted
> filesystem types with something configuration-driven.  So I'm ok with
> reverting it and requiring it to be done in a more general way.  The
> latter is something we want regardless.

Also, I'm not sure it can be fixed cleanly just by policy, or at least
not just via kernel policy.  You wouldn't want to allow creation of
cgroup files in the contexts presently specified via file_contexts; you
would need to modify file_contexts to correctly specify the cgroup file
contexts.  And that in turn raises another existing issue:
distinguishing the label for the mountpoint directory versus the
mounted directory.



Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-02-27 Thread Stephen Smalley
On Mon, 2017-02-27 at 16:23 -0500, Stephen Smalley wrote:
> On Mon, 2017-02-27 at 12:48 -0800, Nick Kralevich wrote:
> > 
> > On Mon, Feb 27, 2017 at 11:53 AM, Stephen Smalley  > v>
> > wrote:
> > > 
> > > 
> > > > 
> > > > 
> > > > I can reproduce it on angler (with a back-port of just that
> > > > patch),
> > > > although I am unclear on the cause.  The patch is only supposed
> > > > to
> > > > enable explicit setting of security labels by userspace on
> > > > cgroup
> > > > files, so it isn't supposed to cause any breakage under
> > > > existing
> > > > policy.  Prior to the patch, the kernel would always just
> > > > return
> > > > -1
> > > > with errno EOPNOTSUPP upon attempts to set security labels on
> > > > cgroup
> > > > files; with the patch, the kernel may instead return -1 with
> > > > errno
> > > > EACCES if not allowed.  So I suppose if userspace was
> > > > explicitly
> > > > testing for EOPNOTSUPP and not failing hard in that case, it
> > > > might
> > > > cause breakage.  Not sure why existing userspace would be
> > > > trying
> > > > to
> > > > relabel cgroup files, unless it is just a recursive restorecon
> > > > that
> > > > happens to traverse into a cgroup mount (and in that case, not
> > > > sure
> > > > why
> > > > it would be fatal).  Other possible interaction would be use of
> > > > setfscreatecon() prior to creating a file in cgroup.
> > > 
> > > Oh, I see - it is the latter.
> > > 
> > > For example, init.rc does mkdir /dev/cpuctl/bg_non_interactive,
> > > which
> > > internally looks up the context for that directory from
> > > file_contexts
> > > and does a setfscreatecon() followed by a mkdir().  Previously,
> > > that
> > > was ignored because cgroup did not support anything other than
> > > the
> > > policy-defined label.  But now it will try to use that label,
> > > which
> > > in
> > > turn will trigger a denial in enforcing mode and the create will
> > > fail.
> > > 
> > > So this is an incompatible change and needs to be reverted.
> > > We'll need to wrap it up with a policy capability or something to
> > > allow
> > > it to be enabled only if the policy correctly supports it.  Even
> > > better, we should instead just allow the policy to specify which
> > > filesystems should support this behavior (already on the issues
> > > list).
> > > 
> > 
> > If Android is the only system affected by this bug, I would prefer
> > to
> > just fix Android to allow for this patch, rather than having
> > additional kernel complexity.
> 
> Well, it does break userspace (even if it happens to only affect
> Android, which isn't clear, e.g. possibly a distribution would
> likewise
> suffer breakage under a tighter policy), and we already have a long-
> standing open issue to replace the current set of whitelisted
> filesystem types with something configuration-driven.  So I'm ok with
> reverting it and requiring it to be done in a more general way.  The
> latter is something we want regardless.

Also, I'm not sure it can be fixed cleanly just by policy, or at least
not just via kernel policy.  You wouldn't want to allow creation of
cgroup files in the contexts presently specified via file_contexts; you
would need to modify file_contexts to correctly specify the cgroup file
contexts.  And that in turn raises another existing issue:
distinguishing the label for the mountpoint directory versus the
mounted directory.



Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-02-27 Thread Stephen Smalley
On Thu, 2017-02-23 at 19:01 -0500, Paul Moore wrote:
> On Thu, Feb 23, 2017 at 1:43 PM, John Stultz 
> wrote:
> > 
> > Hey folks,
> >    I've not been able to figure out why yet, but I wanted to raise
> > the
> > issue that last night I found I couldn't boot Android on my Hikey
> > board with Linus' HEAD kernel. It seems to cause logd to crash
> > repeatedly so I'm not able to get debug info from logcat.
> > 
> > I do see the following over and over on the console:
> > 
> > [   12.505838] init: computing context for service 'logd'
> > [   12.506355] init: starting service 'logd'...
> > [   12.507683] init: property_set("ro.boottime.logd",
> > "12500792498")
> > failed: property already set
> > [   12.508701] init: Created socket '/dev/socket/logd', mode 666,
> > user
> > 1036, group 1036
> > [   12.509294] init: Created socket '/dev/socket/logdr', mode 666,
> > user 1036, group 1036
> > [   12.509891] init: Created socket '/dev/socket/logdw', mode 222,
> > user 1036, group 1036
> > [   12.510132] init: Opened file '/proc/kmsg', flags 0
> > [   12.510187] init: Opened file '/dev/kmsg', flags 1
> > [   12.510353] init: couldn't write 1941 to
> > /dev/cpuset/system-background/tasks: No such file or directory
> > [   12.533046] init: Service 'logd' (pid 1941) exited with status
> > 255
> > 
> > 
> > I did some bisection and narrowed it down to 1ea0ce4069 ("selinux:
> > allow changing labels for cgroupfs"), which was merged in
> > yesterday.
> > I've not yet been able to figure out the root cause, but reverting
> > that patch makes things work again.
> > 
> > So I wanted to raise the issue here so folks were aware.
> > 
> > If there is anything folks want me to test or try, please let me
> > know.
> 
> Unfortunately I don't have an Android test system to play with, have
> any of the SEAndroid folks on the To/CC line seen a similar problem?

I can reproduce it on angler (with a back-port of just that patch),
although I am unclear on the cause.  The patch is only supposed to
enable explicit setting of security labels by userspace on cgroup
files, so it isn't supposed to cause any breakage under existing
policy.  Prior to the patch, the kernel would always just return -1
with errno EOPNOTSUPP upon attempts to set security labels on cgroup
files; with the patch, the kernel may instead return -1 with errno
EACCES if not allowed.  So I suppose if userspace was explicitly
testing for EOPNOTSUPP and not failing hard in that case, it might
cause breakage.  Not sure why existing userspace would be trying to
relabel cgroup files, unless it is just a recursive restorecon that
happens to traverse into a cgroup mount (and in that case, not sure why
it would be fatal).  Other possible interaction would be use of
setfscreatecon() prior to creating a file in cgroup.



Re: [Regression?] 1ea0ce4069 ("selinux: allow changing labels for cgroupfs") stops Android from booting

2017-02-27 Thread Stephen Smalley
On Thu, 2017-02-23 at 19:01 -0500, Paul Moore wrote:
> On Thu, Feb 23, 2017 at 1:43 PM, John Stultz 
> wrote:
> > 
> > Hey folks,
> >    I've not been able to figure out why yet, but I wanted to raise
> > the
> > issue that last night I found I couldn't boot Android on my Hikey
> > board with Linus' HEAD kernel. It seems to cause logd to crash
> > repeatedly so I'm not able to get debug info from logcat.
> > 
> > I do see the following over and over on the console:
> > 
> > [   12.505838] init: computing context for service 'logd'
> > [   12.506355] init: starting service 'logd'...
> > [   12.507683] init: property_set("ro.boottime.logd",
> > "12500792498")
> > failed: property already set
> > [   12.508701] init: Created socket '/dev/socket/logd', mode 666,
> > user
> > 1036, group 1036
> > [   12.509294] init: Created socket '/dev/socket/logdr', mode 666,
> > user 1036, group 1036
> > [   12.509891] init: Created socket '/dev/socket/logdw', mode 222,
> > user 1036, group 1036
> > [   12.510132] init: Opened file '/proc/kmsg', flags 0
> > [   12.510187] init: Opened file '/dev/kmsg', flags 1
> > [   12.510353] init: couldn't write 1941 to
> > /dev/cpuset/system-background/tasks: No such file or directory
> > [   12.533046] init: Service 'logd' (pid 1941) exited with status
> > 255
> > 
> > 
> > I did some bisection and narrowed it down to 1ea0ce4069 ("selinux:
> > allow changing labels for cgroupfs"), which was merged in
> > yesterday.
> > I've not yet been able to figure out the root cause, but reverting
> > that patch makes things work again.
> > 
> > So I wanted to raise the issue here so folks were aware.
> > 
> > If there is anything folks want me to test or try, please let me
> > know.
> 
> Unfortunately I don't have an Android test system to play with, have
> any of the SEAndroid folks on the To/CC line seen a similar problem?

I can reproduce it on angler (with a back-port of just that patch),
although I am unclear on the cause.  The patch is only supposed to
enable explicit setting of security labels by userspace on cgroup
files, so it isn't supposed to cause any breakage under existing
policy.  Prior to the patch, the kernel would always just return -1
with errno EOPNOTSUPP upon attempts to set security labels on cgroup
files; with the patch, the kernel may instead return -1 with errno
EACCES if not allowed.  So I suppose if userspace was explicitly
testing for EOPNOTSUPP and not failing hard in that case, it might
cause breakage.  Not sure why existing userspace would be trying to
relabel cgroup files, unless it is just a recursive restorecon that
happens to traverse into a cgroup mount (and in that case, not sure why
it would be fatal).  Other possible interaction would be use of
setfscreatecon() prior to creating a file in cgroup.



[PATCH] fs: switch order of CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH checks

2017-02-17 Thread Stephen Smalley
generic_permission() presently checks CAP_DAC_OVERRIDE prior to
CAP_DAC_READ_SEARCH.  This can cause misleading audit messages when
using a LSM such as SELinux or AppArmor, since CAP_DAC_OVERRIDE
may not be required for the operation.  Flip the order of the
tests so that CAP_DAC_OVERRIDE is only checked when required for
the operation.

Signed-off-by: Stephen Smalley <s...@tycho.nsa.gov>
---
 fs/namei.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index ad74877..8736e4a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -340,22 +340,14 @@ int generic_permission(struct inode *inode, int mask)
 
if (S_ISDIR(inode->i_mode)) {
/* DACs are overridable for directories */
-   if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
-   return 0;
if (!(mask & MAY_WRITE))
if (capable_wrt_inode_uidgid(inode,
 CAP_DAC_READ_SEARCH))
return 0;
-   return -EACCES;
-   }
-   /*
-* Read/write DACs are always overridable.
-* Executable DACs are overridable when there is
-* at least one exec bit set.
-*/
-   if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
return 0;
+   return -EACCES;
+   }
 
/*
 * Searching includes executable on directories, else just read.
@@ -364,6 +356,14 @@ int generic_permission(struct inode *inode, int mask)
if (mask == MAY_READ)
if (capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
return 0;
+   /*
+* Read/write DACs are always overridable.
+* Executable DACs are overridable when there is
+* at least one exec bit set.
+*/
+   if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
+   if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
+   return 0;
 
return -EACCES;
 }
-- 
2.7.4



[PATCH] fs: switch order of CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH checks

2017-02-17 Thread Stephen Smalley
generic_permission() presently checks CAP_DAC_OVERRIDE prior to
CAP_DAC_READ_SEARCH.  This can cause misleading audit messages when
using a LSM such as SELinux or AppArmor, since CAP_DAC_OVERRIDE
may not be required for the operation.  Flip the order of the
tests so that CAP_DAC_OVERRIDE is only checked when required for
the operation.

Signed-off-by: Stephen Smalley 
---
 fs/namei.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index ad74877..8736e4a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -340,22 +340,14 @@ int generic_permission(struct inode *inode, int mask)
 
if (S_ISDIR(inode->i_mode)) {
/* DACs are overridable for directories */
-   if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
-   return 0;
if (!(mask & MAY_WRITE))
if (capable_wrt_inode_uidgid(inode,
 CAP_DAC_READ_SEARCH))
return 0;
-   return -EACCES;
-   }
-   /*
-* Read/write DACs are always overridable.
-* Executable DACs are overridable when there is
-* at least one exec bit set.
-*/
-   if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
return 0;
+   return -EACCES;
+   }
 
/*
 * Searching includes executable on directories, else just read.
@@ -364,6 +356,14 @@ int generic_permission(struct inode *inode, int mask)
if (mask == MAY_READ)
if (capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
return 0;
+   /*
+* Read/write DACs are always overridable.
+* Executable DACs are overridable when there is
+* at least one exec bit set.
+*/
+   if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
+   if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
+   return 0;
 
return -EACCES;
 }
-- 
2.7.4



[PATCH] timerfd: only check CAP_WAKE_ALARM when it is needed

2017-02-17 Thread Stephen Smalley
timerfd_create() and do_timerfd_settime() presently always
call capable(CAP_WAKE_ALARM) although CAP_WAKE_ALARM is
only required for CLOCK_REALTIME_ALARM and CLOCK_BOOTTIME_ALARM.
This can cause extraneous audit messages when using a LSM such
as SELinux, incorrectly causes PF_SUPERPRIV to be set even when
no privilege was exercised, and is inefficient.  Flip the order
of the tests in both functions so that we only call capable() if
the capability is truly required for the operation.

Signed-off-by: Stephen Smalley <s...@tycho.nsa.gov>
---
 fs/timerfd.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/timerfd.c b/fs/timerfd.c
index 384fa75..c543cdb 100644
--- a/fs/timerfd.c
+++ b/fs/timerfd.c
@@ -400,9 +400,9 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
 clockid != CLOCK_BOOTTIME_ALARM))
return -EINVAL;
 
-   if (!capable(CAP_WAKE_ALARM) &&
-   (clockid == CLOCK_REALTIME_ALARM ||
-clockid == CLOCK_BOOTTIME_ALARM))
+   if ((clockid == CLOCK_REALTIME_ALARM ||
+clockid == CLOCK_BOOTTIME_ALARM) &&
+   !capable(CAP_WAKE_ALARM))
return -EPERM;
 
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -449,7 +449,7 @@ static int do_timerfd_settime(int ufd, int flags,
return ret;
ctx = f.file->private_data;
 
-   if (!capable(CAP_WAKE_ALARM) && isalarm(ctx)) {
+   if (isalarm(ctx) && !capable(CAP_WAKE_ALARM)) {
fdput(f);
return -EPERM;
}
-- 
2.7.4



[PATCH] timerfd: only check CAP_WAKE_ALARM when it is needed

2017-02-17 Thread Stephen Smalley
timerfd_create() and do_timerfd_settime() presently always
call capable(CAP_WAKE_ALARM) although CAP_WAKE_ALARM is
only required for CLOCK_REALTIME_ALARM and CLOCK_BOOTTIME_ALARM.
This can cause extraneous audit messages when using a LSM such
as SELinux, incorrectly causes PF_SUPERPRIV to be set even when
no privilege was exercised, and is inefficient.  Flip the order
of the tests in both functions so that we only call capable() if
the capability is truly required for the operation.

Signed-off-by: Stephen Smalley 
---
 fs/timerfd.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/timerfd.c b/fs/timerfd.c
index 384fa75..c543cdb 100644
--- a/fs/timerfd.c
+++ b/fs/timerfd.c
@@ -400,9 +400,9 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
 clockid != CLOCK_BOOTTIME_ALARM))
return -EINVAL;
 
-   if (!capable(CAP_WAKE_ALARM) &&
-   (clockid == CLOCK_REALTIME_ALARM ||
-clockid == CLOCK_BOOTTIME_ALARM))
+   if ((clockid == CLOCK_REALTIME_ALARM ||
+clockid == CLOCK_BOOTTIME_ALARM) &&
+   !capable(CAP_WAKE_ALARM))
return -EPERM;
 
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -449,7 +449,7 @@ static int do_timerfd_settime(int ufd, int flags,
return ret;
ctx = f.file->private_data;
 
-   if (!capable(CAP_WAKE_ALARM) && isalarm(ctx)) {
+   if (isalarm(ctx) && !capable(CAP_WAKE_ALARM)) {
fdput(f);
return -EPERM;
}
-- 
2.7.4



Re: [PATCH v2] security: selinux: allow changing labels for cgroupfs

2017-02-02 Thread Stephen Smalley
On Thu, 2017-02-02 at 16:22 +0100, Antonio Murdaca wrote:
> This patch allows changing labels for cgroup mounts. Previously,
> running
> chcon on cgroupfs would throw an "Operation not supported". This
> patch
> specifically whitelist cgroupfs.
> 
> The patch could also allow containers to write only to the systemd
> cgroup
> for instance, while the other cgroups are kept with cgroup_t label.
> 
> Signed-off-by: Antonio Murdaca <run...@redhat.com>

Acked-by: Stephen Smalley <s...@tycho.nsa.gov>

> ---
> Changes in v2:
>   - whitelist cgroup2 fs type
> 
>  security/selinux/hooks.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 3b955c6..2789f0a 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -480,6 +480,8 @@ static int selinux_is_sblabel_mnt(struct
> super_block *sb)
>   sbsec->behavior == SECURITY_FS_USE_NATIVE ||
>   /* Special handling. Genfs but also in-core setxattr
> handler */
>   !strcmp(sb->s_type->name, "sysfs") ||
> + !strcmp(sb->s_type->name, "cgroup") ||
> + !strcmp(sb->s_type->name, "cgroup2") ||
>   !strcmp(sb->s_type->name, "pstore") ||
>   !strcmp(sb->s_type->name, "debugfs") ||
>   !strcmp(sb->s_type->name, "tracefs") ||


Re: [PATCH v2] security: selinux: allow changing labels for cgroupfs

2017-02-02 Thread Stephen Smalley
On Thu, 2017-02-02 at 16:22 +0100, Antonio Murdaca wrote:
> This patch allows changing labels for cgroup mounts. Previously,
> running
> chcon on cgroupfs would throw an "Operation not supported". This
> patch
> specifically whitelist cgroupfs.
> 
> The patch could also allow containers to write only to the systemd
> cgroup
> for instance, while the other cgroups are kept with cgroup_t label.
> 
> Signed-off-by: Antonio Murdaca 

Acked-by: Stephen Smalley 

> ---
> Changes in v2:
>   - whitelist cgroup2 fs type
> 
>  security/selinux/hooks.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 3b955c6..2789f0a 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -480,6 +480,8 @@ static int selinux_is_sblabel_mnt(struct
> super_block *sb)
>   sbsec->behavior == SECURITY_FS_USE_NATIVE ||
>   /* Special handling. Genfs but also in-core setxattr
> handler */
>   !strcmp(sb->s_type->name, "sysfs") ||
> + !strcmp(sb->s_type->name, "cgroup") ||
> + !strcmp(sb->s_type->name, "cgroup2") ||
>   !strcmp(sb->s_type->name, "pstore") ||
>   !strcmp(sb->s_type->name, "debugfs") ||
>   !strcmp(sb->s_type->name, "tracefs") ||


Re: SELinux lead to soft lockup when pid 1 proceess reap child

2017-01-09 Thread Stephen Smalley
On Mon, 2017-01-09 at 19:29 +0100, Oleg Nesterov wrote:
> Seriously, could someone explain why do we need the
> security_task_wait()
> hook at all?

I would be ok with killing it.
IIRC, the original motivation was to block an unauthorized data flow
from child to parent when the child context differs, but part of that
original design was also to reparent the child automatically, and that
was never implemented.  I don't think there is a real use case for it
in practice and it just breaks things, so let's get rid of it unless
someone objects.

> 
> 
> On 01/09, Oleg Nesterov wrote:
> > 
> > 
> > On 01/09, yangshukui wrote:
> > > 
> > > 
> > > --- a/security/selinux/hooks.c
> > > +++ b/security/selinux/hooks.c
> > > @@ -3596,6 +3596,9 @@ static int selinux_task_kill(struct
> > > task_struct *p,
> > > struct siginfo *info,
> > > 
> > >  static int selinux_task_wait(struct task_struct *p)
> > >  {
> > > +   if (pid_vnr(task_tgid(current)) == 1){
> > > +return 0;
> > 
> > this check is not really correct, it can be a sub-thread... Doesn't
> > matter,
> > please see below.
> > 
> > > 
> > > +   }
> > > return task_has_perm(p, current, PROCESS__SIGCHLD);
> > >  }
> > > It work but it permit pid 1 process to reap child without selinux
> > > check. Can
> > > we have a better way to handle this problem?
> > 
> > I never understood why security_task_wait() should deny to reap a
> > child. But
> > since it can we probably want some explicit "the whole namespace
> > goes away" check.
> > We could use, say, PIDNS_HASH_ADDING but I'd suggest something like
> > a trivial change
> > below for now.
> > 
> > Eric, what do you think?
> > 
> > Oleg.
> > 
> > diff --git a/security/security.c b/security/security.c
> > index f825304..1330b4e 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -1027,6 +1027,9 @@ int security_task_kill(struct task_struct *p,
> > struct siginfo *info,
> >  
> >  int security_task_wait(struct task_struct *p)
> >  {
> > +   /* must be the exiting child reaper */
> > +   if (unlikely(current->flags & PF_EXITING))
> > +   return 0;
> >     return call_int_hook(task_wait, 0, p);
> >  }
> >  


Re: SELinux lead to soft lockup when pid 1 proceess reap child

2017-01-09 Thread Stephen Smalley
On Mon, 2017-01-09 at 19:29 +0100, Oleg Nesterov wrote:
> Seriously, could someone explain why do we need the
> security_task_wait()
> hook at all?

I would be ok with killing it.
IIRC, the original motivation was to block an unauthorized data flow
from child to parent when the child context differs, but part of that
original design was also to reparent the child automatically, and that
was never implemented.  I don't think there is a real use case for it
in practice and it just breaks things, so let's get rid of it unless
someone objects.

> 
> 
> On 01/09, Oleg Nesterov wrote:
> > 
> > 
> > On 01/09, yangshukui wrote:
> > > 
> > > 
> > > --- a/security/selinux/hooks.c
> > > +++ b/security/selinux/hooks.c
> > > @@ -3596,6 +3596,9 @@ static int selinux_task_kill(struct
> > > task_struct *p,
> > > struct siginfo *info,
> > > 
> > >  static int selinux_task_wait(struct task_struct *p)
> > >  {
> > > +   if (pid_vnr(task_tgid(current)) == 1){
> > > +return 0;
> > 
> > this check is not really correct, it can be a sub-thread... Doesn't
> > matter,
> > please see below.
> > 
> > > 
> > > +   }
> > > return task_has_perm(p, current, PROCESS__SIGCHLD);
> > >  }
> > > It work but it permit pid 1 process to reap child without selinux
> > > check. Can
> > > we have a better way to handle this problem?
> > 
> > I never understood why security_task_wait() should deny to reap a
> > child. But
> > since it can we probably want some explicit "the whole namespace
> > goes away" check.
> > We could use, say, PIDNS_HASH_ADDING but I'd suggest something like
> > a trivial change
> > below for now.
> > 
> > Eric, what do you think?
> > 
> > Oleg.
> > 
> > diff --git a/security/security.c b/security/security.c
> > index f825304..1330b4e 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -1027,6 +1027,9 @@ int security_task_kill(struct task_struct *p,
> > struct siginfo *info,
> >  
> >  int security_task_wait(struct task_struct *p)
> >  {
> > +   /* must be the exiting child reaper */
> > +   if (unlikely(current->flags & PF_EXITING))
> > +   return 0;
> >     return call_int_hook(task_wait, 0, p);
> >  }
> >  


Re: [PATCH v3 3/3] selinux: require EXECMEM for forced ptrace poke

2016-11-03 Thread Stephen Smalley
On 11/02/2016 11:04 PM, Jann Horn wrote:
> This restricts forced writes to private R+X mappings using the EXECMEM
> permission. To avoid a breaking change, a new policy capability needs to
> be enabled before the new restrictions take effect.
> 
> Unlike most other SELinux hooks, this one takes the subject credentials as
> an argument instead of looking up current_cred(). This is done because the
> security_forced_write() LSM hook can be invoked from within the write
> handler of /proc/$pid/mem, where current_cred() is pretty useless.
> 
> Changed in v3:
>  - minor: symmetric comment (Ingo Molnar)
>  - use helper struct (Ingo Molnar)
>  - add new policy capability for enabling forced write checks
>(Stephen Smalley)
> 
> Signed-off-by: Jann Horn <j...@thejh.net>
> ---
>  security/selinux/hooks.c| 15 +++
>  security/selinux/include/security.h |  2 ++
>  security/selinux/selinuxfs.c|  3 ++-
>  security/selinux/ss/services.c  |  3 +++
>  4 files changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 09fd6108e421..cdd9c53db2ed 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2144,6 +2144,20 @@ static int selinux_ptrace_traceme(struct task_struct 
> *parent)
>   return task_has_perm(parent, current, PROCESS__PTRACE);
>  }
>  
> +static int selinux_forced_write(struct vm_area_struct *vma,
> + const struct gup_creds *creds)
> +{
> + /*
> +  * Permitting a write to readonly memory is fine - making the readonly
> +  * memory executable afterwards would require EXECMOD permission because
> +  * anon_vma would be non-NULL.
> +  */
> + if (!selinux_policycap_forcedwrite || (vma->vm_flags & VM_EXEC) == 0)
> + return 0;
> +
> + return cred_has_perm(creds->subject, creds->object, PROCESS__EXECMEM);
> +}
> +
>  static int selinux_capget(struct task_struct *target, kernel_cap_t 
> *effective,
> kernel_cap_t *inheritable, kernel_cap_t *permitted)
>  {
> @@ -6085,6 +6099,7 @@ static struct security_hook_list selinux_hooks[] = {
>  
>   LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check),
>   LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme),
> + LSM_HOOK_INIT(forced_write, selinux_forced_write),
>   LSM_HOOK_INIT(capget, selinux_capget),
>   LSM_HOOK_INIT(capset, selinux_capset),
>   LSM_HOOK_INIT(capable, selinux_capable),
> diff --git a/security/selinux/include/security.h 
> b/security/selinux/include/security.h
> index 308a286c6cbe..87228f0ff09c 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -71,6 +71,7 @@ enum {
>   POLICYDB_CAPABILITY_OPENPERM,
>   POLICYDB_CAPABILITY_REDHAT1,
>   POLICYDB_CAPABILITY_ALWAYSNETWORK,
> + POLICYDB_CAPABILITY_FORCEDWRITE,
>   __POLICYDB_CAPABILITY_MAX
>  };
>  #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
> @@ -78,6 +79,7 @@ enum {
>  extern int selinux_policycap_netpeer;
>  extern int selinux_policycap_openperm;
>  extern int selinux_policycap_alwaysnetwork;
> +extern int selinux_policycap_forcedwrite;
>  
>  /*
>   * type_datum properties
> diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> index 72c145dd799f..a646cb801242 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -46,7 +46,8 @@ static char *policycap_names[] = {
>   "network_peer_controls",
>   "open_perms",
>   "redhat1",
> - "always_check_network"
> + "always_check_network",
> + "forced_write"

This is a nit, but can you provide a more descriptive capability name
that would be meaningful to policy writers and signifies that this
policy capability enables checking execmem in these situations?

>  };
>  
>  unsigned int selinux_checkreqprot = 
> CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index 082b20c78363..4017810030d6 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -73,6 +73,7 @@
>  int selinux_policycap_netpeer;
>  int selinux_policycap_openperm;
>  int selinux_policycap_alwaysnetwork;
> +int selinux_policycap_forcedwrite;
>  
>  static DEFINE_RWLOCK(policy_rwlock);
>  
> @@ -1990,6 +1991,8 @@ static void security_load_policycaps(void)
> POLICYDB_CAPABILITY_OPENPERM);
>   selinux_policycap_alwaysnetwork = ebitmap_get_bit(,
> 
> POLICYDB_CAPABILITY_ALWAYSNETWORK);
> + selinux_policycap_forcedwrite = ebitmap_get_bit(,
> +   
> POLICYDB_CAPABILITY_FORCEDWRITE);
>  }
>  
>  static int security_preserve_bools(struct policydb *p);
> 



Re: [PATCH v3 3/3] selinux: require EXECMEM for forced ptrace poke

2016-11-03 Thread Stephen Smalley
On 11/02/2016 11:04 PM, Jann Horn wrote:
> This restricts forced writes to private R+X mappings using the EXECMEM
> permission. To avoid a breaking change, a new policy capability needs to
> be enabled before the new restrictions take effect.
> 
> Unlike most other SELinux hooks, this one takes the subject credentials as
> an argument instead of looking up current_cred(). This is done because the
> security_forced_write() LSM hook can be invoked from within the write
> handler of /proc/$pid/mem, where current_cred() is pretty useless.
> 
> Changed in v3:
>  - minor: symmetric comment (Ingo Molnar)
>  - use helper struct (Ingo Molnar)
>  - add new policy capability for enabling forced write checks
>(Stephen Smalley)
> 
> Signed-off-by: Jann Horn 
> ---
>  security/selinux/hooks.c| 15 +++
>  security/selinux/include/security.h |  2 ++
>  security/selinux/selinuxfs.c|  3 ++-
>  security/selinux/ss/services.c  |  3 +++
>  4 files changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 09fd6108e421..cdd9c53db2ed 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2144,6 +2144,20 @@ static int selinux_ptrace_traceme(struct task_struct 
> *parent)
>   return task_has_perm(parent, current, PROCESS__PTRACE);
>  }
>  
> +static int selinux_forced_write(struct vm_area_struct *vma,
> + const struct gup_creds *creds)
> +{
> + /*
> +  * Permitting a write to readonly memory is fine - making the readonly
> +  * memory executable afterwards would require EXECMOD permission because
> +  * anon_vma would be non-NULL.
> +  */
> + if (!selinux_policycap_forcedwrite || (vma->vm_flags & VM_EXEC) == 0)
> + return 0;
> +
> + return cred_has_perm(creds->subject, creds->object, PROCESS__EXECMEM);
> +}
> +
>  static int selinux_capget(struct task_struct *target, kernel_cap_t 
> *effective,
> kernel_cap_t *inheritable, kernel_cap_t *permitted)
>  {
> @@ -6085,6 +6099,7 @@ static struct security_hook_list selinux_hooks[] = {
>  
>   LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check),
>   LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme),
> + LSM_HOOK_INIT(forced_write, selinux_forced_write),
>   LSM_HOOK_INIT(capget, selinux_capget),
>   LSM_HOOK_INIT(capset, selinux_capset),
>   LSM_HOOK_INIT(capable, selinux_capable),
> diff --git a/security/selinux/include/security.h 
> b/security/selinux/include/security.h
> index 308a286c6cbe..87228f0ff09c 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -71,6 +71,7 @@ enum {
>   POLICYDB_CAPABILITY_OPENPERM,
>   POLICYDB_CAPABILITY_REDHAT1,
>   POLICYDB_CAPABILITY_ALWAYSNETWORK,
> + POLICYDB_CAPABILITY_FORCEDWRITE,
>   __POLICYDB_CAPABILITY_MAX
>  };
>  #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
> @@ -78,6 +79,7 @@ enum {
>  extern int selinux_policycap_netpeer;
>  extern int selinux_policycap_openperm;
>  extern int selinux_policycap_alwaysnetwork;
> +extern int selinux_policycap_forcedwrite;
>  
>  /*
>   * type_datum properties
> diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> index 72c145dd799f..a646cb801242 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -46,7 +46,8 @@ static char *policycap_names[] = {
>   "network_peer_controls",
>   "open_perms",
>   "redhat1",
> - "always_check_network"
> + "always_check_network",
> + "forced_write"

This is a nit, but can you provide a more descriptive capability name
that would be meaningful to policy writers and signifies that this
policy capability enables checking execmem in these situations?

>  };
>  
>  unsigned int selinux_checkreqprot = 
> CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index 082b20c78363..4017810030d6 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -73,6 +73,7 @@
>  int selinux_policycap_netpeer;
>  int selinux_policycap_openperm;
>  int selinux_policycap_alwaysnetwork;
> +int selinux_policycap_forcedwrite;
>  
>  static DEFINE_RWLOCK(policy_rwlock);
>  
> @@ -1990,6 +1991,8 @@ static void security_load_policycaps(void)
> POLICYDB_CAPABILITY_OPENPERM);
>   selinux_policycap_alwaysnetwork = ebitmap_get_bit(,
> 
> POLICYDB_CAPABILITY_ALWAYSNETWORK);
> + selinux_policycap_forcedwrite = ebitmap_get_bit(,
> +   
> POLICYDB_CAPABILITY_FORCEDWRITE);
>  }
>  
>  static int security_preserve_bools(struct policydb *p);
> 



Re: selinux: should execmem disable shmat(..., SHM_EXEC)?

2016-10-27 Thread Stephen Smalley
On 10/26/2016 04:31 PM, Topi Miettinen wrote:
> Hi,
> 
> Maybe this is a stupid question and I didn't test this with SELinux, but
> it looks to me that SELinux execmem does not prevent process from
> getting writable and executable memory mappings by using shmat(...,
> SHM_EXEC). Shouldn't this be blocked by execmem, I suppose it is there
> to prevent this kind of memory access?
> 
> Here's a test program:
> #include 
> #include 
> 
> int main(void) {
> int shmid;
> char *execmem;
> void (*fn)(void);
> 
> shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0777);
> execmem = shmat(shmid, 0, SHM_EXEC);
> shmctl(shmid, IPC_RMID, 0);
> *execmem = 0xc3; // retq
> fn = (void (*)(void))execmem;
> fn();
> shmdt(execmem);
> }
> 
> -Topi
> 

The test program fails with a seg fault and a SELinux avc denial for
execmem permission when run in a domain that lacks execmem permission.
Thanks though for the test; I'll add it to the selinux testsuite to
ensure we don't regress in this area.



Re: selinux: should execmem disable shmat(..., SHM_EXEC)?

2016-10-27 Thread Stephen Smalley
On 10/26/2016 04:31 PM, Topi Miettinen wrote:
> Hi,
> 
> Maybe this is a stupid question and I didn't test this with SELinux, but
> it looks to me that SELinux execmem does not prevent process from
> getting writable and executable memory mappings by using shmat(...,
> SHM_EXEC). Shouldn't this be blocked by execmem, I suppose it is there
> to prevent this kind of memory access?
> 
> Here's a test program:
> #include 
> #include 
> 
> int main(void) {
> int shmid;
> char *execmem;
> void (*fn)(void);
> 
> shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0777);
> execmem = shmat(shmid, 0, SHM_EXEC);
> shmctl(shmid, IPC_RMID, 0);
> *execmem = 0xc3; // retq
> fn = (void (*)(void))execmem;
> fn();
> shmdt(execmem);
> }
> 
> -Topi
> 

The test program fails with a seg fault and a SELinux avc denial for
execmem permission when run in a domain that lacks execmem permission.
Thanks though for the test; I'll add it to the selinux testsuite to
ensure we don't regress in this area.



Re: [PATCH v2 3/3] selinux: require EXECMEM for forced ptrace poke

2016-09-29 Thread Stephen Smalley
On 09/28/2016 06:54 PM, Jann Horn wrote:
> This is a breaking change for SELinux users that restrict EXECMEM: It might
> break gdb if gdb is executed in a domain that does not have EXECMEM
> privilege over the debuggee domain.

Since this would break compatibility with existing SELinux policies, you
have to wrap it with a conditional on a policy capability that you can
then enable in newer policies.  See commit
2be4d74f2fd45460d70d4fe65cc1972ef45bf849 for an example.  This requires
a corresponding update to libsepol, and then adding the new policy
capability to your policy (in the policy_capabilities file).

> 
> Unlike most other SELinux hooks, this one takes the subject credentials as
> an argument instead of looking up current_cred(). This is done because the
> security_forced_write() LSM hook can be invoked from within the write
> handler of /proc/$pid/mem, where current_cred() is pretty useless.
> 
> Signed-off-by: Jann Horn 
> Reviewed-by: Janis Danisevskis 
> ---
>  security/selinux/hooks.c | 15 +++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 13185a6..e36682a 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2149,6 +2149,20 @@ static int selinux_ptrace_traceme(struct task_struct 
> *parent)
>   return task_has_perm(parent, current, PROCESS__PTRACE);
>  }
>  
> +static int selinux_forced_write(struct vm_area_struct *vma,
> + const struct cred *subject_cred,
> + const struct cred *object_cred)
> +{
> + /* Permitting a write to readonly memory is fine - making the readonly
> +  * memory executable afterwards would require EXECMOD permission because
> +  * anon_vma would be non-NULL.
> +  */
> + if ((vma->vm_flags & VM_EXEC) == 0)
> + return 0;
> +
> + return cred_has_perm(subject_cred, object_cred, PROCESS__EXECMEM);
> +}
> +
>  static int selinux_capget(struct task_struct *target, kernel_cap_t 
> *effective,
> kernel_cap_t *inheritable, kernel_cap_t *permitted)
>  {
> @@ -6033,6 +6047,7 @@ static struct security_hook_list selinux_hooks[] = {
>  
>   LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check),
>   LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme),
> + LSM_HOOK_INIT(forced_write, selinux_forced_write),
>   LSM_HOOK_INIT(capget, selinux_capget),
>   LSM_HOOK_INIT(capset, selinux_capset),
>   LSM_HOOK_INIT(capable, selinux_capable),
> 



Re: [PATCH v2 3/3] selinux: require EXECMEM for forced ptrace poke

2016-09-29 Thread Stephen Smalley
On 09/28/2016 06:54 PM, Jann Horn wrote:
> This is a breaking change for SELinux users that restrict EXECMEM: It might
> break gdb if gdb is executed in a domain that does not have EXECMEM
> privilege over the debuggee domain.

Since this would break compatibility with existing SELinux policies, you
have to wrap it with a conditional on a policy capability that you can
then enable in newer policies.  See commit
2be4d74f2fd45460d70d4fe65cc1972ef45bf849 for an example.  This requires
a corresponding update to libsepol, and then adding the new policy
capability to your policy (in the policy_capabilities file).

> 
> Unlike most other SELinux hooks, this one takes the subject credentials as
> an argument instead of looking up current_cred(). This is done because the
> security_forced_write() LSM hook can be invoked from within the write
> handler of /proc/$pid/mem, where current_cred() is pretty useless.
> 
> Signed-off-by: Jann Horn 
> Reviewed-by: Janis Danisevskis 
> ---
>  security/selinux/hooks.c | 15 +++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 13185a6..e36682a 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2149,6 +2149,20 @@ static int selinux_ptrace_traceme(struct task_struct 
> *parent)
>   return task_has_perm(parent, current, PROCESS__PTRACE);
>  }
>  
> +static int selinux_forced_write(struct vm_area_struct *vma,
> + const struct cred *subject_cred,
> + const struct cred *object_cred)
> +{
> + /* Permitting a write to readonly memory is fine - making the readonly
> +  * memory executable afterwards would require EXECMOD permission because
> +  * anon_vma would be non-NULL.
> +  */
> + if ((vma->vm_flags & VM_EXEC) == 0)
> + return 0;
> +
> + return cred_has_perm(subject_cred, object_cred, PROCESS__EXECMEM);
> +}
> +
>  static int selinux_capget(struct task_struct *target, kernel_cap_t 
> *effective,
> kernel_cap_t *inheritable, kernel_cap_t *permitted)
>  {
> @@ -6033,6 +6047,7 @@ static struct security_hook_list selinux_hooks[] = {
>  
>   LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check),
>   LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme),
> + LSM_HOOK_INIT(forced_write, selinux_forced_write),
>   LSM_HOOK_INIT(capget, selinux_capget),
>   LSM_HOOK_INIT(capset, selinux_capset),
>   LSM_HOOK_INIT(capable, selinux_capable),
> 



Re: [PATCH 1/9] security, overlayfs: provide copy up security hook for unioned files

2016-07-14 Thread Stephen Smalley
On 07/13/2016 11:13 AM, Vivek Goyal wrote:
> Updated patch as per Stephen's feedback.
> 
> Provide a security hook to label new file correctly when a file is copied
> up from lower layer to upper layer of a overlay/union mount.
> 
> This hook can prepare a new set of creds which are suitable for new file
> creation during copy up. Caller will use new creds to create file and then
> revert back to old creds and release new creds.
> 
> Signed-off-by: Vivek Goyal <vgo...@redhat.com>

Acked-by: Stephen Smalley <s...@tycho.nsa.gov>

> ---
>  fs/overlayfs/copy_up.c| 15 +++
>  include/linux/lsm_hooks.h | 11 +++
>  include/linux/security.h  |  6 ++
>  security/security.c   |  8 
>  4 files changed, 40 insertions(+)
> 
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index 80aa6f1..e5e3557 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -246,6 +246,8 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   struct dentry *upper = NULL;
>   umode_t mode = stat->mode;
>   int err;
> + const struct cred *old_creds = NULL;
> + struct cred *new_creds = NULL;
>  
>   newdentry = ovl_lookup_temp(workdir, dentry);
>   err = PTR_ERR(newdentry);
> @@ -258,10 +260,23 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   if (IS_ERR(upper))
>   goto out1;
>  
> + err = security_inode_copy_up(dentry, _creds);
> + if (err < 0)
> + goto out2;
> +
> + if (new_creds)
> + old_creds = override_creds(new_creds);
> +
>   /* Can't properly set mode on creation because of the umask */
>   stat->mode &= S_IFMT;
>   err = ovl_create_real(wdir, newdentry, stat, link, NULL, true);
>   stat->mode = mode;
> +
> + if (new_creds) {
> + revert_creds(old_creds);
> + put_cred(new_creds);
> + }
> +
>   if (err)
>   goto out2;
>  
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7ae3976..c1f95be 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -401,6 +401,15 @@
>   *   @inode contains a pointer to the inode.
>   *   @secid contains a pointer to the location where result will be saved.
>   *   In case of failure, @secid will be set to zero.
> + * @inode_copy_up:
> + *   A file is about to be copied up from lower layer to upper layer of
> + *   overlay filesystem. Security module can prepare a set of new creds
> + *   and modify as need be and return new creds. Caller will switch to
> + *   new creds temporarily to create new file and release newly allocated
> + *   creds.
> + *   @src indicates the union dentry of file that is being copied up.
> + *   @new pointer to pointer to return newly allocated creds.
> + *   Returns 0 on success or a negative error code on error.
>   *
>   * Security hooks for file operations
>   *
> @@ -1425,6 +1434,7 @@ union security_list_options {
>   int (*inode_listsecurity)(struct inode *inode, char *buffer,
>   size_t buffer_size);
>   void (*inode_getsecid)(struct inode *inode, u32 *secid);
> + int (*inode_copy_up) (struct dentry *src, struct cred **new);
>  
>   int (*file_permission)(struct file *file, int mask);
>   int (*file_alloc_security)(struct file *file);
> @@ -1696,6 +1706,7 @@ struct security_hook_heads {
>   struct list_head inode_setsecurity;
>   struct list_head inode_listsecurity;
>   struct list_head inode_getsecid;
> + struct list_head inode_copy_up;
>   struct list_head file_permission;
>   struct list_head file_alloc_security;
>   struct list_head file_free_security;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 14df373..c976d79 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -282,6 +282,7 @@ int security_inode_getsecurity(struct inode *inode, const 
> char *name, void **buf
>  int security_inode_setsecurity(struct inode *inode, const char *name, const 
> void *value, size_t size, int flags);
>  int security_inode_listsecurity(struct inode *inode, char *buffer, size_t 
> buffer_size);
>  void security_inode_getsecid(struct inode *inode, u32 *secid);
> +int security_inode_copy_up(struct dentry *src, struct cred **new);
>  int security_file_permission(struct file *file, int mask);
>  int security_file_alloc(struct file *file);
>  void security_file_free(struct file *file);
> @@ -758,6 +759,11 @@ static inline void security_inode_getsecid(struct inode 
> *inode, u32 *se

Re: [PATCH 1/9] security, overlayfs: provide copy up security hook for unioned files

2016-07-14 Thread Stephen Smalley
On 07/13/2016 11:13 AM, Vivek Goyal wrote:
> Updated patch as per Stephen's feedback.
> 
> Provide a security hook to label new file correctly when a file is copied
> up from lower layer to upper layer of a overlay/union mount.
> 
> This hook can prepare a new set of creds which are suitable for new file
> creation during copy up. Caller will use new creds to create file and then
> revert back to old creds and release new creds.
> 
> Signed-off-by: Vivek Goyal 

Acked-by: Stephen Smalley 

> ---
>  fs/overlayfs/copy_up.c| 15 +++
>  include/linux/lsm_hooks.h | 11 +++
>  include/linux/security.h  |  6 ++
>  security/security.c   |  8 
>  4 files changed, 40 insertions(+)
> 
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index 80aa6f1..e5e3557 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -246,6 +246,8 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   struct dentry *upper = NULL;
>   umode_t mode = stat->mode;
>   int err;
> + const struct cred *old_creds = NULL;
> + struct cred *new_creds = NULL;
>  
>   newdentry = ovl_lookup_temp(workdir, dentry);
>   err = PTR_ERR(newdentry);
> @@ -258,10 +260,23 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   if (IS_ERR(upper))
>   goto out1;
>  
> + err = security_inode_copy_up(dentry, _creds);
> + if (err < 0)
> + goto out2;
> +
> + if (new_creds)
> + old_creds = override_creds(new_creds);
> +
>   /* Can't properly set mode on creation because of the umask */
>   stat->mode &= S_IFMT;
>   err = ovl_create_real(wdir, newdentry, stat, link, NULL, true);
>   stat->mode = mode;
> +
> + if (new_creds) {
> + revert_creds(old_creds);
> + put_cred(new_creds);
> + }
> +
>   if (err)
>   goto out2;
>  
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7ae3976..c1f95be 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -401,6 +401,15 @@
>   *   @inode contains a pointer to the inode.
>   *   @secid contains a pointer to the location where result will be saved.
>   *   In case of failure, @secid will be set to zero.
> + * @inode_copy_up:
> + *   A file is about to be copied up from lower layer to upper layer of
> + *   overlay filesystem. Security module can prepare a set of new creds
> + *   and modify as need be and return new creds. Caller will switch to
> + *   new creds temporarily to create new file and release newly allocated
> + *   creds.
> + *   @src indicates the union dentry of file that is being copied up.
> + *   @new pointer to pointer to return newly allocated creds.
> + *   Returns 0 on success or a negative error code on error.
>   *
>   * Security hooks for file operations
>   *
> @@ -1425,6 +1434,7 @@ union security_list_options {
>   int (*inode_listsecurity)(struct inode *inode, char *buffer,
>   size_t buffer_size);
>   void (*inode_getsecid)(struct inode *inode, u32 *secid);
> + int (*inode_copy_up) (struct dentry *src, struct cred **new);
>  
>   int (*file_permission)(struct file *file, int mask);
>   int (*file_alloc_security)(struct file *file);
> @@ -1696,6 +1706,7 @@ struct security_hook_heads {
>   struct list_head inode_setsecurity;
>   struct list_head inode_listsecurity;
>   struct list_head inode_getsecid;
> + struct list_head inode_copy_up;
>   struct list_head file_permission;
>   struct list_head file_alloc_security;
>   struct list_head file_free_security;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 14df373..c976d79 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -282,6 +282,7 @@ int security_inode_getsecurity(struct inode *inode, const 
> char *name, void **buf
>  int security_inode_setsecurity(struct inode *inode, const char *name, const 
> void *value, size_t size, int flags);
>  int security_inode_listsecurity(struct inode *inode, char *buffer, size_t 
> buffer_size);
>  void security_inode_getsecid(struct inode *inode, u32 *secid);
> +int security_inode_copy_up(struct dentry *src, struct cred **new);
>  int security_file_permission(struct file *file, int mask);
>  int security_file_alloc(struct file *file);
>  void security_file_free(struct file *file);
> @@ -758,6 +759,11 @@ static inline void security_inode_getsecid(struct inode 
> *inode, u32 *secid)
>   *secid = 0;
>  }
>  
> +st

Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files

2016-07-14 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> During a new file creation we need to make sure new file is created with the
> right label. New file is created in upper/ so effectively file should get
> label as if task had created file in upper/.
> 
> We switched to mounter's creds for actual file creation. Also if there is a
> whiteout present, then file will be created in work/ dir first and then
> renamed in upper. In none of the cases file will be labeled as we want it to
> be.
> 
> This patch introduces a new hook dentry_create_files_as(), which determines
> the label/context dentry will get if it had been created by task in upper
> and modify passed set of creds appropriately. Caller makes use of these new
> creds for file creation.
> 
> Signed-off-by: Vivek Goyal <vgo...@redhat.com>

Acked-by: Stephen Smalley <s...@tycho.nsa.gov>

> ---
>  fs/overlayfs/dir.c| 10 ++
>  include/linux/lsm_hooks.h | 15 +++
>  include/linux/security.h  | 12 
>  security/security.c   | 11 +++
>  4 files changed, 48 insertions(+)
> 
> diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
> index 4cdeb74..f94872f 100644
> --- a/fs/overlayfs/dir.c
> +++ b/fs/overlayfs/dir.c
> @@ -433,6 +433,15 @@ static int ovl_create_or_link(struct dentry *dentry, int 
> mode, dev_t rdev,
>   if (override_cred) {
>   override_cred->fsuid = inode->i_uid;
>   override_cred->fsgid = inode->i_gid;
> + if (!hardlink) {
> + err = security_dentry_create_files_as(dentry,
> + mode, >d_name, old_cred,
> + override_cred);
> + if (err) {
> + put_cred(override_cred);
> + goto out_revert_creds;
> + }
> + }
>   put_cred(override_creds(override_cred));
>   put_cred(override_cred);
>  
> @@ -443,6 +452,7 @@ static int ovl_create_or_link(struct dentry *dentry, int 
> mode, dev_t rdev,
>   err = ovl_create_over_whiteout(dentry, inode, ,
>   link, hardlink);
>   }
> +out_revert_creds:
>   revert_creds(old_cred);
>   if (!err) {
>   struct inode *realinode = d_inode(ovl_dentry_upper(dentry));
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 84caead..95745fe 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -151,6 +151,16 @@
>   *   @name name of the last path component used to create file
>   *   @ctx pointer to place the pointer to the resulting context in.
>   *   @ctxlen point to place the length of the resulting context.
> + * @dentry_create_files_as:
> + *   Compute a context for a dentry as the inode is not yet available
> + *   and set that context in passed in creds so that new files are
> + *   created using that context. Context is calculated using the
> + *   passed in creds and not the creds of the caller.
> + *   @dentry dentry to use in calculating the context.
> + *   @mode mode used to determine resource type.
> + *   @name name of the last path component used to create file
> + *   @old creds which should be used for context calculation
> + *   @new creds to modify
>   *
>   *
>   * Security hooks for inode operations.
> @@ -1375,6 +1385,10 @@ union security_list_options {
>   int (*dentry_init_security)(struct dentry *dentry, int mode,
>   struct qstr *name, void **ctx,
>   u32 *ctxlen);
> + int (*dentry_create_files_as)(struct dentry *dentry, int mode,
> + struct qstr *name,
> + const struct cred *old,
> + struct cred *new);
>  
>  
>  #ifdef CONFIG_SECURITY_PATH
> @@ -1675,6 +1689,7 @@ struct security_hook_heads {
>   struct list_head sb_clone_mnt_opts;
>   struct list_head sb_parse_opts_str;
>   struct list_head dentry_init_security;
> + struct list_head dentry_create_files_as;
>  #ifdef CONFIG_SECURITY_PATH
>   struct list_head path_unlink;
>   struct list_head path_mkdir;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 4a3b8bc..1eb03dc 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -242,6 +242,10 @@ int security_sb_parse_opts_str(char *options, struct 
> security_mnt_opts *opts);
>  int security_dentry_init_security(struct dentry *dentry, int mode,
>   stru

Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files

2016-07-14 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> During a new file creation we need to make sure new file is created with the
> right label. New file is created in upper/ so effectively file should get
> label as if task had created file in upper/.
> 
> We switched to mounter's creds for actual file creation. Also if there is a
> whiteout present, then file will be created in work/ dir first and then
> renamed in upper. In none of the cases file will be labeled as we want it to
> be.
> 
> This patch introduces a new hook dentry_create_files_as(), which determines
> the label/context dentry will get if it had been created by task in upper
> and modify passed set of creds appropriately. Caller makes use of these new
> creds for file creation.
> 
> Signed-off-by: Vivek Goyal 

Acked-by: Stephen Smalley 

> ---
>  fs/overlayfs/dir.c| 10 ++
>  include/linux/lsm_hooks.h | 15 +++
>  include/linux/security.h  | 12 
>  security/security.c   | 11 +++
>  4 files changed, 48 insertions(+)
> 
> diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
> index 4cdeb74..f94872f 100644
> --- a/fs/overlayfs/dir.c
> +++ b/fs/overlayfs/dir.c
> @@ -433,6 +433,15 @@ static int ovl_create_or_link(struct dentry *dentry, int 
> mode, dev_t rdev,
>   if (override_cred) {
>   override_cred->fsuid = inode->i_uid;
>   override_cred->fsgid = inode->i_gid;
> + if (!hardlink) {
> + err = security_dentry_create_files_as(dentry,
> + mode, >d_name, old_cred,
> + override_cred);
> + if (err) {
> + put_cred(override_cred);
> + goto out_revert_creds;
> + }
> + }
>   put_cred(override_creds(override_cred));
>   put_cred(override_cred);
>  
> @@ -443,6 +452,7 @@ static int ovl_create_or_link(struct dentry *dentry, int 
> mode, dev_t rdev,
>   err = ovl_create_over_whiteout(dentry, inode, ,
>   link, hardlink);
>   }
> +out_revert_creds:
>   revert_creds(old_cred);
>   if (!err) {
>   struct inode *realinode = d_inode(ovl_dentry_upper(dentry));
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 84caead..95745fe 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -151,6 +151,16 @@
>   *   @name name of the last path component used to create file
>   *   @ctx pointer to place the pointer to the resulting context in.
>   *   @ctxlen point to place the length of the resulting context.
> + * @dentry_create_files_as:
> + *   Compute a context for a dentry as the inode is not yet available
> + *   and set that context in passed in creds so that new files are
> + *   created using that context. Context is calculated using the
> + *   passed in creds and not the creds of the caller.
> + *   @dentry dentry to use in calculating the context.
> + *   @mode mode used to determine resource type.
> + *   @name name of the last path component used to create file
> + *   @old creds which should be used for context calculation
> + *   @new creds to modify
>   *
>   *
>   * Security hooks for inode operations.
> @@ -1375,6 +1385,10 @@ union security_list_options {
>   int (*dentry_init_security)(struct dentry *dentry, int mode,
>   struct qstr *name, void **ctx,
>   u32 *ctxlen);
> + int (*dentry_create_files_as)(struct dentry *dentry, int mode,
> + struct qstr *name,
> + const struct cred *old,
> + struct cred *new);
>  
>  
>  #ifdef CONFIG_SECURITY_PATH
> @@ -1675,6 +1689,7 @@ struct security_hook_heads {
>   struct list_head sb_clone_mnt_opts;
>   struct list_head sb_parse_opts_str;
>   struct list_head dentry_init_security;
> + struct list_head dentry_create_files_as;
>  #ifdef CONFIG_SECURITY_PATH
>   struct list_head path_unlink;
>   struct list_head path_mkdir;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 4a3b8bc..1eb03dc 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -242,6 +242,10 @@ int security_sb_parse_opts_str(char *options, struct 
> security_mnt_opts *opts);
>  int security_dentry_init_security(struct dentry *dentry, int mode,
>   struct qstr *name, void **ctx,
>

Re: [PATCH 3/9] security,overlayfs: Provide security hook for copy up of xattrs for overlay file

2016-07-14 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> Provide a security hook which is called when xattrs of a file are being
> copied up. This hook is called once for each xattr and LSM can return
> 0 if the security module wants the xattr to be copied up, 1 if the
> security module wants the xattr to be discarded on the copy, -EOPNOTSUPP
> if the security module does not handle/manage the xattr, or a -errno
> upon an error.
> 
> Signed-off-by: David Howells <dhowe...@redhat.com>
> Signed-off-by: Vivek Goyal <vgo...@redhat.com>

Acked-by: Stephen Smalley <s...@tycho.nsa.gov>

> ---
>  fs/overlayfs/copy_up.c|  7 +++
>  include/linux/lsm_hooks.h | 10 ++
>  include/linux/security.h  |  6 ++
>  security/security.c   |  8 
>  4 files changed, 31 insertions(+)
> 
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index 8ebea18..68cefb2 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -103,6 +103,13 @@ retry:
>   goto retry;
>   }
>  
> + error = security_inode_copy_up_xattr(name);
> + if (error < 0 && error != -EOPNOTSUPP)
> + break;
> + if (error == 1) {
> + error = 0;
> + continue; /* Discard */
> + }
>   error = vfs_setxattr(new, name, value, size, 0);
>   if (error)
>   break;
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index c1f95be..84caead 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -410,6 +410,14 @@
>   *   @src indicates the union dentry of file that is being copied up.
>   *   @new pointer to pointer to return newly allocated creds.
>   *   Returns 0 on success or a negative error code on error.
> + * @inode_copy_up_xattr:
> + *   Filter the xattrs being copied up when a unioned file is copied
> + *   up from a lower layer to the union/overlay layer.
> + *   @name indicates the name of the xattr.
> + *   Returns 0 to accept the xattr, 1 to discard the xattr, -EOPNOTSUPP if
> + *   security module does not know about attribute or a negative error code
> + *   to abort the copy up. Note that the caller is responsible for reading
> + *   and writing the xattrs as this hook is merely a filter.
>   *
>   * Security hooks for file operations
>   *
> @@ -1435,6 +1443,7 @@ union security_list_options {
>   size_t buffer_size);
>   void (*inode_getsecid)(struct inode *inode, u32 *secid);
>   int (*inode_copy_up) (struct dentry *src, struct cred **new);
> + int (*inode_copy_up_xattr) (const char *name);
>  
>   int (*file_permission)(struct file *file, int mask);
>   int (*file_alloc_security)(struct file *file);
> @@ -1707,6 +1716,7 @@ struct security_hook_heads {
>   struct list_head inode_listsecurity;
>   struct list_head inode_getsecid;
>   struct list_head inode_copy_up;
> + struct list_head inode_copy_up_xattr;
>   struct list_head file_permission;
>   struct list_head file_alloc_security;
>   struct list_head file_free_security;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index c976d79..4a3b8bc 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -283,6 +283,7 @@ int security_inode_setsecurity(struct inode *inode, const 
> char *name, const void
>  int security_inode_listsecurity(struct inode *inode, char *buffer, size_t 
> buffer_size);
>  void security_inode_getsecid(struct inode *inode, u32 *secid);
>  int security_inode_copy_up(struct dentry *src, struct cred **new);
> +int security_inode_copy_up_xattr(const char *name);
>  int security_file_permission(struct file *file, int mask);
>  int security_file_alloc(struct file *file);
>  void security_file_free(struct file *file);
> @@ -764,6 +765,11 @@ static inline int security_inode_copy_up(struct dentry 
> *src, struct cred **new)
>   return 0;
>  }
>  
> +static inline int security_inode_copy_up_xattr(const char *name)
> +{
> + return -EOPNOTSUPP;
> +}
> +
>  static inline int security_file_permission(struct file *file, int mask)
>  {
>   return 0;
> diff --git a/security/security.c b/security/security.c
> index 3d142aa..3321e31 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -733,6 +733,12 @@ int security_inode_copy_up(struct dentry *src, struct 
> cred **new)
>  }
>  EXPORT_SYMBOL(security_inode_copy_up);
>  
> +int security_inode_copy_up_xattr(const char *name)
> +{
> + return call_int_hook(inode_copy_up_xattr, -EOPN

Re: [PATCH 3/9] security,overlayfs: Provide security hook for copy up of xattrs for overlay file

2016-07-14 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> Provide a security hook which is called when xattrs of a file are being
> copied up. This hook is called once for each xattr and LSM can return
> 0 if the security module wants the xattr to be copied up, 1 if the
> security module wants the xattr to be discarded on the copy, -EOPNOTSUPP
> if the security module does not handle/manage the xattr, or a -errno
> upon an error.
> 
> Signed-off-by: David Howells 
> Signed-off-by: Vivek Goyal 

Acked-by: Stephen Smalley 

> ---
>  fs/overlayfs/copy_up.c|  7 +++
>  include/linux/lsm_hooks.h | 10 ++
>  include/linux/security.h  |  6 ++
>  security/security.c   |  8 
>  4 files changed, 31 insertions(+)
> 
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index 8ebea18..68cefb2 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -103,6 +103,13 @@ retry:
>   goto retry;
>   }
>  
> + error = security_inode_copy_up_xattr(name);
> + if (error < 0 && error != -EOPNOTSUPP)
> + break;
> + if (error == 1) {
> + error = 0;
> + continue; /* Discard */
> + }
>   error = vfs_setxattr(new, name, value, size, 0);
>   if (error)
>   break;
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index c1f95be..84caead 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -410,6 +410,14 @@
>   *   @src indicates the union dentry of file that is being copied up.
>   *   @new pointer to pointer to return newly allocated creds.
>   *   Returns 0 on success or a negative error code on error.
> + * @inode_copy_up_xattr:
> + *   Filter the xattrs being copied up when a unioned file is copied
> + *   up from a lower layer to the union/overlay layer.
> + *   @name indicates the name of the xattr.
> + *   Returns 0 to accept the xattr, 1 to discard the xattr, -EOPNOTSUPP if
> + *   security module does not know about attribute or a negative error code
> + *   to abort the copy up. Note that the caller is responsible for reading
> + *   and writing the xattrs as this hook is merely a filter.
>   *
>   * Security hooks for file operations
>   *
> @@ -1435,6 +1443,7 @@ union security_list_options {
>   size_t buffer_size);
>   void (*inode_getsecid)(struct inode *inode, u32 *secid);
>   int (*inode_copy_up) (struct dentry *src, struct cred **new);
> + int (*inode_copy_up_xattr) (const char *name);
>  
>   int (*file_permission)(struct file *file, int mask);
>   int (*file_alloc_security)(struct file *file);
> @@ -1707,6 +1716,7 @@ struct security_hook_heads {
>   struct list_head inode_listsecurity;
>   struct list_head inode_getsecid;
>   struct list_head inode_copy_up;
> + struct list_head inode_copy_up_xattr;
>   struct list_head file_permission;
>   struct list_head file_alloc_security;
>   struct list_head file_free_security;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index c976d79..4a3b8bc 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -283,6 +283,7 @@ int security_inode_setsecurity(struct inode *inode, const 
> char *name, const void
>  int security_inode_listsecurity(struct inode *inode, char *buffer, size_t 
> buffer_size);
>  void security_inode_getsecid(struct inode *inode, u32 *secid);
>  int security_inode_copy_up(struct dentry *src, struct cred **new);
> +int security_inode_copy_up_xattr(const char *name);
>  int security_file_permission(struct file *file, int mask);
>  int security_file_alloc(struct file *file);
>  void security_file_free(struct file *file);
> @@ -764,6 +765,11 @@ static inline int security_inode_copy_up(struct dentry 
> *src, struct cred **new)
>   return 0;
>  }
>  
> +static inline int security_inode_copy_up_xattr(const char *name)
> +{
> + return -EOPNOTSUPP;
> +}
> +
>  static inline int security_file_permission(struct file *file, int mask)
>  {
>   return 0;
> diff --git a/security/security.c b/security/security.c
> index 3d142aa..3321e31 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -733,6 +733,12 @@ int security_inode_copy_up(struct dentry *src, struct 
> cred **new)
>  }
>  EXPORT_SYMBOL(security_inode_copy_up);
>  
> +int security_inode_copy_up_xattr(const char *name)
> +{
> + return call_int_hook(inode_copy_up_xattr, -EOPNOTSUPP, name);
> +}
> +EXPORT_SYMBOL(security_inode_copy_up_xattr);
> +
&g

Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:57 AM, Stephen Smalley wrote:
> On 07/13/2016 10:44 AM, Vivek Goyal wrote:
>> During a new file creation we need to make sure new file is created with the
>> right label. New file is created in upper/ so effectively file should get
>> label as if task had created file in upper/.
>>
>> We switched to mounter's creds for actual file creation. Also if there is a
>> whiteout present, then file will be created in work/ dir first and then
>> renamed in upper. In none of the cases file will be labeled as we want it to
>> be.
>>
>> This patch introduces a new hook dentry_create_files_as(), which determines
>> the label/context dentry will get if it had been created by task in upper
>> and modify passed set of creds appropriately. Caller makes use of these new
>> creds for file creation.
>>
>> Signed-off-by: Vivek Goyal <vgo...@redhat.com>
>> ---
>>  fs/overlayfs/dir.c| 10 ++
>>  include/linux/lsm_hooks.h | 15 +++
>>  include/linux/security.h  | 12 
>>  security/security.c   | 11 +++
>>  4 files changed, 48 insertions(+)
>>
>> diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
>> index 4cdeb74..f94872f 100644
>> --- a/fs/overlayfs/dir.c
>> +++ b/fs/overlayfs/dir.c
>> @@ -433,6 +433,15 @@ static int ovl_create_or_link(struct dentry *dentry, 
>> int mode, dev_t rdev,
>>  if (override_cred) {
>>  override_cred->fsuid = inode->i_uid;
>>  override_cred->fsgid = inode->i_gid;
>> +if (!hardlink) {
>> +err = security_dentry_create_files_as(dentry,
>> +mode, >d_name, old_cred,
>> +override_cred);
>> +if (err) {
>> +put_cred(override_cred);
> 
> Same principle here; on error the caller should do nothing with
> override_cred.

Sorry, never mind - not allocated by the hook so properly handled by the
caller.

> 
>> +goto out_revert_creds;
>> +}
>> +}
>>  put_cred(override_creds(override_cred));
>>  put_cred(override_cred);
>>  
>> @@ -443,6 +452,7 @@ static int ovl_create_or_link(struct dentry *dentry, int 
>> mode, dev_t rdev,
>>  err = ovl_create_over_whiteout(dentry, inode, ,
>>  link, hardlink);
>>  }
>> +out_revert_creds:
>>  revert_creds(old_cred);
>>  if (!err) {
>>  struct inode *realinode = d_inode(ovl_dentry_upper(dentry));
>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
>> index 84caead..95745fe 100644
>> --- a/include/linux/lsm_hooks.h
>> +++ b/include/linux/lsm_hooks.h
>> @@ -151,6 +151,16 @@
>>   *  @name name of the last path component used to create file
>>   *  @ctx pointer to place the pointer to the resulting context in.
>>   *  @ctxlen point to place the length of the resulting context.
>> + * @dentry_create_files_as:
>> + *  Compute a context for a dentry as the inode is not yet available
>> + *  and set that context in passed in creds so that new files are
>> + *  created using that context. Context is calculated using the
>> + *  passed in creds and not the creds of the caller.
>> + *  @dentry dentry to use in calculating the context.
>> + *  @mode mode used to determine resource type.
>> + *  @name name of the last path component used to create file
>> + *  @old creds which should be used for context calculation
>> + *  @new creds to modify
>>   *
>>   *
>>   * Security hooks for inode operations.
>> @@ -1375,6 +1385,10 @@ union security_list_options {
>>  int (*dentry_init_security)(struct dentry *dentry, int mode,
>>  struct qstr *name, void **ctx,
>>  u32 *ctxlen);
>> +int (*dentry_create_files_as)(struct dentry *dentry, int mode,
>> +struct qstr *name,
>> +const struct cred *old,
>> +struct cred *new);
>>  
>>  
>>  #ifdef CONFIG_SECURITY_PATH
>> @@ -1675,6 +1689,7 @@ struct security_hook_heads {
>>  struct list_head sb_clone_mnt_opts;
>>  struct list_head sb_parse_opts_str;
>>  struct list_head dentry_init_security;
>> +struct list_head dentry_create_files_as;
>>  #ifdef

Re: [PATCH 5/9] selinux: Pass security pointer to determine_inode_label()

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> Right now selinux_determine_inode_label() works on security pointer of
> current task. Soon I need this to work on a security pointer retrieved
> from a set of creds. So start passing in a pointer and caller can decide
> where to fetch security pointer from.
> 
> Signed-off-by: Vivek Goyal <vgo...@redhat.com>

Acked-by: Stephen Smalley <s...@tycho.nsa.gov>

> ---
>  security/selinux/hooks.c | 19 ++-
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 4fda548..ae11fd9 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -1785,13 +1785,13 @@ out:
>  /*
>   * Determine the label for an inode that might be unioned.
>   */
> -static int selinux_determine_inode_label(struct inode *dir,
> -  const struct qstr *name,
> -  u16 tclass,
> -  u32 *_new_isid)
> +static int
> +selinux_determine_inode_label(const struct task_security_struct *tsec,
> +  struct inode *dir,
> +  const struct qstr *name, u16 tclass,
> +  u32 *_new_isid)
>  {
>   const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
> - const struct task_security_struct *tsec = current_security();
>  
>   if ((sbsec->flags & SE_SBINITIALIZED) &&
>   (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
> @@ -1834,8 +1834,8 @@ static int may_create(struct inode *dir,
>   if (rc)
>   return rc;
>  
> - rc = selinux_determine_inode_label(dir, >d_name, tclass,
> -);
> + rc = selinux_determine_inode_label(current_security(), dir,
> +>d_name, tclass, );
>   if (rc)
>   return rc;
>  
> @@ -2815,7 +2815,8 @@ static int selinux_dentry_init_security(struct dentry 
> *dentry, int mode,
>   u32 newsid;
>   int rc;
>  
> - rc = selinux_determine_inode_label(d_inode(dentry->d_parent), name,
> + rc = selinux_determine_inode_label(current_security(),
> +d_inode(dentry->d_parent), name,
>  inode_mode_to_security_class(mode),
>  );
>   if (rc)
> @@ -2840,7 +2841,7 @@ static int selinux_inode_init_security(struct inode 
> *inode, struct inode *dir,
>   sid = tsec->sid;
>   newsid = tsec->create_sid;
>  
> - rc = selinux_determine_inode_label(
> + rc = selinux_determine_inode_label(current_security(),
>   dir, qstr,
>   inode_mode_to_security_class(inode->i_mode),
>   );
> 



Re: [PATCH 7/9] selinux: Implement dentry_create_files_as() hook

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> Calculate what would be the label of newly created file and set that secid
> in the passed creds.
> 
> Context of the task which is actually creating file is retrieved from
> set of creds passed in. (old->security).
> 
> Signed-off-by: Vivek Goyal <vgo...@redhat.com>

Acked-by: Stephen Smalley <s...@tycho.nsa.gov>

> ---
>  security/selinux/hooks.c | 22 ++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index ae11fd9..77eb5a8 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2825,6 +2825,27 @@ static int selinux_dentry_init_security(struct dentry 
> *dentry, int mode,
>   return security_sid_to_context(newsid, (char **)ctx, ctxlen);
>  }
>  
> +static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
> +   struct qstr *name,
> +   const struct cred *old,
> +   struct cred *new)
> +{
> + u32 newsid;
> + int rc;
> + struct task_security_struct *tsec;
> +
> + rc = selinux_determine_inode_label(old->security,
> +d_inode(dentry->d_parent), name,
> +inode_mode_to_security_class(mode),
> +);
> + if (rc)
> + return rc;
> +
> + tsec = new->security;
> + tsec->create_sid = newsid;
> + return 0;
> +}
> +
>  static int selinux_inode_init_security(struct inode *inode, struct inode 
> *dir,
>  const struct qstr *qstr,
>  const char **name,
> @@ -6066,6 +6087,7 @@ static struct security_hook_list selinux_hooks[] = {
>   LSM_HOOK_INIT(sb_parse_opts_str, selinux_parse_opts_str),
>  
>   LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security),
> + LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as),
>  
>   LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
>   LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
> 



Re: [PATCH 5/9] selinux: Pass security pointer to determine_inode_label()

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> Right now selinux_determine_inode_label() works on security pointer of
> current task. Soon I need this to work on a security pointer retrieved
> from a set of creds. So start passing in a pointer and caller can decide
> where to fetch security pointer from.
> 
> Signed-off-by: Vivek Goyal 

Acked-by: Stephen Smalley 

> ---
>  security/selinux/hooks.c | 19 ++-
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 4fda548..ae11fd9 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -1785,13 +1785,13 @@ out:
>  /*
>   * Determine the label for an inode that might be unioned.
>   */
> -static int selinux_determine_inode_label(struct inode *dir,
> -  const struct qstr *name,
> -  u16 tclass,
> -  u32 *_new_isid)
> +static int
> +selinux_determine_inode_label(const struct task_security_struct *tsec,
> +  struct inode *dir,
> +  const struct qstr *name, u16 tclass,
> +  u32 *_new_isid)
>  {
>   const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
> - const struct task_security_struct *tsec = current_security();
>  
>   if ((sbsec->flags & SE_SBINITIALIZED) &&
>   (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
> @@ -1834,8 +1834,8 @@ static int may_create(struct inode *dir,
>   if (rc)
>   return rc;
>  
> - rc = selinux_determine_inode_label(dir, >d_name, tclass,
> -);
> + rc = selinux_determine_inode_label(current_security(), dir,
> +>d_name, tclass, );
>   if (rc)
>   return rc;
>  
> @@ -2815,7 +2815,8 @@ static int selinux_dentry_init_security(struct dentry 
> *dentry, int mode,
>   u32 newsid;
>   int rc;
>  
> - rc = selinux_determine_inode_label(d_inode(dentry->d_parent), name,
> + rc = selinux_determine_inode_label(current_security(),
> +d_inode(dentry->d_parent), name,
>  inode_mode_to_security_class(mode),
>  );
>   if (rc)
> @@ -2840,7 +2841,7 @@ static int selinux_inode_init_security(struct inode 
> *inode, struct inode *dir,
>   sid = tsec->sid;
>   newsid = tsec->create_sid;
>  
> - rc = selinux_determine_inode_label(
> + rc = selinux_determine_inode_label(current_security(),
>   dir, qstr,
>   inode_mode_to_security_class(inode->i_mode),
>   );
> 



Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:57 AM, Stephen Smalley wrote:
> On 07/13/2016 10:44 AM, Vivek Goyal wrote:
>> During a new file creation we need to make sure new file is created with the
>> right label. New file is created in upper/ so effectively file should get
>> label as if task had created file in upper/.
>>
>> We switched to mounter's creds for actual file creation. Also if there is a
>> whiteout present, then file will be created in work/ dir first and then
>> renamed in upper. In none of the cases file will be labeled as we want it to
>> be.
>>
>> This patch introduces a new hook dentry_create_files_as(), which determines
>> the label/context dentry will get if it had been created by task in upper
>> and modify passed set of creds appropriately. Caller makes use of these new
>> creds for file creation.
>>
>> Signed-off-by: Vivek Goyal 
>> ---
>>  fs/overlayfs/dir.c| 10 ++
>>  include/linux/lsm_hooks.h | 15 +++
>>  include/linux/security.h  | 12 
>>  security/security.c   | 11 +++
>>  4 files changed, 48 insertions(+)
>>
>> diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
>> index 4cdeb74..f94872f 100644
>> --- a/fs/overlayfs/dir.c
>> +++ b/fs/overlayfs/dir.c
>> @@ -433,6 +433,15 @@ static int ovl_create_or_link(struct dentry *dentry, 
>> int mode, dev_t rdev,
>>  if (override_cred) {
>>  override_cred->fsuid = inode->i_uid;
>>  override_cred->fsgid = inode->i_gid;
>> +if (!hardlink) {
>> +err = security_dentry_create_files_as(dentry,
>> +mode, >d_name, old_cred,
>> +override_cred);
>> +if (err) {
>> +put_cred(override_cred);
> 
> Same principle here; on error the caller should do nothing with
> override_cred.

Sorry, never mind - not allocated by the hook so properly handled by the
caller.

> 
>> +goto out_revert_creds;
>> +}
>> +}
>>  put_cred(override_creds(override_cred));
>>  put_cred(override_cred);
>>  
>> @@ -443,6 +452,7 @@ static int ovl_create_or_link(struct dentry *dentry, int 
>> mode, dev_t rdev,
>>  err = ovl_create_over_whiteout(dentry, inode, ,
>>  link, hardlink);
>>  }
>> +out_revert_creds:
>>  revert_creds(old_cred);
>>  if (!err) {
>>  struct inode *realinode = d_inode(ovl_dentry_upper(dentry));
>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
>> index 84caead..95745fe 100644
>> --- a/include/linux/lsm_hooks.h
>> +++ b/include/linux/lsm_hooks.h
>> @@ -151,6 +151,16 @@
>>   *  @name name of the last path component used to create file
>>   *  @ctx pointer to place the pointer to the resulting context in.
>>   *  @ctxlen point to place the length of the resulting context.
>> + * @dentry_create_files_as:
>> + *  Compute a context for a dentry as the inode is not yet available
>> + *  and set that context in passed in creds so that new files are
>> + *  created using that context. Context is calculated using the
>> + *  passed in creds and not the creds of the caller.
>> + *  @dentry dentry to use in calculating the context.
>> + *  @mode mode used to determine resource type.
>> + *  @name name of the last path component used to create file
>> + *  @old creds which should be used for context calculation
>> + *  @new creds to modify
>>   *
>>   *
>>   * Security hooks for inode operations.
>> @@ -1375,6 +1385,10 @@ union security_list_options {
>>  int (*dentry_init_security)(struct dentry *dentry, int mode,
>>  struct qstr *name, void **ctx,
>>  u32 *ctxlen);
>> +int (*dentry_create_files_as)(struct dentry *dentry, int mode,
>> +struct qstr *name,
>> +const struct cred *old,
>> +struct cred *new);
>>  
>>  
>>  #ifdef CONFIG_SECURITY_PATH
>> @@ -1675,6 +1689,7 @@ struct security_hook_heads {
>>  struct list_head sb_clone_mnt_opts;
>>  struct list_head sb_parse_opts_str;
>>  struct list_head dentry_init_security;
>> +struct list_head dentry_create_files_as;
>>  #ifdef CONFIG_SECURITY_PATH
>>  st

Re: [PATCH 7/9] selinux: Implement dentry_create_files_as() hook

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> Calculate what would be the label of newly created file and set that secid
> in the passed creds.
> 
> Context of the task which is actually creating file is retrieved from
> set of creds passed in. (old->security).
> 
> Signed-off-by: Vivek Goyal 

Acked-by: Stephen Smalley 

> ---
>  security/selinux/hooks.c | 22 ++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index ae11fd9..77eb5a8 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2825,6 +2825,27 @@ static int selinux_dentry_init_security(struct dentry 
> *dentry, int mode,
>   return security_sid_to_context(newsid, (char **)ctx, ctxlen);
>  }
>  
> +static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
> +   struct qstr *name,
> +   const struct cred *old,
> +   struct cred *new)
> +{
> + u32 newsid;
> + int rc;
> + struct task_security_struct *tsec;
> +
> + rc = selinux_determine_inode_label(old->security,
> +d_inode(dentry->d_parent), name,
> +inode_mode_to_security_class(mode),
> +);
> + if (rc)
> + return rc;
> +
> + tsec = new->security;
> + tsec->create_sid = newsid;
> + return 0;
> +}
> +
>  static int selinux_inode_init_security(struct inode *inode, struct inode 
> *dir,
>  const struct qstr *qstr,
>  const char **name,
> @@ -6066,6 +6087,7 @@ static struct security_hook_list selinux_hooks[] = {
>   LSM_HOOK_INIT(sb_parse_opts_str, selinux_parse_opts_str),
>  
>   LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security),
> + LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as),
>  
>   LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
>   LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
> 



Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> During a new file creation we need to make sure new file is created with the
> right label. New file is created in upper/ so effectively file should get
> label as if task had created file in upper/.
> 
> We switched to mounter's creds for actual file creation. Also if there is a
> whiteout present, then file will be created in work/ dir first and then
> renamed in upper. In none of the cases file will be labeled as we want it to
> be.
> 
> This patch introduces a new hook dentry_create_files_as(), which determines
> the label/context dentry will get if it had been created by task in upper
> and modify passed set of creds appropriately. Caller makes use of these new
> creds for file creation.
> 
> Signed-off-by: Vivek Goyal 
> ---
>  fs/overlayfs/dir.c| 10 ++
>  include/linux/lsm_hooks.h | 15 +++
>  include/linux/security.h  | 12 
>  security/security.c   | 11 +++
>  4 files changed, 48 insertions(+)
> 
> diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
> index 4cdeb74..f94872f 100644
> --- a/fs/overlayfs/dir.c
> +++ b/fs/overlayfs/dir.c
> @@ -433,6 +433,15 @@ static int ovl_create_or_link(struct dentry *dentry, int 
> mode, dev_t rdev,
>   if (override_cred) {
>   override_cred->fsuid = inode->i_uid;
>   override_cred->fsgid = inode->i_gid;
> + if (!hardlink) {
> + err = security_dentry_create_files_as(dentry,
> + mode, >d_name, old_cred,
> + override_cred);
> + if (err) {
> + put_cred(override_cred);

Same principle here; on error the caller should do nothing with
override_cred.

> + goto out_revert_creds;
> + }
> + }
>   put_cred(override_creds(override_cred));
>   put_cred(override_cred);
>  
> @@ -443,6 +452,7 @@ static int ovl_create_or_link(struct dentry *dentry, int 
> mode, dev_t rdev,
>   err = ovl_create_over_whiteout(dentry, inode, ,
>   link, hardlink);
>   }
> +out_revert_creds:
>   revert_creds(old_cred);
>   if (!err) {
>   struct inode *realinode = d_inode(ovl_dentry_upper(dentry));
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 84caead..95745fe 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -151,6 +151,16 @@
>   *   @name name of the last path component used to create file
>   *   @ctx pointer to place the pointer to the resulting context in.
>   *   @ctxlen point to place the length of the resulting context.
> + * @dentry_create_files_as:
> + *   Compute a context for a dentry as the inode is not yet available
> + *   and set that context in passed in creds so that new files are
> + *   created using that context. Context is calculated using the
> + *   passed in creds and not the creds of the caller.
> + *   @dentry dentry to use in calculating the context.
> + *   @mode mode used to determine resource type.
> + *   @name name of the last path component used to create file
> + *   @old creds which should be used for context calculation
> + *   @new creds to modify
>   *
>   *
>   * Security hooks for inode operations.
> @@ -1375,6 +1385,10 @@ union security_list_options {
>   int (*dentry_init_security)(struct dentry *dentry, int mode,
>   struct qstr *name, void **ctx,
>   u32 *ctxlen);
> + int (*dentry_create_files_as)(struct dentry *dentry, int mode,
> + struct qstr *name,
> + const struct cred *old,
> + struct cred *new);
>  
>  
>  #ifdef CONFIG_SECURITY_PATH
> @@ -1675,6 +1689,7 @@ struct security_hook_heads {
>   struct list_head sb_clone_mnt_opts;
>   struct list_head sb_parse_opts_str;
>   struct list_head dentry_init_security;
> + struct list_head dentry_create_files_as;
>  #ifdef CONFIG_SECURITY_PATH
>   struct list_head path_unlink;
>   struct list_head path_mkdir;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 4a3b8bc..1eb03dc 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -242,6 +242,10 @@ int security_sb_parse_opts_str(char *options, struct 
> security_mnt_opts *opts);
>  int security_dentry_init_security(struct dentry *dentry, int mode,
>   struct qstr *name, void **ctx,
>   u32 *ctxlen);
> +int security_dentry_create_files_as(struct dentry *dentry, int mode,
> + struct qstr *name,
> + const struct cred *old,
> +   

Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> During a new file creation we need to make sure new file is created with the
> right label. New file is created in upper/ so effectively file should get
> label as if task had created file in upper/.
> 
> We switched to mounter's creds for actual file creation. Also if there is a
> whiteout present, then file will be created in work/ dir first and then
> renamed in upper. In none of the cases file will be labeled as we want it to
> be.
> 
> This patch introduces a new hook dentry_create_files_as(), which determines
> the label/context dentry will get if it had been created by task in upper
> and modify passed set of creds appropriately. Caller makes use of these new
> creds for file creation.
> 
> Signed-off-by: Vivek Goyal 
> ---
>  fs/overlayfs/dir.c| 10 ++
>  include/linux/lsm_hooks.h | 15 +++
>  include/linux/security.h  | 12 
>  security/security.c   | 11 +++
>  4 files changed, 48 insertions(+)
> 
> diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
> index 4cdeb74..f94872f 100644
> --- a/fs/overlayfs/dir.c
> +++ b/fs/overlayfs/dir.c
> @@ -433,6 +433,15 @@ static int ovl_create_or_link(struct dentry *dentry, int 
> mode, dev_t rdev,
>   if (override_cred) {
>   override_cred->fsuid = inode->i_uid;
>   override_cred->fsgid = inode->i_gid;
> + if (!hardlink) {
> + err = security_dentry_create_files_as(dentry,
> + mode, >d_name, old_cred,
> + override_cred);
> + if (err) {
> + put_cred(override_cred);

Same principle here; on error the caller should do nothing with
override_cred.

> + goto out_revert_creds;
> + }
> + }
>   put_cred(override_creds(override_cred));
>   put_cred(override_cred);
>  
> @@ -443,6 +452,7 @@ static int ovl_create_or_link(struct dentry *dentry, int 
> mode, dev_t rdev,
>   err = ovl_create_over_whiteout(dentry, inode, ,
>   link, hardlink);
>   }
> +out_revert_creds:
>   revert_creds(old_cred);
>   if (!err) {
>   struct inode *realinode = d_inode(ovl_dentry_upper(dentry));
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 84caead..95745fe 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -151,6 +151,16 @@
>   *   @name name of the last path component used to create file
>   *   @ctx pointer to place the pointer to the resulting context in.
>   *   @ctxlen point to place the length of the resulting context.
> + * @dentry_create_files_as:
> + *   Compute a context for a dentry as the inode is not yet available
> + *   and set that context in passed in creds so that new files are
> + *   created using that context. Context is calculated using the
> + *   passed in creds and not the creds of the caller.
> + *   @dentry dentry to use in calculating the context.
> + *   @mode mode used to determine resource type.
> + *   @name name of the last path component used to create file
> + *   @old creds which should be used for context calculation
> + *   @new creds to modify
>   *
>   *
>   * Security hooks for inode operations.
> @@ -1375,6 +1385,10 @@ union security_list_options {
>   int (*dentry_init_security)(struct dentry *dentry, int mode,
>   struct qstr *name, void **ctx,
>   u32 *ctxlen);
> + int (*dentry_create_files_as)(struct dentry *dentry, int mode,
> + struct qstr *name,
> + const struct cred *old,
> + struct cred *new);
>  
>  
>  #ifdef CONFIG_SECURITY_PATH
> @@ -1675,6 +1689,7 @@ struct security_hook_heads {
>   struct list_head sb_clone_mnt_opts;
>   struct list_head sb_parse_opts_str;
>   struct list_head dentry_init_security;
> + struct list_head dentry_create_files_as;
>  #ifdef CONFIG_SECURITY_PATH
>   struct list_head path_unlink;
>   struct list_head path_mkdir;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 4a3b8bc..1eb03dc 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -242,6 +242,10 @@ int security_sb_parse_opts_str(char *options, struct 
> security_mnt_opts *opts);
>  int security_dentry_init_security(struct dentry *dentry, int mode,
>   struct qstr *name, void **ctx,
>   u32 *ctxlen);
> +int security_dentry_create_files_as(struct dentry *dentry, int mode,
> + struct qstr *name,
> + const struct cred *old,
> + 

Re: [PATCH 2/9] selinux: Implementation for inode_copy_up() hook

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> A file is being copied up for overlay file system. Prepare a new set of
> creds and set create_sid appropriately so that new file is created with
> appropriate label.
> 
> Overlay inode has right label for both context and non-context mount
> cases. In case of non-context mount, overlay inode will have the label
> of lower file and in case of context mount, overlay inode will have
> the label from context= mount option.
> 
> Signed-off-by: Vivek Goyal <vgo...@redhat.com>

Acked-by: Stephen Smalley <s...@tycho.nsa.gov>

> ---
>  security/selinux/hooks.c | 21 +
>  1 file changed, 21 insertions(+)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index a86d537..c82ee54 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -3270,6 +3270,26 @@ static void selinux_inode_getsecid(struct inode 
> *inode, u32 *secid)
>   *secid = isec->sid;
>  }
>  
> +static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
> +{
> + u32 sid;
> + struct task_security_struct *tsec;
> + struct cred *new_creds = *new;
> +
> + if (new_creds == NULL) {
> + new_creds = prepare_creds();
> + if (!new_creds)
> + return -ENOMEM;
> + }
> +
> + tsec = new_creds->security;
> + /* Get label from overlay inode and set it in create_sid */
> + selinux_inode_getsecid(d_inode(src), );
> + tsec->create_sid = sid;
> + *new = new_creds;
> + return 0;
> +}
> +
>  /* file security operations */
>  
>  static int selinux_revalidate_file_permission(struct file *file, int mask)
> @@ -6056,6 +6076,7 @@ static struct security_hook_list selinux_hooks[] = {
>   LSM_HOOK_INIT(inode_setsecurity, selinux_inode_setsecurity),
>   LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity),
>   LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
> + LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
>  
>   LSM_HOOK_INIT(file_permission, selinux_file_permission),
>   LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
> 



Re: [PATCH 4/9] selinux: Implementation for inode_copy_up_xattr() hook

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> When a file is copied up in overlay, we have already created file on upper/
> with right label and there is no need to copy up selinux label/xattr from
> lower file to upper file. In fact in case of context mount, we don't want
> to copy up label as newly created file got its label from context= option.
> 
> Signed-off-by: Vivek Goyal <vgo...@redhat.com>

Acked-by: Stephen Smalley <s...@tycho.nsa.gov>

> ---
>  security/selinux/hooks.c | 16 
>  1 file changed, 16 insertions(+)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index c82ee54..4fda548 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -3290,6 +3290,21 @@ static int selinux_inode_copy_up(struct dentry *src, 
> struct cred **new)
>   return 0;
>  }
>  
> +static int selinux_inode_copy_up_xattr(const char *name)
> +{
> + /* The copy_up hook above sets the initial context on an inode, but we
> +  * don't then want to overwrite it by blindly copying all the lower
> +  * xattrs up.  Instead, we have to filter out SELinux-related xattrs.
> +  */
> + if (strcmp(name, XATTR_NAME_SELINUX) == 0)
> + return 1; /* Discard */
> + /*
> +  * Any other attribute apart from SELINUX is not claimed, supported
> +  * by selinux.
> +  */
> + return -EOPNOTSUPP;
> +}
> +
>  /* file security operations */
>  
>  static int selinux_revalidate_file_permission(struct file *file, int mask)
> @@ -6077,6 +6092,7 @@ static struct security_hook_list selinux_hooks[] = {
>   LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity),
>   LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
>   LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
> + LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr),
>  
>   LSM_HOOK_INIT(file_permission, selinux_file_permission),
>   LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
> 



Re: [PATCH 2/9] selinux: Implementation for inode_copy_up() hook

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> A file is being copied up for overlay file system. Prepare a new set of
> creds and set create_sid appropriately so that new file is created with
> appropriate label.
> 
> Overlay inode has right label for both context and non-context mount
> cases. In case of non-context mount, overlay inode will have the label
> of lower file and in case of context mount, overlay inode will have
> the label from context= mount option.
> 
> Signed-off-by: Vivek Goyal 

Acked-by: Stephen Smalley 

> ---
>  security/selinux/hooks.c | 21 +
>  1 file changed, 21 insertions(+)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index a86d537..c82ee54 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -3270,6 +3270,26 @@ static void selinux_inode_getsecid(struct inode 
> *inode, u32 *secid)
>   *secid = isec->sid;
>  }
>  
> +static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
> +{
> + u32 sid;
> + struct task_security_struct *tsec;
> + struct cred *new_creds = *new;
> +
> + if (new_creds == NULL) {
> + new_creds = prepare_creds();
> + if (!new_creds)
> + return -ENOMEM;
> + }
> +
> + tsec = new_creds->security;
> + /* Get label from overlay inode and set it in create_sid */
> + selinux_inode_getsecid(d_inode(src), );
> + tsec->create_sid = sid;
> + *new = new_creds;
> + return 0;
> +}
> +
>  /* file security operations */
>  
>  static int selinux_revalidate_file_permission(struct file *file, int mask)
> @@ -6056,6 +6076,7 @@ static struct security_hook_list selinux_hooks[] = {
>   LSM_HOOK_INIT(inode_setsecurity, selinux_inode_setsecurity),
>   LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity),
>   LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
> + LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
>  
>   LSM_HOOK_INIT(file_permission, selinux_file_permission),
>   LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
> 



Re: [PATCH 4/9] selinux: Implementation for inode_copy_up_xattr() hook

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> When a file is copied up in overlay, we have already created file on upper/
> with right label and there is no need to copy up selinux label/xattr from
> lower file to upper file. In fact in case of context mount, we don't want
> to copy up label as newly created file got its label from context= option.
> 
> Signed-off-by: Vivek Goyal 

Acked-by: Stephen Smalley 

> ---
>  security/selinux/hooks.c | 16 
>  1 file changed, 16 insertions(+)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index c82ee54..4fda548 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -3290,6 +3290,21 @@ static int selinux_inode_copy_up(struct dentry *src, 
> struct cred **new)
>   return 0;
>  }
>  
> +static int selinux_inode_copy_up_xattr(const char *name)
> +{
> + /* The copy_up hook above sets the initial context on an inode, but we
> +  * don't then want to overwrite it by blindly copying all the lower
> +  * xattrs up.  Instead, we have to filter out SELinux-related xattrs.
> +  */
> + if (strcmp(name, XATTR_NAME_SELINUX) == 0)
> + return 1; /* Discard */
> + /*
> +  * Any other attribute apart from SELINUX is not claimed, supported
> +  * by selinux.
> +  */
> + return -EOPNOTSUPP;
> +}
> +
>  /* file security operations */
>  
>  static int selinux_revalidate_file_permission(struct file *file, int mask)
> @@ -6077,6 +6092,7 @@ static struct security_hook_list selinux_hooks[] = {
>   LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity),
>   LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
>   LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
> + LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr),
>  
>   LSM_HOOK_INIT(file_permission, selinux_file_permission),
>   LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
> 



Re: [PATCH 1/9] security, overlayfs: provide copy up security hook for unioned files

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> Provide a security hook to label new file correctly when a file is copied
> up from lower layer to upper layer of a overlay/union mount.
> 
> This hook can prepare a new set of creds which are suitable for new file
> creation during copy up. Caller will use new creds to create file and then
> revert back to old creds and release new creds.
> 
> Signed-off-by: Vivek Goyal 
> ---
>  fs/overlayfs/copy_up.c| 18 ++
>  include/linux/lsm_hooks.h | 11 +++
>  include/linux/security.h  |  6 ++
>  security/security.c   |  8 
>  4 files changed, 43 insertions(+)
> 
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index 80aa6f1..8ebea18 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -246,6 +246,8 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   struct dentry *upper = NULL;
>   umode_t mode = stat->mode;
>   int err;
> + const struct cred *old_creds = NULL;
> + struct cred *new_creds = NULL;
>  
>   newdentry = ovl_lookup_temp(workdir, dentry);
>   err = PTR_ERR(newdentry);
> @@ -258,10 +260,26 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   if (IS_ERR(upper))
>   goto out1;
>  
> + err = security_inode_copy_up(dentry, _creds);
> + if (err < 0) {
> + if (new_creds)
> + put_cred(new_creds);

I think this is a mistake, diverges from how other hooks handle error
conditions (if the hook allocates, the hook or the security
infrastructure is responsible for freeing on error return, not the
caller), and will be prone to double free errors.

> + goto out2;
> + }
> +
> + if (new_creds)
> + old_creds = override_creds(new_creds);
> +
>   /* Can't properly set mode on creation because of the umask */
>   stat->mode &= S_IFMT;
>   err = ovl_create_real(wdir, newdentry, stat, link, NULL, true);
>   stat->mode = mode;
> +
> + if (new_creds) {
> + revert_creds(old_creds);
> + put_cred(new_creds);
> + }
> +
>   if (err)
>   goto out2;
>  
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7ae3976..c1f95be 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -401,6 +401,15 @@
>   *   @inode contains a pointer to the inode.
>   *   @secid contains a pointer to the location where result will be saved.
>   *   In case of failure, @secid will be set to zero.
> + * @inode_copy_up:
> + *   A file is about to be copied up from lower layer to upper layer of
> + *   overlay filesystem. Security module can prepare a set of new creds
> + *   and modify as need be and return new creds. Caller will switch to
> + *   new creds temporarily to create new file and release newly allocated
> + *   creds.
> + *   @src indicates the union dentry of file that is being copied up.
> + *   @new pointer to pointer to return newly allocated creds.
> + *   Returns 0 on success or a negative error code on error.
>   *
>   * Security hooks for file operations
>   *
> @@ -1425,6 +1434,7 @@ union security_list_options {
>   int (*inode_listsecurity)(struct inode *inode, char *buffer,
>   size_t buffer_size);
>   void (*inode_getsecid)(struct inode *inode, u32 *secid);
> + int (*inode_copy_up) (struct dentry *src, struct cred **new);
>  
>   int (*file_permission)(struct file *file, int mask);
>   int (*file_alloc_security)(struct file *file);
> @@ -1696,6 +1706,7 @@ struct security_hook_heads {
>   struct list_head inode_setsecurity;
>   struct list_head inode_listsecurity;
>   struct list_head inode_getsecid;
> + struct list_head inode_copy_up;
>   struct list_head file_permission;
>   struct list_head file_alloc_security;
>   struct list_head file_free_security;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 14df373..c976d79 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -282,6 +282,7 @@ int security_inode_getsecurity(struct inode *inode, const 
> char *name, void **buf
>  int security_inode_setsecurity(struct inode *inode, const char *name, const 
> void *value, size_t size, int flags);
>  int security_inode_listsecurity(struct inode *inode, char *buffer, size_t 
> buffer_size);
>  void security_inode_getsecid(struct inode *inode, u32 *secid);
> +int security_inode_copy_up(struct dentry *src, struct cred **new);
>  int security_file_permission(struct file *file, int mask);
>  int security_file_alloc(struct file *file);
>  void security_file_free(struct file *file);
> @@ -758,6 +759,11 @@ static inline void security_inode_getsecid(struct inode 
> *inode, u32 *secid)
>   *secid = 0;
>  }
>  
> +static inline int security_inode_copy_up(struct dentry *src, struct cred 

Re: [PATCH 1/9] security, overlayfs: provide copy up security hook for unioned files

2016-07-13 Thread Stephen Smalley
On 07/13/2016 10:44 AM, Vivek Goyal wrote:
> Provide a security hook to label new file correctly when a file is copied
> up from lower layer to upper layer of a overlay/union mount.
> 
> This hook can prepare a new set of creds which are suitable for new file
> creation during copy up. Caller will use new creds to create file and then
> revert back to old creds and release new creds.
> 
> Signed-off-by: Vivek Goyal 
> ---
>  fs/overlayfs/copy_up.c| 18 ++
>  include/linux/lsm_hooks.h | 11 +++
>  include/linux/security.h  |  6 ++
>  security/security.c   |  8 
>  4 files changed, 43 insertions(+)
> 
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index 80aa6f1..8ebea18 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -246,6 +246,8 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   struct dentry *upper = NULL;
>   umode_t mode = stat->mode;
>   int err;
> + const struct cred *old_creds = NULL;
> + struct cred *new_creds = NULL;
>  
>   newdentry = ovl_lookup_temp(workdir, dentry);
>   err = PTR_ERR(newdentry);
> @@ -258,10 +260,26 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   if (IS_ERR(upper))
>   goto out1;
>  
> + err = security_inode_copy_up(dentry, _creds);
> + if (err < 0) {
> + if (new_creds)
> + put_cred(new_creds);

I think this is a mistake, diverges from how other hooks handle error
conditions (if the hook allocates, the hook or the security
infrastructure is responsible for freeing on error return, not the
caller), and will be prone to double free errors.

> + goto out2;
> + }
> +
> + if (new_creds)
> + old_creds = override_creds(new_creds);
> +
>   /* Can't properly set mode on creation because of the umask */
>   stat->mode &= S_IFMT;
>   err = ovl_create_real(wdir, newdentry, stat, link, NULL, true);
>   stat->mode = mode;
> +
> + if (new_creds) {
> + revert_creds(old_creds);
> + put_cred(new_creds);
> + }
> +
>   if (err)
>   goto out2;
>  
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7ae3976..c1f95be 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -401,6 +401,15 @@
>   *   @inode contains a pointer to the inode.
>   *   @secid contains a pointer to the location where result will be saved.
>   *   In case of failure, @secid will be set to zero.
> + * @inode_copy_up:
> + *   A file is about to be copied up from lower layer to upper layer of
> + *   overlay filesystem. Security module can prepare a set of new creds
> + *   and modify as need be and return new creds. Caller will switch to
> + *   new creds temporarily to create new file and release newly allocated
> + *   creds.
> + *   @src indicates the union dentry of file that is being copied up.
> + *   @new pointer to pointer to return newly allocated creds.
> + *   Returns 0 on success or a negative error code on error.
>   *
>   * Security hooks for file operations
>   *
> @@ -1425,6 +1434,7 @@ union security_list_options {
>   int (*inode_listsecurity)(struct inode *inode, char *buffer,
>   size_t buffer_size);
>   void (*inode_getsecid)(struct inode *inode, u32 *secid);
> + int (*inode_copy_up) (struct dentry *src, struct cred **new);
>  
>   int (*file_permission)(struct file *file, int mask);
>   int (*file_alloc_security)(struct file *file);
> @@ -1696,6 +1706,7 @@ struct security_hook_heads {
>   struct list_head inode_setsecurity;
>   struct list_head inode_listsecurity;
>   struct list_head inode_getsecid;
> + struct list_head inode_copy_up;
>   struct list_head file_permission;
>   struct list_head file_alloc_security;
>   struct list_head file_free_security;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 14df373..c976d79 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -282,6 +282,7 @@ int security_inode_getsecurity(struct inode *inode, const 
> char *name, void **buf
>  int security_inode_setsecurity(struct inode *inode, const char *name, const 
> void *value, size_t size, int flags);
>  int security_inode_listsecurity(struct inode *inode, char *buffer, size_t 
> buffer_size);
>  void security_inode_getsecid(struct inode *inode, u32 *secid);
> +int security_inode_copy_up(struct dentry *src, struct cred **new);
>  int security_file_permission(struct file *file, int mask);
>  int security_file_alloc(struct file *file);
>  void security_file_free(struct file *file);
> @@ -758,6 +759,11 @@ static inline void security_inode_getsecid(struct inode 
> *inode, u32 *secid)
>   *secid = 0;
>  }
>  
> +static inline int security_inode_copy_up(struct dentry *src, struct cred 
> **new)
> +{
> +  

Re: [PATCH 3/7] security,overlayfs: Provide security hook for copy up of xattrs for overlay file

2016-07-11 Thread Stephen Smalley
On 07/08/2016 12:19 PM, Vivek Goyal wrote:
> Provide a security hook which is called when xattrs of a file are being
> copied up. This hook is called once for each xattr and LSM can return 0
> to access the xattr, 1 to reject xattr, -EOPNOTSUPP if none of the lsms
> claim to know xattr and a negative error code if something went terribly
> wrong.

0 if the security module wants the xattr to be copied up, 1 if the
security module wants the xattr to be discarded on the copy, -EOPNOTSUPP
if the security module does not handle/manage the xattr, or a -errno
upon an error.

> 
> If 0 or -EOPNOTSUPP is returned, xattr will be copied up, if 1 is returned,
> xattr will not be copied up and if negative error code is returned, copy up
> will be aborted.

Not sure I understand the benefit of the 0 vs -EOPNOTSUPP distinction.

> 
> Signed-off-by: David Howells 
> Signed-off-by: Vivek Goyal 
> ---
>  fs/overlayfs/copy_up.c|  7 +++
>  include/linux/lsm_hooks.h | 10 ++
>  include/linux/security.h  |  6 ++
>  security/security.c   |  8 
>  4 files changed, 31 insertions(+)
> 
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index 8ebea18..68cefb2 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -103,6 +103,13 @@ retry:
>   goto retry;
>   }
>  
> + error = security_inode_copy_up_xattr(name);
> + if (error < 0 && error != -EOPNOTSUPP)
> + break;
> + if (error == 1) {
> + error = 0;
> + continue; /* Discard */
> + }
>   error = vfs_setxattr(new, name, value, size, 0);
>   if (error)
>   break;
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index c1f95be..84caead 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -410,6 +410,14 @@
>   *   @src indicates the union dentry of file that is being copied up.
>   *   @new pointer to pointer to return newly allocated creds.
>   *   Returns 0 on success or a negative error code on error.
> + * @inode_copy_up_xattr:
> + *   Filter the xattrs being copied up when a unioned file is copied
> + *   up from a lower layer to the union/overlay layer.
> + *   @name indicates the name of the xattr.
> + *   Returns 0 to accept the xattr, 1 to discard the xattr, -EOPNOTSUPP if
> + *   security module does not know about attribute or a negative error code
> + *   to abort the copy up. Note that the caller is responsible for reading
> + *   and writing the xattrs as this hook is merely a filter.
>   *
>   * Security hooks for file operations
>   *
> @@ -1435,6 +1443,7 @@ union security_list_options {
>   size_t buffer_size);
>   void (*inode_getsecid)(struct inode *inode, u32 *secid);
>   int (*inode_copy_up) (struct dentry *src, struct cred **new);
> + int (*inode_copy_up_xattr) (const char *name);
>  
>   int (*file_permission)(struct file *file, int mask);
>   int (*file_alloc_security)(struct file *file);
> @@ -1707,6 +1716,7 @@ struct security_hook_heads {
>   struct list_head inode_listsecurity;
>   struct list_head inode_getsecid;
>   struct list_head inode_copy_up;
> + struct list_head inode_copy_up_xattr;
>   struct list_head file_permission;
>   struct list_head file_alloc_security;
>   struct list_head file_free_security;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index c976d79..08d3191 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -283,6 +283,7 @@ int security_inode_setsecurity(struct inode *inode, const 
> char *name, const void
>  int security_inode_listsecurity(struct inode *inode, char *buffer, size_t 
> buffer_size);
>  void security_inode_getsecid(struct inode *inode, u32 *secid);
>  int security_inode_copy_up(struct dentry *src, struct cred **new);
> +int security_inode_copy_up_xattr(const char *name);
>  int security_file_permission(struct file *file, int mask);
>  int security_file_alloc(struct file *file);
>  void security_file_free(struct file *file);
> @@ -764,6 +765,11 @@ static inline int security_inode_copy_up(struct dentry 
> *src, struct cred **new)
>   return 0;
>  }
>  
> +static inline int security_inode_copy_up_xattr(const char *name)
> +{
> + -EOPNOTSUPP;

return?

> +}
> +
>  static inline int security_file_permission(struct file *file, int mask)
>  {
>   return 0;
> diff --git a/security/security.c b/security/security.c
> index 3d142aa..3321e31 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -733,6 +733,12 @@ int security_inode_copy_up(struct dentry *src, struct 
> cred **new)
>  }
>  EXPORT_SYMBOL(security_inode_copy_up);
>  
> +int security_inode_copy_up_xattr(const char *name)
> +{
> + return call_int_hook(inode_copy_up_xattr, -EOPNOTSUPP, 

Re: [PATCH 3/7] security,overlayfs: Provide security hook for copy up of xattrs for overlay file

2016-07-11 Thread Stephen Smalley
On 07/08/2016 12:19 PM, Vivek Goyal wrote:
> Provide a security hook which is called when xattrs of a file are being
> copied up. This hook is called once for each xattr and LSM can return 0
> to access the xattr, 1 to reject xattr, -EOPNOTSUPP if none of the lsms
> claim to know xattr and a negative error code if something went terribly
> wrong.

0 if the security module wants the xattr to be copied up, 1 if the
security module wants the xattr to be discarded on the copy, -EOPNOTSUPP
if the security module does not handle/manage the xattr, or a -errno
upon an error.

> 
> If 0 or -EOPNOTSUPP is returned, xattr will be copied up, if 1 is returned,
> xattr will not be copied up and if negative error code is returned, copy up
> will be aborted.

Not sure I understand the benefit of the 0 vs -EOPNOTSUPP distinction.

> 
> Signed-off-by: David Howells 
> Signed-off-by: Vivek Goyal 
> ---
>  fs/overlayfs/copy_up.c|  7 +++
>  include/linux/lsm_hooks.h | 10 ++
>  include/linux/security.h  |  6 ++
>  security/security.c   |  8 
>  4 files changed, 31 insertions(+)
> 
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index 8ebea18..68cefb2 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -103,6 +103,13 @@ retry:
>   goto retry;
>   }
>  
> + error = security_inode_copy_up_xattr(name);
> + if (error < 0 && error != -EOPNOTSUPP)
> + break;
> + if (error == 1) {
> + error = 0;
> + continue; /* Discard */
> + }
>   error = vfs_setxattr(new, name, value, size, 0);
>   if (error)
>   break;
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index c1f95be..84caead 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -410,6 +410,14 @@
>   *   @src indicates the union dentry of file that is being copied up.
>   *   @new pointer to pointer to return newly allocated creds.
>   *   Returns 0 on success or a negative error code on error.
> + * @inode_copy_up_xattr:
> + *   Filter the xattrs being copied up when a unioned file is copied
> + *   up from a lower layer to the union/overlay layer.
> + *   @name indicates the name of the xattr.
> + *   Returns 0 to accept the xattr, 1 to discard the xattr, -EOPNOTSUPP if
> + *   security module does not know about attribute or a negative error code
> + *   to abort the copy up. Note that the caller is responsible for reading
> + *   and writing the xattrs as this hook is merely a filter.
>   *
>   * Security hooks for file operations
>   *
> @@ -1435,6 +1443,7 @@ union security_list_options {
>   size_t buffer_size);
>   void (*inode_getsecid)(struct inode *inode, u32 *secid);
>   int (*inode_copy_up) (struct dentry *src, struct cred **new);
> + int (*inode_copy_up_xattr) (const char *name);
>  
>   int (*file_permission)(struct file *file, int mask);
>   int (*file_alloc_security)(struct file *file);
> @@ -1707,6 +1716,7 @@ struct security_hook_heads {
>   struct list_head inode_listsecurity;
>   struct list_head inode_getsecid;
>   struct list_head inode_copy_up;
> + struct list_head inode_copy_up_xattr;
>   struct list_head file_permission;
>   struct list_head file_alloc_security;
>   struct list_head file_free_security;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index c976d79..08d3191 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -283,6 +283,7 @@ int security_inode_setsecurity(struct inode *inode, const 
> char *name, const void
>  int security_inode_listsecurity(struct inode *inode, char *buffer, size_t 
> buffer_size);
>  void security_inode_getsecid(struct inode *inode, u32 *secid);
>  int security_inode_copy_up(struct dentry *src, struct cred **new);
> +int security_inode_copy_up_xattr(const char *name);
>  int security_file_permission(struct file *file, int mask);
>  int security_file_alloc(struct file *file);
>  void security_file_free(struct file *file);
> @@ -764,6 +765,11 @@ static inline int security_inode_copy_up(struct dentry 
> *src, struct cred **new)
>   return 0;
>  }
>  
> +static inline int security_inode_copy_up_xattr(const char *name)
> +{
> + -EOPNOTSUPP;

return?

> +}
> +
>  static inline int security_file_permission(struct file *file, int mask)
>  {
>   return 0;
> diff --git a/security/security.c b/security/security.c
> index 3d142aa..3321e31 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -733,6 +733,12 @@ int security_inode_copy_up(struct dentry *src, struct 
> cred **new)
>  }
>  EXPORT_SYMBOL(security_inode_copy_up);
>  
> +int security_inode_copy_up_xattr(const char *name)
> +{
> + return call_int_hook(inode_copy_up_xattr, -EOPNOTSUPP, name);
> +}
> 

Re: [PATCH 1/7] security, overlayfs: provide copy up security hook for unioned files

2016-07-11 Thread Stephen Smalley
On 07/08/2016 12:19 PM, Vivek Goyal wrote:
> Provide a security hook to label new file correctly when a file is copied
> up from lower layer to upper layer of a overlay/union mount.
> 
> This hook can prepare a new set of creds which are suitable for new file
> creation during copy up. Caller will use new creds to create file and then
> revert back to old creds and release new creds.
> 
> Signed-off-by: Vivek Goyal 
> ---
>  fs/overlayfs/copy_up.c| 18 ++
>  include/linux/lsm_hooks.h | 11 +++
>  include/linux/security.h  |  6 ++
>  security/security.c   |  8 
>  4 files changed, 43 insertions(+)
> 
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index 80aa6f1..8ebea18 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -246,6 +246,8 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   struct dentry *upper = NULL;
>   umode_t mode = stat->mode;
>   int err;
> + const struct cred *old_creds = NULL;
> + struct cred *new_creds = NULL;
>  
>   newdentry = ovl_lookup_temp(workdir, dentry);
>   err = PTR_ERR(newdentry);
> @@ -258,10 +260,26 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   if (IS_ERR(upper))
>   goto out1;
>  
> + err = security_inode_copy_up(dentry, _creds);
> + if (err < 0) {
> + if (new_creds)
> + put_cred(new_creds);

Why do we need a put_cred() here?

> + goto out2;
> + }
> +
> + if (new_creds)
> + old_creds = override_creds(new_creds);
> +
>   /* Can't properly set mode on creation because of the umask */
>   stat->mode &= S_IFMT;
>   err = ovl_create_real(wdir, newdentry, stat, link, NULL, true);
>   stat->mode = mode;
> +
> + if (new_creds) {
> + revert_creds(old_creds);
> + put_cred(new_creds);
> + }
> +
>   if (err)
>   goto out2;
>  
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7ae3976..c1f95be 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -401,6 +401,15 @@
>   *   @inode contains a pointer to the inode.
>   *   @secid contains a pointer to the location where result will be saved.
>   *   In case of failure, @secid will be set to zero.
> + * @inode_copy_up:
> + *   A file is about to be copied up from lower layer to upper layer of
> + *   overlay filesystem. Security module can prepare a set of new creds
> + *   and modify as need be and return new creds. Caller will switch to
> + *   new creds temporarily to create new file and release newly allocated
> + *   creds.
> + *   @src indicates the union dentry of file that is being copied up.
> + *   @new pointer to pointer to return newly allocated creds.
> + *   Returns 0 on success or a negative error code on error.
>   *
>   * Security hooks for file operations
>   *
> @@ -1425,6 +1434,7 @@ union security_list_options {
>   int (*inode_listsecurity)(struct inode *inode, char *buffer,
>   size_t buffer_size);
>   void (*inode_getsecid)(struct inode *inode, u32 *secid);
> + int (*inode_copy_up) (struct dentry *src, struct cred **new);
>  
>   int (*file_permission)(struct file *file, int mask);
>   int (*file_alloc_security)(struct file *file);
> @@ -1696,6 +1706,7 @@ struct security_hook_heads {
>   struct list_head inode_setsecurity;
>   struct list_head inode_listsecurity;
>   struct list_head inode_getsecid;
> + struct list_head inode_copy_up;
>   struct list_head file_permission;
>   struct list_head file_alloc_security;
>   struct list_head file_free_security;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 14df373..c976d79 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -282,6 +282,7 @@ int security_inode_getsecurity(struct inode *inode, const 
> char *name, void **buf
>  int security_inode_setsecurity(struct inode *inode, const char *name, const 
> void *value, size_t size, int flags);
>  int security_inode_listsecurity(struct inode *inode, char *buffer, size_t 
> buffer_size);
>  void security_inode_getsecid(struct inode *inode, u32 *secid);
> +int security_inode_copy_up(struct dentry *src, struct cred **new);
>  int security_file_permission(struct file *file, int mask);
>  int security_file_alloc(struct file *file);
>  void security_file_free(struct file *file);
> @@ -758,6 +759,11 @@ static inline void security_inode_getsecid(struct inode 
> *inode, u32 *secid)
>   *secid = 0;
>  }
>  
> +static inline int security_inode_copy_up(struct dentry *src, struct cred 
> **new)
> +{
> + return 0;
> +}
> +
>  static inline int security_file_permission(struct file *file, int mask)
>  {
>   return 0;
> diff --git a/security/security.c b/security/security.c
> index 

Re: [PATCH 1/7] security, overlayfs: provide copy up security hook for unioned files

2016-07-11 Thread Stephen Smalley
On 07/08/2016 12:19 PM, Vivek Goyal wrote:
> Provide a security hook to label new file correctly when a file is copied
> up from lower layer to upper layer of a overlay/union mount.
> 
> This hook can prepare a new set of creds which are suitable for new file
> creation during copy up. Caller will use new creds to create file and then
> revert back to old creds and release new creds.
> 
> Signed-off-by: Vivek Goyal 
> ---
>  fs/overlayfs/copy_up.c| 18 ++
>  include/linux/lsm_hooks.h | 11 +++
>  include/linux/security.h  |  6 ++
>  security/security.c   |  8 
>  4 files changed, 43 insertions(+)
> 
> diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
> index 80aa6f1..8ebea18 100644
> --- a/fs/overlayfs/copy_up.c
> +++ b/fs/overlayfs/copy_up.c
> @@ -246,6 +246,8 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   struct dentry *upper = NULL;
>   umode_t mode = stat->mode;
>   int err;
> + const struct cred *old_creds = NULL;
> + struct cred *new_creds = NULL;
>  
>   newdentry = ovl_lookup_temp(workdir, dentry);
>   err = PTR_ERR(newdentry);
> @@ -258,10 +260,26 @@ static int ovl_copy_up_locked(struct dentry *workdir, 
> struct dentry *upperdir,
>   if (IS_ERR(upper))
>   goto out1;
>  
> + err = security_inode_copy_up(dentry, _creds);
> + if (err < 0) {
> + if (new_creds)
> + put_cred(new_creds);

Why do we need a put_cred() here?

> + goto out2;
> + }
> +
> + if (new_creds)
> + old_creds = override_creds(new_creds);
> +
>   /* Can't properly set mode on creation because of the umask */
>   stat->mode &= S_IFMT;
>   err = ovl_create_real(wdir, newdentry, stat, link, NULL, true);
>   stat->mode = mode;
> +
> + if (new_creds) {
> + revert_creds(old_creds);
> + put_cred(new_creds);
> + }
> +
>   if (err)
>   goto out2;
>  
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 7ae3976..c1f95be 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -401,6 +401,15 @@
>   *   @inode contains a pointer to the inode.
>   *   @secid contains a pointer to the location where result will be saved.
>   *   In case of failure, @secid will be set to zero.
> + * @inode_copy_up:
> + *   A file is about to be copied up from lower layer to upper layer of
> + *   overlay filesystem. Security module can prepare a set of new creds
> + *   and modify as need be and return new creds. Caller will switch to
> + *   new creds temporarily to create new file and release newly allocated
> + *   creds.
> + *   @src indicates the union dentry of file that is being copied up.
> + *   @new pointer to pointer to return newly allocated creds.
> + *   Returns 0 on success or a negative error code on error.
>   *
>   * Security hooks for file operations
>   *
> @@ -1425,6 +1434,7 @@ union security_list_options {
>   int (*inode_listsecurity)(struct inode *inode, char *buffer,
>   size_t buffer_size);
>   void (*inode_getsecid)(struct inode *inode, u32 *secid);
> + int (*inode_copy_up) (struct dentry *src, struct cred **new);
>  
>   int (*file_permission)(struct file *file, int mask);
>   int (*file_alloc_security)(struct file *file);
> @@ -1696,6 +1706,7 @@ struct security_hook_heads {
>   struct list_head inode_setsecurity;
>   struct list_head inode_listsecurity;
>   struct list_head inode_getsecid;
> + struct list_head inode_copy_up;
>   struct list_head file_permission;
>   struct list_head file_alloc_security;
>   struct list_head file_free_security;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 14df373..c976d79 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -282,6 +282,7 @@ int security_inode_getsecurity(struct inode *inode, const 
> char *name, void **buf
>  int security_inode_setsecurity(struct inode *inode, const char *name, const 
> void *value, size_t size, int flags);
>  int security_inode_listsecurity(struct inode *inode, char *buffer, size_t 
> buffer_size);
>  void security_inode_getsecid(struct inode *inode, u32 *secid);
> +int security_inode_copy_up(struct dentry *src, struct cred **new);
>  int security_file_permission(struct file *file, int mask);
>  int security_file_alloc(struct file *file);
>  void security_file_free(struct file *file);
> @@ -758,6 +759,11 @@ static inline void security_inode_getsecid(struct inode 
> *inode, u32 *secid)
>   *secid = 0;
>  }
>  
> +static inline int security_inode_copy_up(struct dentry *src, struct cred 
> **new)
> +{
> + return 0;
> +}
> +
>  static inline int security_file_permission(struct file *file, int mask)
>  {
>   return 0;
> diff --git a/security/security.c b/security/security.c
> index 7095693..3d142aa 100644
> 

Re: Documenting ptrace access mode checking

2016-06-23 Thread Stephen Smalley
On 06/21/2016 05:41 AM, Michael Kerrisk (man-pages) wrote:
> Hi Jann, Stephen, et al.
> 
> Jann, since you recently committed a patch in this area, and Stephen,
> since you committed 006ebb40d3d much further back in time, I wonder if
> you might help me by reviewing the text below that I propose to add to
> the ptrace(2) man page, in order to document "ptrace access mode 
> checking" that is performed in various parts of the kernel-user-space
> interface. Of course, I welcome input from anyone else as well.
> 
> Here's the new ptrace(2) text. Any comments, technical or terminological
> fixes, other improvements, etc. are welcome.
> 
> [[
>Ptrace access mode checking
>Various parts of the kernel-user-space API (not just  ptrace(2)
>operations), require so-called "ptrace access mode permissions"
>which are gated  by  Linux  Security  Modules  (LSMs)  such  as
>SELinux,  Yama,  Smack,  or  the  default  LSM.  Prior to Linux
>2.6.27, all such checks were of a  single  type.   Since  Linux
>2.6.27, two access mode levels are distinguished:
> 
>PTRACE_MODE_READ
>   For  "read" operations or other operations that are less
>   dangerous, such as: get_robust_list(2); kcmp(2); reading
>   /proc/[pid]/auxv, /proc/[pid]/environ,or
>   /proc/[pid]/stat; or readlink(2) of  a  /proc/[pid]/ns/*
>   file.
> 
>PTRACE_MODE_ATTACH
>   For  "write"  operations,  or  other operations that are
>   moredangerous,suchas:ptraceattaching
>   (PTRACE_ATTACH)to   another   process   or   calling
>   process_vm_writev(2).   (PTRACE_MODE_ATTACH  was  effec‐
>   tively the default before Linux 2.6.27.)

That was the intent when the distinction was introduced, but it doesn't
appear to have been properly maintained, e.g. there is now a common
helper lock_trace() that is used for
/proc/pid/{stack,syscall,personality} but checks PTRACE_MODE_ATTACH, and
PTRACE_MODE_ATTACH is also used in timerslack_ns_write/show().  Likely
should review and make them consistent.  There was also some debate
about proper handling of /proc/pid/fd.  Arguably that one might belong
back in the _ATTACH camp.

> 
>Since  Linux  4.5, the above access mode checks may be combined
>(ORed) with one of the following modifiers:
> 
>PTRACE_MODE_FSCREDS
>   Use the caller's filesystem UID  and  GID  (see  creden‐
>   tials(7)) or effective capabilities for LSM checks.
> 
>PTRACE_MODE_REALCREDS
>   Use the caller's real UID and GID or permitted capabili‐
>   ties for LSM checks.  This was effectively  the  default
>   before Linux 4.5.
> 
>Because  combining  one of the credential modifiers with one of
>the aforementioned access modes is  typical,  some  macros  are
>defined in the kernel sources for the combinations:
> 
>PTRACE_MODE_READ_FSCREDS
>   Defined as PTRACE_MODE_READ | PTRACE_MODE_FSCREDS.
> 
>PTRACE_MODE_READ_REALCREDS
>   Defined as PTRACE_MODE_READ | PTRACE_MODE_REALCREDS.
> 
>PTRACE_MODE_ATTACH_FSCREDS
>   Defined as PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS.
> 
>PTRACE_MODE_ATTACH_REALCREDS
>   Defined as PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS.
> 
>One further modifier can be ORed with the access mode:
> 
>PTRACE_MODE_NOAUDIT (since Linux 3.3)
>   Don't audit this access mode check.
> 
> [I'd quite welcome some text to explain "auditing" here.]

Some ptrace access mode checks, such as checks when reading
/proc/pid/stat, merely cause the output to be filtered/sanitized rather
than an error to be returned to the caller.  In these cases, accessing
the file is not a security violation and there is no reason to generate
a security audit record.  This modifier suppresses the generation of
such an audit record for the particular access check.

> 
>The  algorithm  employed for ptrace access mode checking deter‐
>mines whether the calling process is  allowed  to  perform  the
>corresponding action on the target process, as follows:
> 
>1.  If the calling thread and the target thread are in the same
>thread group, access is always allowed.
> 
>2.  If the access mode specifies PTRACE_MODE_FSCREDS, then  for
>the  check in the next step, employ the caller's filesystem
>user ID and group ID (see credentials(7));  otherwise  (the
>access  mode  specifies  PTRACE_MODE_REALCREDS, so) use the
>caller's real user ID and group ID.
> 
>3.  Deny access if neither of the following is true:
> 
>· The real, effective, and saved-set user IDs of the target
>  match  the caller's user ID, and the real, 

Re: Documenting ptrace access mode checking

2016-06-23 Thread Stephen Smalley
On 06/21/2016 05:41 AM, Michael Kerrisk (man-pages) wrote:
> Hi Jann, Stephen, et al.
> 
> Jann, since you recently committed a patch in this area, and Stephen,
> since you committed 006ebb40d3d much further back in time, I wonder if
> you might help me by reviewing the text below that I propose to add to
> the ptrace(2) man page, in order to document "ptrace access mode 
> checking" that is performed in various parts of the kernel-user-space
> interface. Of course, I welcome input from anyone else as well.
> 
> Here's the new ptrace(2) text. Any comments, technical or terminological
> fixes, other improvements, etc. are welcome.
> 
> [[
>Ptrace access mode checking
>Various parts of the kernel-user-space API (not just  ptrace(2)
>operations), require so-called "ptrace access mode permissions"
>which are gated  by  Linux  Security  Modules  (LSMs)  such  as
>SELinux,  Yama,  Smack,  or  the  default  LSM.  Prior to Linux
>2.6.27, all such checks were of a  single  type.   Since  Linux
>2.6.27, two access mode levels are distinguished:
> 
>PTRACE_MODE_READ
>   For  "read" operations or other operations that are less
>   dangerous, such as: get_robust_list(2); kcmp(2); reading
>   /proc/[pid]/auxv, /proc/[pid]/environ,or
>   /proc/[pid]/stat; or readlink(2) of  a  /proc/[pid]/ns/*
>   file.
> 
>PTRACE_MODE_ATTACH
>   For  "write"  operations,  or  other operations that are
>   moredangerous,suchas:ptraceattaching
>   (PTRACE_ATTACH)to   another   process   or   calling
>   process_vm_writev(2).   (PTRACE_MODE_ATTACH  was  effec‐
>   tively the default before Linux 2.6.27.)

That was the intent when the distinction was introduced, but it doesn't
appear to have been properly maintained, e.g. there is now a common
helper lock_trace() that is used for
/proc/pid/{stack,syscall,personality} but checks PTRACE_MODE_ATTACH, and
PTRACE_MODE_ATTACH is also used in timerslack_ns_write/show().  Likely
should review and make them consistent.  There was also some debate
about proper handling of /proc/pid/fd.  Arguably that one might belong
back in the _ATTACH camp.

> 
>Since  Linux  4.5, the above access mode checks may be combined
>(ORed) with one of the following modifiers:
> 
>PTRACE_MODE_FSCREDS
>   Use the caller's filesystem UID  and  GID  (see  creden‐
>   tials(7)) or effective capabilities for LSM checks.
> 
>PTRACE_MODE_REALCREDS
>   Use the caller's real UID and GID or permitted capabili‐
>   ties for LSM checks.  This was effectively  the  default
>   before Linux 4.5.
> 
>Because  combining  one of the credential modifiers with one of
>the aforementioned access modes is  typical,  some  macros  are
>defined in the kernel sources for the combinations:
> 
>PTRACE_MODE_READ_FSCREDS
>   Defined as PTRACE_MODE_READ | PTRACE_MODE_FSCREDS.
> 
>PTRACE_MODE_READ_REALCREDS
>   Defined as PTRACE_MODE_READ | PTRACE_MODE_REALCREDS.
> 
>PTRACE_MODE_ATTACH_FSCREDS
>   Defined as PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS.
> 
>PTRACE_MODE_ATTACH_REALCREDS
>   Defined as PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS.
> 
>One further modifier can be ORed with the access mode:
> 
>PTRACE_MODE_NOAUDIT (since Linux 3.3)
>   Don't audit this access mode check.
> 
> [I'd quite welcome some text to explain "auditing" here.]

Some ptrace access mode checks, such as checks when reading
/proc/pid/stat, merely cause the output to be filtered/sanitized rather
than an error to be returned to the caller.  In these cases, accessing
the file is not a security violation and there is no reason to generate
a security audit record.  This modifier suppresses the generation of
such an audit record for the particular access check.

> 
>The  algorithm  employed for ptrace access mode checking deter‐
>mines whether the calling process is  allowed  to  perform  the
>corresponding action on the target process, as follows:
> 
>1.  If the calling thread and the target thread are in the same
>thread group, access is always allowed.
> 
>2.  If the access mode specifies PTRACE_MODE_FSCREDS, then  for
>the  check in the next step, employ the caller's filesystem
>user ID and group ID (see credentials(7));  otherwise  (the
>access  mode  specifies  PTRACE_MODE_REALCREDS, so) use the
>caller's real user ID and group ID.
> 
>3.  Deny access if neither of the following is true:
> 
>· The real, effective, and saved-set user IDs of the target
>  match  the caller's user ID, and the real, 

Re: [PATCH] LSM: Reorder security_capset to do access checks properly

2016-06-01 Thread Stephen Smalley
On 06/01/2016 04:30 PM, Casey Schaufler wrote:
> On 6/1/2016 1:06 PM, Stephen Smalley wrote:
>> On 06/01/2016 03:27 PM, Casey Schaufler wrote:
>>> Subject: [PATCH] LSM: Reorder security_capset to do access checks properly
>>>
>>> The security module hooks that check whether a process should
>>> be able to set a new capset are currently called after the new
>>> values are set in cap_capset(). This change reverses the order.
>>> The capability module no longer adds cap_capset to the module list.
>>> Instead, it is invoked directly by the LSM infrastructure.
>>> This isn't an approach that generalizes well.
>> Is this change necessary?  The fact that cap_capset() modifies new
>> before the other hooks are called does no harm, because if any hook
>> returns an error, then the caller returns that error and never commits
>> the new cred.  It is actually possibly beneficial for the other security
>> hooks to be called after cap_capset() so that they can adjust the new
>> values if desired (e.g. to reduce them) before they are finally committed.
> 
> The existing code will set the new credential values before the
> security modules do their checks. Even if it's harmless, it's sloppy.
> Currently there's only one caller, but with Serge's work on ns_capabilities
> I'm looking to make this safer.

It's intentional.  cap_capset() does two things: it validates the
proposed capability sets (a permission check, returning -EPERM on
failure) and if valid under its own logic, it then updates new.  But the
update does not take effect until the caller of security_capset() calls
commit_creds() and that only happens if all of the hooks pass.  By
moving cap_capset() to the end, you are reversing the order of checks
from the norm (DAC before MAC) and you aren't allowing other security
modules to vet and possibly reduce new further.  Also, it is obvious
from the patch below that doing so requires a massive hack to what was
otherwise working fine for stacking.

If you are going to insist on reversing the order, then I think you need
to split security_capset into two hooks, one which only validates and
one which sets, and only use your alternative ordering for the latter.
But that's a lot of work for no apparent gain...

> 
>>
>>> Signed-off-by: Casey Schaufler <ca...@schaufler-ca.com>
>>> ---
>>>  security/commoncap.c |  2 +-
>>>  security/security.c  | 24 ++--
>>>  2 files changed, 23 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/security/commoncap.c b/security/commoncap.c
>>> index 48071ed..f5bce18 100644
>>> --- a/security/commoncap.c
>>> +++ b/security/commoncap.c
>>> @@ -1073,7 +1073,7 @@ struct security_hook_list capability_hooks[] = {
>>> LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check),
>>> LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme),
>>> LSM_HOOK_INIT(capget, cap_capget),
>>> -   LSM_HOOK_INIT(capset, cap_capset),
>>> +   /* Carefull! Do not include cap_capset! */
>>> LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds),
>>> LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec),
>>> LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
>>> diff --git a/security/security.c b/security/security.c
>>> index 92cd1d8..1610be8 100644
>>> --- a/security/security.c
>>> +++ b/security/security.c
>>> @@ -177,8 +177,28 @@ int security_capset(struct cred *new, const struct 
>>> cred *old,
>>> const kernel_cap_t *inheritable,
>>> const kernel_cap_t *permitted)
>>>  {
>>> -   return call_int_hook(capset, 0, new, old,
>>> -   effective, inheritable, permitted);
>>> +   struct security_hook_list *hp;
>>> +   int rc;
>>> +
>>> +   /*
>>> +* Special case handling because the "new" capabilities
>>> +* should not be set until it has been determined that
>>> +* all modules approve of the change. Passing NULL pointers
>>> +* to all modules except the capabilty module as it is
>>> +* expected that only the capability modules needs the
>>> +* result pointers.
>>> +*
>>> +* cap_capset() must not be in the capability module hook list!
>>> +*/
>>> +   list_for_each_entry(hp, _hook_heads.capset, list) {
>>> +   rc = hp->hook.capset(new, old, NULL, NULL, NULL);
>>> +   if (rc != 0)
>>> +   return rc;
>>> +   }
>>> +   /*
>>> +* Call cap_capset now to update the new capset.
>>> +*/
>>> +   return cap_capset(new, old, effective, inheritable, permitted);
>>>  }
>>>  
>>>  int security_capable(const struct cred *cred, struct user_namespace *ns,
>>>
>>> ___
>>> Selinux mailing list
>>> seli...@tycho.nsa.gov
>>> To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
>>> To get help, send an email containing "help" to 
>>> selinux-requ...@tycho.nsa.gov.
>>>
>>
> 



Re: [PATCH] LSM: Reorder security_capset to do access checks properly

2016-06-01 Thread Stephen Smalley
On 06/01/2016 04:30 PM, Casey Schaufler wrote:
> On 6/1/2016 1:06 PM, Stephen Smalley wrote:
>> On 06/01/2016 03:27 PM, Casey Schaufler wrote:
>>> Subject: [PATCH] LSM: Reorder security_capset to do access checks properly
>>>
>>> The security module hooks that check whether a process should
>>> be able to set a new capset are currently called after the new
>>> values are set in cap_capset(). This change reverses the order.
>>> The capability module no longer adds cap_capset to the module list.
>>> Instead, it is invoked directly by the LSM infrastructure.
>>> This isn't an approach that generalizes well.
>> Is this change necessary?  The fact that cap_capset() modifies new
>> before the other hooks are called does no harm, because if any hook
>> returns an error, then the caller returns that error and never commits
>> the new cred.  It is actually possibly beneficial for the other security
>> hooks to be called after cap_capset() so that they can adjust the new
>> values if desired (e.g. to reduce them) before they are finally committed.
> 
> The existing code will set the new credential values before the
> security modules do their checks. Even if it's harmless, it's sloppy.
> Currently there's only one caller, but with Serge's work on ns_capabilities
> I'm looking to make this safer.

It's intentional.  cap_capset() does two things: it validates the
proposed capability sets (a permission check, returning -EPERM on
failure) and if valid under its own logic, it then updates new.  But the
update does not take effect until the caller of security_capset() calls
commit_creds() and that only happens if all of the hooks pass.  By
moving cap_capset() to the end, you are reversing the order of checks
from the norm (DAC before MAC) and you aren't allowing other security
modules to vet and possibly reduce new further.  Also, it is obvious
from the patch below that doing so requires a massive hack to what was
otherwise working fine for stacking.

If you are going to insist on reversing the order, then I think you need
to split security_capset into two hooks, one which only validates and
one which sets, and only use your alternative ordering for the latter.
But that's a lot of work for no apparent gain...

> 
>>
>>> Signed-off-by: Casey Schaufler 
>>> ---
>>>  security/commoncap.c |  2 +-
>>>  security/security.c  | 24 ++--
>>>  2 files changed, 23 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/security/commoncap.c b/security/commoncap.c
>>> index 48071ed..f5bce18 100644
>>> --- a/security/commoncap.c
>>> +++ b/security/commoncap.c
>>> @@ -1073,7 +1073,7 @@ struct security_hook_list capability_hooks[] = {
>>> LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check),
>>> LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme),
>>> LSM_HOOK_INIT(capget, cap_capget),
>>> -   LSM_HOOK_INIT(capset, cap_capset),
>>> +   /* Carefull! Do not include cap_capset! */
>>> LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds),
>>> LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec),
>>> LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
>>> diff --git a/security/security.c b/security/security.c
>>> index 92cd1d8..1610be8 100644
>>> --- a/security/security.c
>>> +++ b/security/security.c
>>> @@ -177,8 +177,28 @@ int security_capset(struct cred *new, const struct 
>>> cred *old,
>>> const kernel_cap_t *inheritable,
>>> const kernel_cap_t *permitted)
>>>  {
>>> -   return call_int_hook(capset, 0, new, old,
>>> -   effective, inheritable, permitted);
>>> +   struct security_hook_list *hp;
>>> +   int rc;
>>> +
>>> +   /*
>>> +* Special case handling because the "new" capabilities
>>> +* should not be set until it has been determined that
>>> +* all modules approve of the change. Passing NULL pointers
>>> +* to all modules except the capabilty module as it is
>>> +* expected that only the capability modules needs the
>>> +* result pointers.
>>> +*
>>> +* cap_capset() must not be in the capability module hook list!
>>> +*/
>>> +   list_for_each_entry(hp, _hook_heads.capset, list) {
>>> +   rc = hp->hook.capset(new, old, NULL, NULL, NULL);
>>> +   if (rc != 0)
>>> +   return rc;
>>> +   }
>>> +   /*
>>> +* Call cap_capset now to update the new capset.
>>> +*/
>>> +   return cap_capset(new, old, effective, inheritable, permitted);
>>>  }
>>>  
>>>  int security_capable(const struct cred *cred, struct user_namespace *ns,
>>>
>>> ___
>>> Selinux mailing list
>>> seli...@tycho.nsa.gov
>>> To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
>>> To get help, send an email containing "help" to 
>>> selinux-requ...@tycho.nsa.gov.
>>>
>>
> 



Re: [PATCH] LSM: Reorder security_capset to do access checks properly

2016-06-01 Thread Stephen Smalley
On 06/01/2016 03:27 PM, Casey Schaufler wrote:
> Subject: [PATCH] LSM: Reorder security_capset to do access checks properly
> 
> The security module hooks that check whether a process should
> be able to set a new capset are currently called after the new
> values are set in cap_capset(). This change reverses the order.
> The capability module no longer adds cap_capset to the module list.
> Instead, it is invoked directly by the LSM infrastructure.
> This isn't an approach that generalizes well.

Is this change necessary?  The fact that cap_capset() modifies new
before the other hooks are called does no harm, because if any hook
returns an error, then the caller returns that error and never commits
the new cred.  It is actually possibly beneficial for the other security
hooks to be called after cap_capset() so that they can adjust the new
values if desired (e.g. to reduce them) before they are finally committed.

> 
> Signed-off-by: Casey Schaufler 
> ---
>  security/commoncap.c |  2 +-
>  security/security.c  | 24 ++--
>  2 files changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/security/commoncap.c b/security/commoncap.c
> index 48071ed..f5bce18 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -1073,7 +1073,7 @@ struct security_hook_list capability_hooks[] = {
>   LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check),
>   LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme),
>   LSM_HOOK_INIT(capget, cap_capget),
> - LSM_HOOK_INIT(capset, cap_capset),
> + /* Carefull! Do not include cap_capset! */
>   LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds),
>   LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec),
>   LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
> diff --git a/security/security.c b/security/security.c
> index 92cd1d8..1610be8 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -177,8 +177,28 @@ int security_capset(struct cred *new, const struct cred 
> *old,
>   const kernel_cap_t *inheritable,
>   const kernel_cap_t *permitted)
>  {
> - return call_int_hook(capset, 0, new, old,
> - effective, inheritable, permitted);
> + struct security_hook_list *hp;
> + int rc;
> +
> + /*
> +  * Special case handling because the "new" capabilities
> +  * should not be set until it has been determined that
> +  * all modules approve of the change. Passing NULL pointers
> +  * to all modules except the capabilty module as it is
> +  * expected that only the capability modules needs the
> +  * result pointers.
> +  *
> +  * cap_capset() must not be in the capability module hook list!
> +  */
> + list_for_each_entry(hp, _hook_heads.capset, list) {
> + rc = hp->hook.capset(new, old, NULL, NULL, NULL);
> + if (rc != 0)
> + return rc;
> + }
> + /*
> +  * Call cap_capset now to update the new capset.
> +  */
> + return cap_capset(new, old, effective, inheritable, permitted);
>  }
>  
>  int security_capable(const struct cred *cred, struct user_namespace *ns,
> 
> ___
> Selinux mailing list
> seli...@tycho.nsa.gov
> To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
> To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
> 



Re: [PATCH] LSM: Reorder security_capset to do access checks properly

2016-06-01 Thread Stephen Smalley
On 06/01/2016 03:27 PM, Casey Schaufler wrote:
> Subject: [PATCH] LSM: Reorder security_capset to do access checks properly
> 
> The security module hooks that check whether a process should
> be able to set a new capset are currently called after the new
> values are set in cap_capset(). This change reverses the order.
> The capability module no longer adds cap_capset to the module list.
> Instead, it is invoked directly by the LSM infrastructure.
> This isn't an approach that generalizes well.

Is this change necessary?  The fact that cap_capset() modifies new
before the other hooks are called does no harm, because if any hook
returns an error, then the caller returns that error and never commits
the new cred.  It is actually possibly beneficial for the other security
hooks to be called after cap_capset() so that they can adjust the new
values if desired (e.g. to reduce them) before they are finally committed.

> 
> Signed-off-by: Casey Schaufler 
> ---
>  security/commoncap.c |  2 +-
>  security/security.c  | 24 ++--
>  2 files changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/security/commoncap.c b/security/commoncap.c
> index 48071ed..f5bce18 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -1073,7 +1073,7 @@ struct security_hook_list capability_hooks[] = {
>   LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check),
>   LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme),
>   LSM_HOOK_INIT(capget, cap_capget),
> - LSM_HOOK_INIT(capset, cap_capset),
> + /* Carefull! Do not include cap_capset! */
>   LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds),
>   LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec),
>   LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
> diff --git a/security/security.c b/security/security.c
> index 92cd1d8..1610be8 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -177,8 +177,28 @@ int security_capset(struct cred *new, const struct cred 
> *old,
>   const kernel_cap_t *inheritable,
>   const kernel_cap_t *permitted)
>  {
> - return call_int_hook(capset, 0, new, old,
> - effective, inheritable, permitted);
> + struct security_hook_list *hp;
> + int rc;
> +
> + /*
> +  * Special case handling because the "new" capabilities
> +  * should not be set until it has been determined that
> +  * all modules approve of the change. Passing NULL pointers
> +  * to all modules except the capabilty module as it is
> +  * expected that only the capability modules needs the
> +  * result pointers.
> +  *
> +  * cap_capset() must not be in the capability module hook list!
> +  */
> + list_for_each_entry(hp, _hook_heads.capset, list) {
> + rc = hp->hook.capset(new, old, NULL, NULL, NULL);
> + if (rc != 0)
> + return rc;
> + }
> + /*
> +  * Call cap_capset now to update the new capset.
> +  */
> + return cap_capset(new, old, effective, inheritable, permitted);
>  }
>  
>  int security_capable(const struct cred *cred, struct user_namespace *ns,
> 
> ___
> Selinux mailing list
> seli...@tycho.nsa.gov
> To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
> To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
> 



Re: PROBLEM: Resume form hibernate broken by setting NX on gap

2016-05-20 Thread Stephen Smalley
On 05/20/2016 07:34 AM, Rafael J. Wysocki wrote:
> On Fri, May 20, 2016 at 9:15 AM, Ingo Molnar  wrote:
>>
>> * Logan Gunthorpe  wrote:
>>
>>> Hi,
>>>
>>> I have been working on a bug that causes my laptop to freeze during
>>> resume from hibernation. I did a bisect to find the offending commit:
>>>
>>> [ab76f7b4ab] x86/mm: Set NX on gap between __ex_table and rodata
>>>
>>> There is more information in the bugzilla report [1] that
>>> I've been working on but I will summarize things below.
>>>
>>> I've experienced intermittent but reproducible freezes when resuming
>>> from hibernation since about kernel version 3.19. The freeze was
>>> significantly more reproducible when a few applications were loaded
>>> before hibernation and would largely not happen if hibernated
>>> immediately after booting to a desktop. I did some tracing work to find
>>> that the kernel gets as far as the resume_image call in
>>> swsusp_arch_resume and I could not find any response from the image
>>> kernel when I hit the bug. I also did testing that seemed to rule out
>>> this being caused by a problematic driver.
>>>
>>> I did a successful bisect between 3.18 and 3.19 which found a bug in
>>> commit f5b2831d6 that was then later fixed by commit 55696b1f66 in 4.4.
>>> Then, I did a second bisect with a ported version of the fix to the
>>> first bug and found commit ab76f7b4ab in 4.3 to also break hibernation
>>> with what appears to be the exact same symptoms. Reverting that commit
>>> in recent kernels up to and including 4.6 fixes the issue and restores
>>> reliable hibernation. However, it's not at all clear to me why that
>>> commit would cause this issue or how to fix the issue without reverting.
>>
>> I've attached that commit below and also Cc:-ed a few more people who might 
>> have
>> an idea about why this regressed. Worst-case we'll have to revert it.
> 
> Without looking deep into mm, my theory would be that after this patch
> the final jump from the boot kernel to the image kernel's trampoline
> code during resume may crash the kernel if the trampoline page turns
> out to be NX in the boot kernel (it has to be executable in both the
> boot and the image kernels).

So, pardon my ignorance, but where is this trampoline page placed in
kernel memory?


Re: PROBLEM: Resume form hibernate broken by setting NX on gap

2016-05-20 Thread Stephen Smalley
On 05/20/2016 07:34 AM, Rafael J. Wysocki wrote:
> On Fri, May 20, 2016 at 9:15 AM, Ingo Molnar  wrote:
>>
>> * Logan Gunthorpe  wrote:
>>
>>> Hi,
>>>
>>> I have been working on a bug that causes my laptop to freeze during
>>> resume from hibernation. I did a bisect to find the offending commit:
>>>
>>> [ab76f7b4ab] x86/mm: Set NX on gap between __ex_table and rodata
>>>
>>> There is more information in the bugzilla report [1] that
>>> I've been working on but I will summarize things below.
>>>
>>> I've experienced intermittent but reproducible freezes when resuming
>>> from hibernation since about kernel version 3.19. The freeze was
>>> significantly more reproducible when a few applications were loaded
>>> before hibernation and would largely not happen if hibernated
>>> immediately after booting to a desktop. I did some tracing work to find
>>> that the kernel gets as far as the resume_image call in
>>> swsusp_arch_resume and I could not find any response from the image
>>> kernel when I hit the bug. I also did testing that seemed to rule out
>>> this being caused by a problematic driver.
>>>
>>> I did a successful bisect between 3.18 and 3.19 which found a bug in
>>> commit f5b2831d6 that was then later fixed by commit 55696b1f66 in 4.4.
>>> Then, I did a second bisect with a ported version of the fix to the
>>> first bug and found commit ab76f7b4ab in 4.3 to also break hibernation
>>> with what appears to be the exact same symptoms. Reverting that commit
>>> in recent kernels up to and including 4.6 fixes the issue and restores
>>> reliable hibernation. However, it's not at all clear to me why that
>>> commit would cause this issue or how to fix the issue without reverting.
>>
>> I've attached that commit below and also Cc:-ed a few more people who might 
>> have
>> an idea about why this regressed. Worst-case we'll have to revert it.
> 
> Without looking deep into mm, my theory would be that after this patch
> the final jump from the boot kernel to the image kernel's trampoline
> code during resume may crash the kernel if the trampoline page turns
> out to be NX in the boot kernel (it has to be executable in both the
> boot and the image kernels).

So, pardon my ignorance, but where is this trampoline page placed in
kernel memory?


Re: Linux 4.4 MW: Boot under Xen fails with CONFIG_DEBUG_WX enabled: RIP: ptdump_walk_pgd_level_core

2015-11-04 Thread Stephen Smalley

On 11/04/2015 01:28 PM, Sander Eikelenboom wrote:

On 2015-11-04 16:52, Stephen Smalley wrote:

On 11/04/2015 06:55 AM, Sander Eikelenboom wrote:

Hi All,

I just tried to boot with the current linus mergewindow tree under Xen.
It fails with a kernel panic at boot with the new "CONFIG_DEBUG_WX"
option enabled.
Disabling it makes the kernel boot fine.

The splat:
[   18.424241] Freeing unused kernel memory: 1104K (822fc000 -
8241)
[   18.430314] Write protecting the kernel read-only data: 18432k
[   18.441054] Freeing unused kernel memory: 1144K (880001ae2000 -
880001c0)
[   18.447966] Freeing unused kernel memory: 1560K (88000207a000 -
88000220)
[   18.453947] BUG: unable to handle kernel paging request at
88055c883000
[   18.459943] IP: []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.465847] PGD 2212067 PUD 0
[   18.471564] Oops:  [#1] SMP
[   18.477248] Modules linked in:
[   18.482918] CPU: 2 PID: 1 Comm: swapper/0 Not tainted
4.3.0-mw-20151104-linus-doflr+ #1
[   18.488804] Hardware name: MSI MS-7640/890FXA-GD70 (MS-7640)  , BIOS
V1.8B1 09/13/2010
[   18.494778] task: 880059b9 ti: 880059b98000 task.ti:
880059b98000
[   18.500852] RIP: e030:[]  []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.507102] RSP: e02b:880059b9be48  EFLAGS: 00010296
[   18.513351] RAX: 88055c883000 RBX: 81ae2000 RCX:
8800
[   18.519733] RDX: 0067 RSI: 880059b9be98 RDI:
88001000
[   18.526129] RBP: 880059b9bf00 R08:  R09:

[   18.532522] R10: 88005fd0e790 R11: 0001 R12:
88008000
[   18.538891] R13: cfff R14: 880059b9be98 R15:

[   18.545247] FS:  () GS:88005f68()
knlGS:
[   18.551708] CS:  e033 DS:  ES:  CR0: 8005003b
[   18.558153] CR2: 88055c883000 CR3: 02211000 CR4:
0660
[   18.564686] Stack:
[   18.571106]  000159b9be50 82211000 88055c884000
0800
[   18.577704]  8000 88055c883000 0007
88005fd0e790
[   18.584291]  880059b9bed8 81156ace 0001

[   18.590916] Call Trace:
[   18.597458]  [] ? free_reserved_area+0x11e/0x120
[   18.604180]  []
ptdump_walk_pgd_level_checkwx+0x12/0x20
[   18.611014]  [] mark_rodata_ro+0xe9/0xf0
[   18.617819]  [] ? rest_init+0x80/0x80
[   18.624512]  [] kernel_init+0x18/0xe0
[   18.631095]  [] ret_from_fork+0x3f/0x70
[   18.637650]  [] ? rest_init+0x80/0x80
[   18.644178] Code: 70 ff ff ff 48 3b 85 58 ff ff ff 0f 84 c0 fe ff ff
48 8b 85 68 ff ff ff 48 c1 e0 10 48 c1 f8 10 48 89 45 b0 48 8b 85 70 ff
ff ff <48> 8b 38 48 85 ff 0f 85 4e ff ff ff b9 02 00 00 00 31 d2 4c 89
[   18.658246] RIP  []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.665211]  RSP 
[   18.672073] CR2: 88055c883000
[   18.678852] ---[ end trace d84e34461c40637a ]---
[   18.685641] Kernel panic - not syncing: Attempted to kill init!
exitcode=0x0009
[   18.685641]
[   18.699520] Kernel Offset: disable



What's your .config?  Does cat /sys/kernel/debug/kernel_page_tables
produce a similar fault even with CONFIG_DEBUG_WX=n?


.config is attached

Hmm that sysfs file doesn't seem to exist then:
# cat /sys/kernel/debug/kernel_page_tables
cat: /sys/kernel/debug/kernel_page_tables: No such file or directory


Needs CONFIG_X86_PTDUMP=y.
Also assumes you have debugfs mounted there.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Linux 4.4 MW: Boot under Xen fails with CONFIG_DEBUG_WX enabled: RIP: ptdump_walk_pgd_level_core

2015-11-04 Thread Stephen Smalley

On 11/04/2015 06:55 AM, Sander Eikelenboom wrote:

Hi All,

I just tried to boot with the current linus mergewindow tree under Xen.
It fails with a kernel panic at boot with the new "CONFIG_DEBUG_WX"
option enabled.
Disabling it makes the kernel boot fine.

The splat:
[   18.424241] Freeing unused kernel memory: 1104K (822fc000 -
8241)
[   18.430314] Write protecting the kernel read-only data: 18432k
[   18.441054] Freeing unused kernel memory: 1144K (880001ae2000 -
880001c0)
[   18.447966] Freeing unused kernel memory: 1560K (88000207a000 -
88000220)
[   18.453947] BUG: unable to handle kernel paging request at
88055c883000
[   18.459943] IP: []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.465847] PGD 2212067 PUD 0
[   18.471564] Oops:  [#1] SMP
[   18.477248] Modules linked in:
[   18.482918] CPU: 2 PID: 1 Comm: swapper/0 Not tainted
4.3.0-mw-20151104-linus-doflr+ #1
[   18.488804] Hardware name: MSI MS-7640/890FXA-GD70 (MS-7640)  , BIOS
V1.8B1 09/13/2010
[   18.494778] task: 880059b9 ti: 880059b98000 task.ti:
880059b98000
[   18.500852] RIP: e030:[]  []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.507102] RSP: e02b:880059b9be48  EFLAGS: 00010296
[   18.513351] RAX: 88055c883000 RBX: 81ae2000 RCX:
8800
[   18.519733] RDX: 0067 RSI: 880059b9be98 RDI:
88001000
[   18.526129] RBP: 880059b9bf00 R08:  R09:

[   18.532522] R10: 88005fd0e790 R11: 0001 R12:
88008000
[   18.538891] R13: cfff R14: 880059b9be98 R15:

[   18.545247] FS:  () GS:88005f68()
knlGS:
[   18.551708] CS:  e033 DS:  ES:  CR0: 8005003b
[   18.558153] CR2: 88055c883000 CR3: 02211000 CR4:
0660
[   18.564686] Stack:
[   18.571106]  000159b9be50 82211000 88055c884000
0800
[   18.577704]  8000 88055c883000 0007
88005fd0e790
[   18.584291]  880059b9bed8 81156ace 0001

[   18.590916] Call Trace:
[   18.597458]  [] ? free_reserved_area+0x11e/0x120
[   18.604180]  []
ptdump_walk_pgd_level_checkwx+0x12/0x20
[   18.611014]  [] mark_rodata_ro+0xe9/0xf0
[   18.617819]  [] ? rest_init+0x80/0x80
[   18.624512]  [] kernel_init+0x18/0xe0
[   18.631095]  [] ret_from_fork+0x3f/0x70
[   18.637650]  [] ? rest_init+0x80/0x80
[   18.644178] Code: 70 ff ff ff 48 3b 85 58 ff ff ff 0f 84 c0 fe ff ff
48 8b 85 68 ff ff ff 48 c1 e0 10 48 c1 f8 10 48 89 45 b0 48 8b 85 70 ff
ff ff <48> 8b 38 48 85 ff 0f 85 4e ff ff ff b9 02 00 00 00 31 d2 4c 89
[   18.658246] RIP  []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.665211]  RSP 
[   18.672073] CR2: 88055c883000
[   18.678852] ---[ end trace d84e34461c40637a ]---
[   18.685641] Kernel panic - not syncing: Attempted to kill init!
exitcode=0x0009
[   18.685641]
[   18.699520] Kernel Offset: disable



What's your .config?  Does cat /sys/kernel/debug/kernel_page_tables 
produce a similar fault even with CONFIG_DEBUG_WX=n?

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Linux 4.4 MW: Boot under Xen fails with CONFIG_DEBUG_WX enabled: RIP: ptdump_walk_pgd_level_core

2015-11-04 Thread Stephen Smalley

On 11/04/2015 06:55 AM, Sander Eikelenboom wrote:

Hi All,

I just tried to boot with the current linus mergewindow tree under Xen.
It fails with a kernel panic at boot with the new "CONFIG_DEBUG_WX"
option enabled.
Disabling it makes the kernel boot fine.

The splat:
[   18.424241] Freeing unused kernel memory: 1104K (822fc000 -
8241)
[   18.430314] Write protecting the kernel read-only data: 18432k
[   18.441054] Freeing unused kernel memory: 1144K (880001ae2000 -
880001c0)
[   18.447966] Freeing unused kernel memory: 1560K (88000207a000 -
88000220)
[   18.453947] BUG: unable to handle kernel paging request at
88055c883000
[   18.459943] IP: []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.465847] PGD 2212067 PUD 0
[   18.471564] Oops:  [#1] SMP
[   18.477248] Modules linked in:
[   18.482918] CPU: 2 PID: 1 Comm: swapper/0 Not tainted
4.3.0-mw-20151104-linus-doflr+ #1
[   18.488804] Hardware name: MSI MS-7640/890FXA-GD70 (MS-7640)  , BIOS
V1.8B1 09/13/2010
[   18.494778] task: 880059b9 ti: 880059b98000 task.ti:
880059b98000
[   18.500852] RIP: e030:[]  []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.507102] RSP: e02b:880059b9be48  EFLAGS: 00010296
[   18.513351] RAX: 88055c883000 RBX: 81ae2000 RCX:
8800
[   18.519733] RDX: 0067 RSI: 880059b9be98 RDI:
88001000
[   18.526129] RBP: 880059b9bf00 R08:  R09:

[   18.532522] R10: 88005fd0e790 R11: 0001 R12:
88008000
[   18.538891] R13: cfff R14: 880059b9be98 R15:

[   18.545247] FS:  () GS:88005f68()
knlGS:
[   18.551708] CS:  e033 DS:  ES:  CR0: 8005003b
[   18.558153] CR2: 88055c883000 CR3: 02211000 CR4:
0660
[   18.564686] Stack:
[   18.571106]  000159b9be50 82211000 88055c884000
0800
[   18.577704]  8000 88055c883000 0007
88005fd0e790
[   18.584291]  880059b9bed8 81156ace 0001

[   18.590916] Call Trace:
[   18.597458]  [] ? free_reserved_area+0x11e/0x120
[   18.604180]  []
ptdump_walk_pgd_level_checkwx+0x12/0x20
[   18.611014]  [] mark_rodata_ro+0xe9/0xf0
[   18.617819]  [] ? rest_init+0x80/0x80
[   18.624512]  [] kernel_init+0x18/0xe0
[   18.631095]  [] ret_from_fork+0x3f/0x70
[   18.637650]  [] ? rest_init+0x80/0x80
[   18.644178] Code: 70 ff ff ff 48 3b 85 58 ff ff ff 0f 84 c0 fe ff ff
48 8b 85 68 ff ff ff 48 c1 e0 10 48 c1 f8 10 48 89 45 b0 48 8b 85 70 ff
ff ff <48> 8b 38 48 85 ff 0f 85 4e ff ff ff b9 02 00 00 00 31 d2 4c 89
[   18.658246] RIP  []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.665211]  RSP 
[   18.672073] CR2: 88055c883000
[   18.678852] ---[ end trace d84e34461c40637a ]---
[   18.685641] Kernel panic - not syncing: Attempted to kill init!
exitcode=0x0009
[   18.685641]
[   18.699520] Kernel Offset: disable



What's your .config?  Does cat /sys/kernel/debug/kernel_page_tables 
produce a similar fault even with CONFIG_DEBUG_WX=n?

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Linux 4.4 MW: Boot under Xen fails with CONFIG_DEBUG_WX enabled: RIP: ptdump_walk_pgd_level_core

2015-11-04 Thread Stephen Smalley

On 11/04/2015 01:28 PM, Sander Eikelenboom wrote:

On 2015-11-04 16:52, Stephen Smalley wrote:

On 11/04/2015 06:55 AM, Sander Eikelenboom wrote:

Hi All,

I just tried to boot with the current linus mergewindow tree under Xen.
It fails with a kernel panic at boot with the new "CONFIG_DEBUG_WX"
option enabled.
Disabling it makes the kernel boot fine.

The splat:
[   18.424241] Freeing unused kernel memory: 1104K (822fc000 -
8241)
[   18.430314] Write protecting the kernel read-only data: 18432k
[   18.441054] Freeing unused kernel memory: 1144K (880001ae2000 -
880001c0)
[   18.447966] Freeing unused kernel memory: 1560K (88000207a000 -
88000220)
[   18.453947] BUG: unable to handle kernel paging request at
88055c883000
[   18.459943] IP: []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.465847] PGD 2212067 PUD 0
[   18.471564] Oops:  [#1] SMP
[   18.477248] Modules linked in:
[   18.482918] CPU: 2 PID: 1 Comm: swapper/0 Not tainted
4.3.0-mw-20151104-linus-doflr+ #1
[   18.488804] Hardware name: MSI MS-7640/890FXA-GD70 (MS-7640)  , BIOS
V1.8B1 09/13/2010
[   18.494778] task: 880059b9 ti: 880059b98000 task.ti:
880059b98000
[   18.500852] RIP: e030:[]  []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.507102] RSP: e02b:880059b9be48  EFLAGS: 00010296
[   18.513351] RAX: 88055c883000 RBX: 81ae2000 RCX:
8800
[   18.519733] RDX: 0067 RSI: 880059b9be98 RDI:
88001000
[   18.526129] RBP: 880059b9bf00 R08:  R09:

[   18.532522] R10: 88005fd0e790 R11: 0001 R12:
88008000
[   18.538891] R13: cfff R14: 880059b9be98 R15:

[   18.545247] FS:  () GS:88005f68()
knlGS:
[   18.551708] CS:  e033 DS:  ES:  CR0: 8005003b
[   18.558153] CR2: 88055c883000 CR3: 02211000 CR4:
0660
[   18.564686] Stack:
[   18.571106]  000159b9be50 82211000 88055c884000
0800
[   18.577704]  8000 88055c883000 0007
88005fd0e790
[   18.584291]  880059b9bed8 81156ace 0001

[   18.590916] Call Trace:
[   18.597458]  [] ? free_reserved_area+0x11e/0x120
[   18.604180]  []
ptdump_walk_pgd_level_checkwx+0x12/0x20
[   18.611014]  [] mark_rodata_ro+0xe9/0xf0
[   18.617819]  [] ? rest_init+0x80/0x80
[   18.624512]  [] kernel_init+0x18/0xe0
[   18.631095]  [] ret_from_fork+0x3f/0x70
[   18.637650]  [] ? rest_init+0x80/0x80
[   18.644178] Code: 70 ff ff ff 48 3b 85 58 ff ff ff 0f 84 c0 fe ff ff
48 8b 85 68 ff ff ff 48 c1 e0 10 48 c1 f8 10 48 89 45 b0 48 8b 85 70 ff
ff ff <48> 8b 38 48 85 ff 0f 85 4e ff ff ff b9 02 00 00 00 31 d2 4c 89
[   18.658246] RIP  []
ptdump_walk_pgd_level_core+0x20e/0x440
[   18.665211]  RSP 
[   18.672073] CR2: 88055c883000
[   18.678852] ---[ end trace d84e34461c40637a ]---
[   18.685641] Kernel panic - not syncing: Attempted to kill init!
exitcode=0x0009
[   18.685641]
[   18.699520] Kernel Offset: disable



What's your .config?  Does cat /sys/kernel/debug/kernel_page_tables
produce a similar fault even with CONFIG_DEBUG_WX=n?


.config is attached

Hmm that sysfs file doesn't seem to exist then:
# cat /sys/kernel/debug/kernel_page_tables
cat: /sys/kernel/debug/kernel_page_tables: No such file or directory


Needs CONFIG_X86_PTDUMP=y.
Also assumes you have debugfs mounted there.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] lkdtm: fix ACCESS_USERSPACE test

2015-10-29 Thread Stephen Smalley

On 10/27/2015 08:12 PM, Greg KH wrote:

On Tue, Oct 27, 2015 at 04:47:53PM -0400, Stephen Smalley wrote:

Add a copy_to_user() call to the ACCESS_USERSPACE test
prior to attempting direct dereferencing of the user
address to ensure the page is present.  Otherwise,
a fault occurs on arm kernels even prior to the introduction
of CONFIG_CPU_SW_DOMAIN_PAN, and there is no difference in
behavior for CONFIG_CPU_SW_DOMAIN_PAN=n vs CONFIG_CPU_SW_DOMAIN_PAN=y.

Before this change, for any value of CONFIG_CPU_SW_DOMAIN_PAN:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6fe8000
Unable to handle kernel paging request at virtual address b6fe8000

After this change, for CONFIG_CPU_SW_DOMAIN_PAN=n:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6efc000
lkdtm: attempting bad write at b6efc000

After this change, for CONFIG_CPU_SW_DOMAIN_PAN=y:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6f7d000
Unhandled fault: page domain fault (0x01b) at 0xb6f7d000
...

Signed-off-by: Stephen Smalley 
---
 drivers/misc/lkdtm.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)


Should this also be applied to older kernels (i.e. a stable fix)?


I don't think it qualifies (only a fix for a kernel crash test), but will defer 
to Kees.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] lkdtm: fix ACCESS_USERSPACE test

2015-10-29 Thread Stephen Smalley

On 10/27/2015 08:12 PM, Greg KH wrote:

On Tue, Oct 27, 2015 at 04:47:53PM -0400, Stephen Smalley wrote:

Add a copy_to_user() call to the ACCESS_USERSPACE test
prior to attempting direct dereferencing of the user
address to ensure the page is present.  Otherwise,
a fault occurs on arm kernels even prior to the introduction
of CONFIG_CPU_SW_DOMAIN_PAN, and there is no difference in
behavior for CONFIG_CPU_SW_DOMAIN_PAN=n vs CONFIG_CPU_SW_DOMAIN_PAN=y.

Before this change, for any value of CONFIG_CPU_SW_DOMAIN_PAN:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6fe8000
Unable to handle kernel paging request at virtual address b6fe8000

After this change, for CONFIG_CPU_SW_DOMAIN_PAN=n:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6efc000
lkdtm: attempting bad write at b6efc000

After this change, for CONFIG_CPU_SW_DOMAIN_PAN=y:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6f7d000
Unhandled fault: page domain fault (0x01b) at 0xb6f7d000
...

Signed-off-by: Stephen Smalley <s...@tycho.nsa.gov>
---
 drivers/misc/lkdtm.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)


Should this also be applied to older kernels (i.e. a stable fix)?


I don't think it qualifies (only a fix for a kernel crash test), but will defer 
to Kees.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] lkdtm: fix ACCESS_USERSPACE test

2015-10-27 Thread Stephen Smalley
Add a copy_to_user() call to the ACCESS_USERSPACE test
prior to attempting direct dereferencing of the user
address to ensure the page is present.  Otherwise,
a fault occurs on arm kernels even prior to the introduction
of CONFIG_CPU_SW_DOMAIN_PAN, and there is no difference in
behavior for CONFIG_CPU_SW_DOMAIN_PAN=n vs CONFIG_CPU_SW_DOMAIN_PAN=y.

Before this change, for any value of CONFIG_CPU_SW_DOMAIN_PAN:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6fe8000
Unable to handle kernel paging request at virtual address b6fe8000

After this change, for CONFIG_CPU_SW_DOMAIN_PAN=n:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6efc000
lkdtm: attempting bad write at b6efc000

After this change, for CONFIG_CPU_SW_DOMAIN_PAN=y:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6f7d000
Unhandled fault: page domain fault (0x01b) at 0xb6f7d000
...

Signed-off-by: Stephen Smalley 
---
 drivers/misc/lkdtm.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index b5abe34..11fdadc 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -472,7 +472,7 @@ static void lkdtm_do_action(enum ctype which)
break;
}
case CT_ACCESS_USERSPACE: {
-   unsigned long user_addr, tmp;
+   unsigned long user_addr, tmp = 0;
unsigned long *ptr;
 
user_addr = vm_mmap(NULL, 0, PAGE_SIZE,
@@ -483,6 +483,12 @@ static void lkdtm_do_action(enum ctype which)
return;
}
 
+   if (copy_to_user((void __user *)user_addr, , sizeof(tmp))) {
+   pr_warn("copy_to_user failed\n");
+   vm_munmap(user_addr, PAGE_SIZE);
+   return;
+   }
+
ptr = (unsigned long *)user_addr;
 
pr_info("attempting bad read at %p\n", ptr);
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] lkdtm: fix ACCESS_USERSPACE test

2015-10-27 Thread Stephen Smalley
Add a copy_to_user() call to the ACCESS_USERSPACE test
prior to attempting direct dereferencing of the user
address to ensure the page is present.  Otherwise,
a fault occurs on arm kernels even prior to the introduction
of CONFIG_CPU_SW_DOMAIN_PAN, and there is no difference in
behavior for CONFIG_CPU_SW_DOMAIN_PAN=n vs CONFIG_CPU_SW_DOMAIN_PAN=y.

Before this change, for any value of CONFIG_CPU_SW_DOMAIN_PAN:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6fe8000
Unable to handle kernel paging request at virtual address b6fe8000

After this change, for CONFIG_CPU_SW_DOMAIN_PAN=n:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6efc000
lkdtm: attempting bad write at b6efc000

After this change, for CONFIG_CPU_SW_DOMAIN_PAN=y:
lkdtm: Performing direct entry ACCESS_USERSPACE
lkdtm: attempting bad read at b6f7d000
Unhandled fault: page domain fault (0x01b) at 0xb6f7d000
...

Signed-off-by: Stephen Smalley <s...@tycho.nsa.gov>
---
 drivers/misc/lkdtm.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index b5abe34..11fdadc 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -472,7 +472,7 @@ static void lkdtm_do_action(enum ctype which)
break;
}
case CT_ACCESS_USERSPACE: {
-   unsigned long user_addr, tmp;
+   unsigned long user_addr, tmp = 0;
unsigned long *ptr;
 
user_addr = vm_mmap(NULL, 0, PAGE_SIZE,
@@ -483,6 +483,12 @@ static void lkdtm_do_action(enum ctype which)
return;
}
 
+   if (copy_to_user((void __user *)user_addr, , sizeof(tmp))) {
+   pr_warn("copy_to_user failed\n");
+   vm_munmap(user_addr, PAGE_SIZE);
+   return;
+   }
+
ptr = (unsigned long *)user_addr;
 
pr_info("attempting bad read at %p\n", ptr);
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 5/7] selinux: Add support for unprivileged mounts from user namespaces

2015-10-13 Thread Stephen Smalley

On 10/13/2015 01:04 PM, Seth Forshee wrote:

Security labels from unprivileged mounts in user namespaces must
be ignored. Force superblocks from user namespaces whose labeling
behavior is to use xattrs to use mountpoint labeling instead.
For the mountpoint label, default to converting the current task
context into a form suitable for file objects, but also allow the
policy writer to specify a different label through policy
transition rules.

Pieced together from code snippets provided by Stephen Smalley.

Signed-off-by: Seth Forshee 


Acked-by: Stephen Smalley 


---
  security/selinux/hooks.c | 23 +++
  1 file changed, 23 insertions(+)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index de05207eb665..09be1dc21e58 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -756,6 +756,28 @@ static int selinux_set_mnt_opts(struct super_block *sb,
goto out;
}
}
+
+   /*
+* If this is a user namespace mount, no contexts are allowed
+* on the command line and security labels must be ignored.
+*/
+   if (sb->s_user_ns != _user_ns) {
+   if (context_sid || fscontext_sid || rootcontext_sid ||
+   defcontext_sid) {
+   rc = -EACCES;
+   goto out;
+   }
+   if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
+   sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
+   rc = security_transition_sid(current_sid(), 
current_sid(),
+SECCLASS_FILE, NULL,
+>mntpoint_sid);
+   if (rc)
+   goto out;
+   }
+   goto out_set_opts;
+   }
+
/* sets the context of the superblock for the fs being mounted. */
if (fscontext_sid) {
rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred);
@@ -824,6 +846,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
sbsec->def_sid = defcontext_sid;
}

+out_set_opts:
rc = sb_finish_set_opts(sb);
  out:
mutex_unlock(>lock);



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


<    1   2   3   4   5   6   7   8   9   10   >