Skip to content

Commit

Permalink
Merge branch 'stable-4.9' of git://git.infradead.org/users/pcmoore/se…
Browse files Browse the repository at this point in the history
…linux into next
  • Loading branch information
James Morris committed Sep 19, 2016
2 parents e350e24 + 9b6a9ec commit de2f4b3
Show file tree
Hide file tree
Showing 13 changed files with 211 additions and 65 deletions.
22 changes: 22 additions & 0 deletions fs/overlayfs/copy_up.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
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;
Expand Down Expand Up @@ -246,6 +253,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);
Expand All @@ -258,10 +267,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, &new_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;

Expand Down
10 changes: 10 additions & 0 deletions fs/overlayfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,15 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
if (override_cred) {
override_cred->fsuid = inode->i_uid;
override_cred->fsgid = inode->i_gid;
if (!hardlink) {
err = security_dentry_create_files_as(dentry,
stat->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);

Expand All @@ -445,6 +454,7 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
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));
Expand Down
36 changes: 36 additions & 0 deletions include/linux/lsm_hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -401,6 +411,23 @@
* @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.
* @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
*
Expand Down Expand Up @@ -1358,6 +1385,10 @@ union security_list_options {
int (*dentry_init_security)(struct dentry *dentry, int mode,
const 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
Expand Down Expand Up @@ -1425,6 +1456,8 @@ 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 (*inode_copy_up_xattr)(const char *name);

int (*file_permission)(struct file *file, int mask);
int (*file_alloc_security)(struct file *file);
Expand Down Expand Up @@ -1655,6 +1688,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;
Expand Down Expand Up @@ -1695,6 +1729,8 @@ 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 inode_copy_up_xattr;
struct list_head file_permission;
struct list_head file_alloc_security;
struct list_head file_free_security;
Expand Down
24 changes: 24 additions & 0 deletions include/linux/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
const 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);
Expand Down Expand Up @@ -282,6 +286,8 @@ 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_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);
Expand Down Expand Up @@ -597,6 +603,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,
Expand Down Expand Up @@ -757,6 +771,16 @@ 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_inode_copy_up_xattr(const char *name)
{
return -EOPNOTSUPP;
}

static inline int security_file_permission(struct file *file, int mask)
{
return 0;
Expand Down
4 changes: 2 additions & 2 deletions security/lsm_audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
}
return ret;
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#if IS_ENABLED(CONFIG_IPV6)
/**
* ipv6_skb_to_auditdata : fill auditdata from skb
* @skb : the skb
Expand Down Expand Up @@ -257,7 +257,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
audit_log_format(ab, " ino=%lu", inode->i_ino);
}

audit_log_format(ab, " ioctlcmd=%hx", a->u.op->cmd);
audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd);
break;
}
case LSM_AUDIT_DATA_DENTRY: {
Expand Down
27 changes: 27 additions & 0 deletions security/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -748,6 +757,18 @@ void security_inode_getsecid(struct inode *inode, u32 *secid)
call_void_hook(inode_getsecid, inode, secid);
}

int security_inode_copy_up(struct dentry *src, struct cred **new)
{
return call_int_hook(inode_copy_up, 0, src, 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);

int security_file_permission(struct file *file, int mask)
{
int ret;
Expand Down Expand Up @@ -1623,6 +1644,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),
Expand Down Expand Up @@ -1684,6 +1707,10 @@ struct security_hook_heads security_hook_heads = {
LIST_HEAD_INIT(security_hook_heads.inode_listsecurity),
.inode_getsecid =
LIST_HEAD_INIT(security_hook_heads.inode_getsecid),
.inode_copy_up =
LIST_HEAD_INIT(security_hook_heads.inode_copy_up),
.inode_copy_up_xattr =
LIST_HEAD_INIT(security_hook_heads.inode_copy_up_xattr),
.file_permission =
LIST_HEAD_INIT(security_hook_heads.file_permission),
.file_alloc_security =
Expand Down
38 changes: 0 additions & 38 deletions security/selinux/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -93,41 +93,3 @@ config SECURITY_SELINUX_CHECKREQPROT_VALUE
via /selinux/checkreqprot if authorized by policy.

If you are unsure how to answer this question, answer 0.

config SECURITY_SELINUX_POLICYDB_VERSION_MAX
bool "NSA SELinux maximum supported policy format version"
depends on SECURITY_SELINUX
default n
help
This option enables the maximum policy format version supported
by SELinux to be set to a particular value. This value is reported
to userspace via /selinux/policyvers and used at policy load time.
It can be adjusted downward to support legacy userland (init) that
does not correctly handle kernels that support newer policy versions.

Examples:
For the Fedora Core 3 or 4 Linux distributions, enable this option
and set the value via the next option. For Fedora Core 5 and later,
do not enable this option.

If you are unsure how to answer this question, answer N.

config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
int "NSA SELinux maximum supported policy format version value"
depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
range 15 23
default 19
help
This option sets the value for the maximum policy format version
supported by SELinux.

Examples:
For Fedora Core 3, use 18.
For Fedora Core 4, use 19.

If you are unsure how to answer this question, look for the
policy format version supported by your policy toolchain, by
running 'checkpolicy -V'. Or look at what policy you have
installed under /etc/selinux/$SELINUXTYPE/policy, where
SELINUXTYPE is defined in your /etc/selinux/config.

Loading

0 comments on commit de2f4b3

Please sign in to comment.