Loading fs/overlayfs/copy_up.c +22 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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; Loading fs/overlayfs/dir.c +10 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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)); Loading include/linux/lsm_hooks.h +36 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 * Loading Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading include/linux/security.h +24 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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; Loading security/lsm_audit.c +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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: { Loading Loading
fs/overlayfs/copy_up.c +22 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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; Loading
fs/overlayfs/dir.c +10 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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)); Loading
include/linux/lsm_hooks.h +36 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 * Loading Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading
include/linux/security.h +24 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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; Loading
security/lsm_audit.c +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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: { Loading