Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1442515 > unrolled thread
| Started by | Vivek Goyal <vgoyal@redhat.com> |
|---|---|
| First post | 2016-07-13 16:50 +0200 |
| Last post | 2016-07-22 17:40 +0200 |
| Articles | 11 — 5 participants |
Back to article view | Back to linux.kernel
[RFC PATCH 0/9][V3] Overlayfs SELinux Support Vivek Goyal <vgoyal@redhat.com> - 2016-07-13 16:50 +0200
[PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files Vivek Goyal <vgoyal@redhat.com> - 2016-07-13 16:50 +0200
Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files Stephen Smalley <sds@tycho.nsa.gov> - 2016-07-13 17:10 +0200
Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files Stephen Smalley <sds@tycho.nsa.gov> - 2016-07-13 17:10 +0200
Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files Stephen Smalley <sds@tycho.nsa.gov> - 2016-07-14 16:30 +0200
[PATCH 9/9] overlayfs: Append MAY_READ when diluting write checks Vivek Goyal <vgoyal@redhat.com> - 2016-07-13 16:50 +0200
Re: [PATCH 9/9] overlayfs: Append MAY_READ when diluting write checks Miklos Szeredi <miklos@szeredi.hu> - 2016-07-14 08:50 +0200
Re: [RFC PATCH 0/9][V3] Overlayfs SELinux Support Paul Moore <paul@paul-moore.com> - 2016-07-21 23:20 +0200
Re: [RFC PATCH 0/9][V3] Overlayfs SELinux Support James Morris <jmorris@namei.org> - 2016-07-22 01:10 +0200
Re: [RFC PATCH 0/9][V3] Overlayfs SELinux Support Miklos Szeredi <miklos@szeredi.hu> - 2016-07-22 09:10 +0200
Re: [RFC PATCH 0/9][V3] Overlayfs SELinux Support Paul Moore <paul@paul-moore.com> - 2016-07-22 17:40 +0200
| From | Vivek Goyal <vgoyal@redhat.com> |
|---|---|
| Date | 2016-07-13 16:50 +0200 |
| Subject | [RFC PATCH 0/9][V3] Overlayfs SELinux Support |
| Message-ID | <rUtE5-4my-5@gated-at.bofh.it> |
Hi All,
Please find attached the V3 of patches. Changes since V2 are as follows.
- Fixed the build issue with CONFIG_SECURITY=n.
- Dan Walsh was writing more tests for selinux-testsuite and noted couple
of issues. I have fixed those issues and added two more patches in series.
1. We are resetting MAY_WRITE check for lower inode assuming file will
be coiped up. But this is not true for special_file() as these files
are not copied up. So checks should not be reset in case of special
file.
2. We are resetting MAY_WRITE check for lower inode assuming file will
be copied up. But this also should mean that mounter has permission
to MAY_READ lower file for copy up to succeed. So add MAY_READ
check while resetting MAY_WRITE.
Original description of patches follows.
Following are RFC patches to support SELinux with overlayfs. I started
with David Howells's latest posting on this topic and started modifying
patches. These patches apply on top of overlayfs-next branch of miklos
vfs git tree.
git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git overlayfs-next
These patches can be pulled from my branch too.
https://github.com/rhvgoyal/linux/commits/overlayfs-selinux-mounter-next
Thanks to Dan Walsh, Stephen Smalley and Miklos Szeredi for numerous
conversation and ideas in helping figuring out what one reasonable
implementation might look like.
Dan Walsh has been writing tests for selinux overlayfs in selinux-testsuite.
These patches pass those tests now
https://github.com/rhatdan/selinux-testsuite/commits/master
Posting these patches for review and comments.
These patches introduce 3 new security hooks.
- security_inode_copy_up(), is called when a file is copied up. This hook
prepares a new set of cred which is used for copy up operation. And
new set of creds are prepared so that ->create_sid can be set appropriately
and newly created file is labeled properly.
When a file is copied up, label of lower file is retained except for the
case of context= mount where new file gets the label from context= option.
- security_inode_copy_up_xattr(), is called when xattrs of a file are
being copied up. Before this we already called security_inode_copy_up()
and created new file and copied up data. That means file already got
labeled properly and there is no need to take SELINUX xattr of lower
file and overwrite the upper file xattr. So this hook is used to avoid
copying up of SELINUX xattr.
- dentry_create_files_as(), is called when a new file is about to be created.
This hook determines what the label of the file should be if task had
created that file in upper/ and sets create_sid accordingly in the passed
in creds.
Normal transition rules don't work for the case of context mounts as
underlying file system is not aware of context option which only overlay
layer is aware of. For non-context mounts, creation can happen in work/
dir first and then file might be renamed into upper/, and it might get
label based on work/ dir. So this hooks helps avoiding all these issues.
When a new file is created in upper/, it gets its label based on transition
rules. For the case of context mount, it gets the label from context=
option.
Any feedback is welcome.
Vivek Goyal (9):
security, overlayfs: provide copy up security hook for unioned files
selinux: Implementation for inode_copy_up() hook
security,overlayfs: Provide security hook for copy up of xattrs for
overlay file
selinux: Implementation for inode_copy_up_xattr() hook
selinux: Pass security pointer to determine_inode_label()
security, overlayfs: Provide hook to correctly label newly created
files
selinux: Implement dentry_create_files_as() hook
overlayfs: Dilute permission checks on lower only if not special file
overlayfs: Append MAY_READ when diluting write checks
fs/overlayfs/copy_up.c | 25 +++++++++++++++
fs/overlayfs/dir.c | 10 ++++++
fs/overlayfs/inode.c | 9 ++++--
include/linux/lsm_hooks.h | 36 ++++++++++++++++++++++
include/linux/security.h | 24 +++++++++++++++
security/security.c | 27 ++++++++++++++++
security/selinux/hooks.c | 78 +++++++++++++++++++++++++++++++++++++++++------
7 files changed, 198 insertions(+), 11 deletions(-)
--
2.7.4
[toc] | [next] | [standalone]
| From | Vivek Goyal <vgoyal@redhat.com> |
|---|---|
| Date | 2016-07-13 16:50 +0200 |
| Subject | [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files |
| Message-ID | <rUtE6-4my-19@gated-at.bofh.it> |
| In reply to | #1442515 |
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 <vgoyal@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, &dentry->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, &stat,
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,
+ struct cred *new);
int security_inode_alloc(struct inode *inode);
void security_inode_free(struct inode *inode);
@@ -600,6 +604,14 @@ static inline int security_dentry_init_security(struct dentry *dentry,
return -EOPNOTSUPP;
}
+static inline int security_dentry_create_files_as(struct dentry *dentry,
+ int mode, struct qstr *name,
+ const struct cred *old,
+ struct cred *new)
+{
+ return 0;
+}
+
static inline int security_inode_init_security(struct inode *inode,
struct inode *dir,
diff --git a/security/security.c b/security/security.c
index 3321e31..38747d1 100644
--- a/security/security.c
+++ b/security/security.c
@@ -364,6 +364,15 @@ int security_dentry_init_security(struct dentry *dentry, int mode,
}
EXPORT_SYMBOL(security_dentry_init_security);
+int security_dentry_create_files_as(struct dentry *dentry, int mode,
+ struct qstr *name,
+ const struct cred *old, struct cred *new)
+{
+ return call_int_hook(dentry_create_files_as, 0, dentry, mode,
+ name, old, new);
+}
+EXPORT_SYMBOL(security_dentry_create_files_as);
+
int security_inode_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr,
const initxattrs initxattrs, void *fs_data)
@@ -1614,6 +1623,8 @@ struct security_hook_heads security_hook_heads = {
LIST_HEAD_INIT(security_hook_heads.sb_parse_opts_str),
.dentry_init_security =
LIST_HEAD_INIT(security_hook_heads.dentry_init_security),
+ .dentry_create_files_as =
+ LIST_HEAD_INIT(security_hook_heads.dentry_create_files_as),
#ifdef CONFIG_SECURITY_PATH
.path_unlink = LIST_HEAD_INIT(security_hook_heads.path_unlink),
.path_mkdir = LIST_HEAD_INIT(security_hook_heads.path_mkdir),
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Stephen Smalley <sds@tycho.nsa.gov> |
|---|---|
| Date | 2016-07-13 17:10 +0200 |
| Subject | Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files |
| Message-ID | <rUtXs-4Ju-11@gated-at.bofh.it> |
| In reply to | #1442516 |
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 <vgoyal@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, &dentry->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, &stat,
>> 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,
>> + struct cred *new);
>>
>> int security_inode_alloc(struct inode *inode);
>> void security_inode_free(struct inode *inode);
>> @@ -600,6 +604,14 @@ static inline int security_dentry_init_security(struct dentry *dentry,
>> return -EOPNOTSUPP;
>> }
>>
>> +static inline int security_dentry_create_files_as(struct dentry *dentry,
>> + int mode, struct qstr *name,
>> + const struct cred *old,
>> + struct cred *new)
>> +{
>> + return 0;
>> +}
>> +
>>
>> static inline int security_inode_init_security(struct inode *inode,
>> struct inode *dir,
>> diff --git a/security/security.c b/security/security.c
>> index 3321e31..38747d1 100644
>> --- a/security/security.c
>> +++ b/security/security.c
>> @@ -364,6 +364,15 @@ int security_dentry_init_security(struct dentry *dentry, int mode,
>> }
>> EXPORT_SYMBOL(security_dentry_init_security);
>>
>> +int security_dentry_create_files_as(struct dentry *dentry, int mode,
>> + struct qstr *name,
>> + const struct cred *old, struct cred *new)
>> +{
>> + return call_int_hook(dentry_create_files_as, 0, dentry, mode,
>> + name, old, new);
>> +}
>> +EXPORT_SYMBOL(security_dentry_create_files_as);
>> +
>> int security_inode_init_security(struct inode *inode, struct inode *dir,
>> const struct qstr *qstr,
>> const initxattrs initxattrs, void *fs_data)
>> @@ -1614,6 +1623,8 @@ struct security_hook_heads security_hook_heads = {
>> LIST_HEAD_INIT(security_hook_heads.sb_parse_opts_str),
>> .dentry_init_security =
>> LIST_HEAD_INIT(security_hook_heads.dentry_init_security),
>> + .dentry_create_files_as =
>> + LIST_HEAD_INIT(security_hook_heads.dentry_create_files_as),
>> #ifdef CONFIG_SECURITY_PATH
>> .path_unlink = LIST_HEAD_INIT(security_hook_heads.path_unlink),
>> .path_mkdir = LIST_HEAD_INIT(security_hook_heads.path_mkdir),
>>
>
[toc] | [prev] | [next] | [standalone]
| From | Stephen Smalley <sds@tycho.nsa.gov> |
|---|---|
| Date | 2016-07-13 17:10 +0200 |
| Subject | Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files |
| Message-ID | <rUtXs-4Ju-13@gated-at.bofh.it> |
| In reply to | #1442516 |
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 <vgoyal@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, &dentry->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, &stat,
> 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,
> + struct cred *new);
>
> int security_inode_alloc(struct inode *inode);
> void security_inode_free(struct inode *inode);
> @@ -600,6 +604,14 @@ static inline int security_dentry_init_security(struct dentry *dentry,
> return -EOPNOTSUPP;
> }
>
> +static inline int security_dentry_create_files_as(struct dentry *dentry,
> + int mode, struct qstr *name,
> + const struct cred *old,
> + struct cred *new)
> +{
> + return 0;
> +}
> +
>
> static inline int security_inode_init_security(struct inode *inode,
> struct inode *dir,
> diff --git a/security/security.c b/security/security.c
> index 3321e31..38747d1 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -364,6 +364,15 @@ int security_dentry_init_security(struct dentry *dentry, int mode,
> }
> EXPORT_SYMBOL(security_dentry_init_security);
>
> +int security_dentry_create_files_as(struct dentry *dentry, int mode,
> + struct qstr *name,
> + const struct cred *old, struct cred *new)
> +{
> + return call_int_hook(dentry_create_files_as, 0, dentry, mode,
> + name, old, new);
> +}
> +EXPORT_SYMBOL(security_dentry_create_files_as);
> +
> int security_inode_init_security(struct inode *inode, struct inode *dir,
> const struct qstr *qstr,
> const initxattrs initxattrs, void *fs_data)
> @@ -1614,6 +1623,8 @@ struct security_hook_heads security_hook_heads = {
> LIST_HEAD_INIT(security_hook_heads.sb_parse_opts_str),
> .dentry_init_security =
> LIST_HEAD_INIT(security_hook_heads.dentry_init_security),
> + .dentry_create_files_as =
> + LIST_HEAD_INIT(security_hook_heads.dentry_create_files_as),
> #ifdef CONFIG_SECURITY_PATH
> .path_unlink = LIST_HEAD_INIT(security_hook_heads.path_unlink),
> .path_mkdir = LIST_HEAD_INIT(security_hook_heads.path_mkdir),
>
[toc] | [prev] | [next] | [standalone]
| From | Stephen Smalley <sds@tycho.nsa.gov> |
|---|---|
| Date | 2016-07-14 16:30 +0200 |
| Subject | Re: [PATCH 6/9] security, overlayfs: Provide hook to correctly label newly created files |
| Message-ID | <rUPOh-2or-21@gated-at.bofh.it> |
| In reply to | #1442516 |
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 <vgoyal@redhat.com>
Acked-by: Stephen Smalley <sds@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, &dentry->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, &stat,
> 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,
> + struct cred *new);
>
> int security_inode_alloc(struct inode *inode);
> void security_inode_free(struct inode *inode);
> @@ -600,6 +604,14 @@ static inline int security_dentry_init_security(struct dentry *dentry,
> return -EOPNOTSUPP;
> }
>
> +static inline int security_dentry_create_files_as(struct dentry *dentry,
> + int mode, struct qstr *name,
> + const struct cred *old,
> + struct cred *new)
> +{
> + return 0;
> +}
> +
>
> static inline int security_inode_init_security(struct inode *inode,
> struct inode *dir,
> diff --git a/security/security.c b/security/security.c
> index 3321e31..38747d1 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -364,6 +364,15 @@ int security_dentry_init_security(struct dentry *dentry, int mode,
> }
> EXPORT_SYMBOL(security_dentry_init_security);
>
> +int security_dentry_create_files_as(struct dentry *dentry, int mode,
> + struct qstr *name,
> + const struct cred *old, struct cred *new)
> +{
> + return call_int_hook(dentry_create_files_as, 0, dentry, mode,
> + name, old, new);
> +}
> +EXPORT_SYMBOL(security_dentry_create_files_as);
> +
> int security_inode_init_security(struct inode *inode, struct inode *dir,
> const struct qstr *qstr,
> const initxattrs initxattrs, void *fs_data)
> @@ -1614,6 +1623,8 @@ struct security_hook_heads security_hook_heads = {
> LIST_HEAD_INIT(security_hook_heads.sb_parse_opts_str),
> .dentry_init_security =
> LIST_HEAD_INIT(security_hook_heads.dentry_init_security),
> + .dentry_create_files_as =
> + LIST_HEAD_INIT(security_hook_heads.dentry_create_files_as),
> #ifdef CONFIG_SECURITY_PATH
> .path_unlink = LIST_HEAD_INIT(security_hook_heads.path_unlink),
> .path_mkdir = LIST_HEAD_INIT(security_hook_heads.path_mkdir),
>
[toc] | [prev] | [next] | [standalone]
| From | Vivek Goyal <vgoyal@redhat.com> |
|---|---|
| Date | 2016-07-13 16:50 +0200 |
| Subject | [PATCH 9/9] overlayfs: Append MAY_READ when diluting write checks |
| Message-ID | <rUtE6-4my-27@gated-at.bofh.it> |
| In reply to | #1442515 |
Right now we remove MAY_WRITE/MAY_APPEND bits from mask if realfile is
on lower/. This is done as files on lower will never be written and will
be copied up. But to copy up a file, mounter should have MAY_READ permission
otherwise copy up will fail. So set MAY_READ in mask when MAY_WRITE is
reset.
Dan Walsh noticed this when he did access(lowerfile, W_OK) and it returned
True (context mounts) but when he tried to actually write to file, it failed
as mounter did not have permission on lower file.
Reported-by: Dan Walsh <dwalsh@redhat.com>
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
fs/overlayfs/inode.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 6d9d86e..83b2422 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -140,8 +140,13 @@ int ovl_permission(struct inode *inode, int mask)
return err;
old_cred = ovl_override_creds(inode->i_sb);
- if (!is_upper && !special_file(realinode->i_mode))
- mask &= ~(MAY_WRITE | MAY_APPEND);
+ if (!is_upper && !special_file(realinode->i_mode)) {
+ if (mask & MAY_WRITE || mask & MAY_APPEND) {
+ mask &= ~(MAY_WRITE | MAY_APPEND);
+ /* Make sure mounter can read file for copy up later */
+ mask |= MAY_READ;
+ }
+ }
err = inode_permission(realinode, mask);
revert_creds(old_cred);
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Miklos Szeredi <miklos@szeredi.hu> |
|---|---|
| Date | 2016-07-14 08:50 +0200 |
| Subject | Re: [PATCH 9/9] overlayfs: Append MAY_READ when diluting write checks |
| Message-ID | <rUID8-614-15@gated-at.bofh.it> |
| In reply to | #1442517 |
On Wed, Jul 13, 2016 at 4:44 PM, Vivek Goyal <vgoyal@redhat.com> wrote:
> Right now we remove MAY_WRITE/MAY_APPEND bits from mask if realfile is
> on lower/. This is done as files on lower will never be written and will
> be copied up. But to copy up a file, mounter should have MAY_READ permission
> otherwise copy up will fail. So set MAY_READ in mask when MAY_WRITE is
> reset.
>
> Dan Walsh noticed this when he did access(lowerfile, W_OK) and it returned
> True (context mounts) but when he tried to actually write to file, it failed
> as mounter did not have permission on lower file.
>
> Reported-by: Dan Walsh <dwalsh@redhat.com>
> Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
> ---
> fs/overlayfs/inode.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
> index 6d9d86e..83b2422 100644
> --- a/fs/overlayfs/inode.c
> +++ b/fs/overlayfs/inode.c
> @@ -140,8 +140,13 @@ int ovl_permission(struct inode *inode, int mask)
> return err;
>
> old_cred = ovl_override_creds(inode->i_sb);
> - if (!is_upper && !special_file(realinode->i_mode))
> - mask &= ~(MAY_WRITE | MAY_APPEND);
> + if (!is_upper && !special_file(realinode->i_mode)) {
> + if (mask & MAY_WRITE || mask & MAY_APPEND) {
Hmm. From what I can tell O_APPEND with O_RDONLY is equivalent to
O_RDONLY, hence MAY_APPEND without MAY_WRITE should not behave as if
MAY_WRITE was given. I.e. it should not trigger a copy up. Not sure
what MAC checks do with MAY_APPEND, though.
Pushed amended commit to overlayfs-next.
Thanks,
Miklos
> + mask &= ~(MAY_WRITE | MAY_APPEND);
> + /* Make sure mounter can read file for copy up later */
> + mask |= MAY_READ;
> + }
> + }
> err = inode_permission(realinode, mask);
> revert_creds(old_cred);
>
> --
> 2.7.4
>
[toc] | [prev] | [next] | [standalone]
| From | Paul Moore <paul@paul-moore.com> |
|---|---|
| Date | 2016-07-21 23:20 +0200 |
| Message-ID | <rXtxU-4A4-35@gated-at.bofh.it> |
| In reply to | #1442515 |
On Wed, Jul 13, 2016 at 10:44 AM, Vivek Goyal <vgoyal@redhat.com> wrote: > Hi All, > > Please find attached the V3 of patches. Changes since V2 are as follows. > > - Fixed the build issue with CONFIG_SECURITY=n. > > - Dan Walsh was writing more tests for selinux-testsuite and noted couple > of issues. I have fixed those issues and added two more patches in series. > > 1. We are resetting MAY_WRITE check for lower inode assuming file will > be coiped up. But this is not true for special_file() as these files > are not copied up. So checks should not be reset in case of special > file. > > 2. We are resetting MAY_WRITE check for lower inode assuming file will > be copied up. But this also should mean that mounter has permission > to MAY_READ lower file for copy up to succeed. So add MAY_READ > check while resetting MAY_WRITE. > > Original description of patches follows. > > Following are RFC patches to support SELinux with overlayfs. I started > with David Howells's latest posting on this topic and started modifying > patches. These patches apply on top of overlayfs-next branch of miklos > vfs git tree. > > git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git overlayfs-next > > These patches can be pulled from my branch too. > > https://github.com/rhvgoyal/linux/commits/overlayfs-selinux-mounter-next > > Thanks to Dan Walsh, Stephen Smalley and Miklos Szeredi for numerous > conversation and ideas in helping figuring out what one reasonable > implementation might look like. > > Dan Walsh has been writing tests for selinux overlayfs in selinux-testsuite. > These patches pass those tests now > > https://github.com/rhatdan/selinux-testsuite/commits/master > > Posting these patches for review and comments. > > These patches introduce 3 new security hooks. > > - security_inode_copy_up(), is called when a file is copied up. This hook > prepares a new set of cred which is used for copy up operation. And > new set of creds are prepared so that ->create_sid can be set appropriately > and newly created file is labeled properly. > > When a file is copied up, label of lower file is retained except for the > case of context= mount where new file gets the label from context= option. > > - security_inode_copy_up_xattr(), is called when xattrs of a file are > being copied up. Before this we already called security_inode_copy_up() > and created new file and copied up data. That means file already got > labeled properly and there is no need to take SELINUX xattr of lower > file and overwrite the upper file xattr. So this hook is used to avoid > copying up of SELINUX xattr. > > - dentry_create_files_as(), is called when a new file is about to be created. > This hook determines what the label of the file should be if task had > created that file in upper/ and sets create_sid accordingly in the passed > in creds. > > Normal transition rules don't work for the case of context mounts as > underlying file system is not aware of context option which only overlay > layer is aware of. For non-context mounts, creation can happen in work/ > dir first and then file might be renamed into upper/, and it might get > label based on work/ dir. So this hooks helps avoiding all these issues. > > When a new file is created in upper/, it gets its label based on transition > rules. For the case of context mount, it gets the label from context= > option. > > Any feedback is welcome. Hi Vivek, These patches look fine to me, thanks for all your hard work and to everyone who helped review and provide feedback. I have tagged these patches for merging into the SELinux next branch after this merge window. Miklos, this patchset depends on patches in your overlayfs-next branch, I assume you're pushing that branch during the upcoming merge window? James, assuming the overlayfs-next branch is pulled during the merge window, can you rebase your linux-security#next branch to v4.8-rc1 once Linus tags it? -- paul moore www.paul-moore.com
[toc] | [prev] | [next] | [standalone]
| From | James Morris <jmorris@namei.org> |
|---|---|
| Date | 2016-07-22 01:10 +0200 |
| Message-ID | <rXvgm-5P3-7@gated-at.bofh.it> |
| In reply to | #1448159 |
On Thu, 21 Jul 2016, Paul Moore wrote: > James, assuming the overlayfs-next branch is pulled during the merge > window, can you rebase your linux-security#next branch to v4.8-rc1 > once Linus tags it? Yep. -- James Morris <jmorris@namei.org>
[toc] | [prev] | [next] | [standalone]
| From | Miklos Szeredi <miklos@szeredi.hu> |
|---|---|
| Date | 2016-07-22 09:10 +0200 |
| Message-ID | <rXCKR-2yo-1@gated-at.bofh.it> |
| In reply to | #1448159 |
On Thu, Jul 21, 2016 at 11:16 PM, Paul Moore <paul@paul-moore.com> wrote: > Hi Vivek, > > These patches look fine to me, thanks for all your hard work and to > everyone who helped review and provide feedback. I have tagged these > patches for merging into the SELinux next branch after this merge > window. > > Miklos, this patchset depends on patches in your overlayfs-next > branch, I assume you're pushing that branch during the upcoming merge > window? Yes, that's the plan. Thanks, Miklos
[toc] | [prev] | [next] | [standalone]
| From | Paul Moore <paul@paul-moore.com> |
|---|---|
| Date | 2016-07-22 17:40 +0200 |
| Message-ID | <rXKIp-7Bs-1@gated-at.bofh.it> |
| In reply to | #1448423 |
On Thu, Jul 21, 2016 at 7:09 PM, James Morris <jmorris@namei.org> wrote: > On Thu, 21 Jul 2016, Paul Moore wrote: >> James, assuming the overlayfs-next branch is pulled during the merge >> window, can you rebase your linux-security#next branch to v4.8-rc1 >> once Linus tags it? > > Yep. On Fri, Jul 22, 2016 at 3:05 AM, Miklos Szeredi <miklos@szeredi.hu> wrote: > On Thu, Jul 21, 2016 at 11:16 PM, Paul Moore <paul@paul-moore.com> wrote: >> Hi Vivek, >> >> These patches look fine to me, thanks for all your hard work and to >> everyone who helped review and provide feedback. I have tagged these >> patches for merging into the SELinux next branch after this merge >> window. >> >> Miklos, this patchset depends on patches in your overlayfs-next >> branch, I assume you're pushing that branch during the upcoming merge >> window? > > Yes, that's the plan. Great, thanks. -- paul moore www.paul-moore.com
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web