/** * sdp_xattr.c * * get/set sdp context to xattr */ #include "../fscrypt_private.h" #include "fscrypto_sdp_xattr_private.h" #include #define FSCRYPT_SDP_FS_TYPE_EXT4_STR "ext4" #define FSCRYPT_SDP_FS_TYPE_F2FS_STR "f2fs" #define FSCRYPT_SDP_XATTR_NAME_ENCRYPTION_SDP_CONTEXT "sdp" //Must sync with ext4/xattr.h #define FSCRYPT_SDP_EXT4_XATTR_INDEX_ENCRYPTION 9 extern int ext4_xattr_set(struct inode *, int, const char *, const void *, size_t, int); extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t); //Must sync with f2fs/xattr.h #define FSCRYPT_SDP_F2FS_XATTR_INDEX_ENCRYPTION 9 #ifdef CONFIG_F2FS_FS_XATTR extern int f2fs_setxattr(struct inode *, int, const char *, const void *, size_t, struct page *, int); extern int f2fs_getxattr(struct inode *, int, const char *, void *, size_t, struct page *); #else static inline int f2fs_setxattr(struct inode *inode, int index, const char *name, const void *value, size_t size, struct page *page, int flags) { return -EOPNOTSUPP; } static inline int f2fs_getxattr(struct inode *inode, int index, const char *name, void *buffer, size_t buffer_size, struct page *dpage) { return -EOPNOTSUPP; } #endif int fscrypt_sdp_get_context(struct inode *inode, void *ctx, size_t len) { const char *fs_type_name = inode->i_mapping->host->i_sb->s_type->name; if (!strcmp(FSCRYPT_SDP_FS_TYPE_EXT4_STR, fs_type_name)) { return ext4_xattr_get(inode, FSCRYPT_SDP_EXT4_XATTR_INDEX_ENCRYPTION, FSCRYPT_SDP_XATTR_NAME_ENCRYPTION_SDP_CONTEXT, ctx, len); } else if (!strcmp(FSCRYPT_SDP_FS_TYPE_F2FS_STR, fs_type_name)) { return f2fs_getxattr(inode, FSCRYPT_SDP_F2FS_XATTR_INDEX_ENCRYPTION, FSCRYPT_SDP_XATTR_NAME_ENCRYPTION_SDP_CONTEXT, ctx, len, NULL); } return -ENOTTY; } static int __fscrypt_sdp_set_context(struct inode *inode, void *ctx, size_t len, bool is_lock, void *fs_data) { int retval = -ENOTTY; const char *fs_type_name = inode->i_mapping->host->i_sb->s_type->name; if (is_lock) inode_lock(inode); if (!strcmp(FSCRYPT_SDP_FS_TYPE_EXT4_STR, fs_type_name)) { retval = ext4_xattr_set(inode, FSCRYPT_SDP_EXT4_XATTR_INDEX_ENCRYPTION, FSCRYPT_SDP_XATTR_NAME_ENCRYPTION_SDP_CONTEXT, ctx, len, 0); } else if (!strcmp(FSCRYPT_SDP_FS_TYPE_F2FS_STR, fs_type_name)) { retval = f2fs_setxattr(inode, FSCRYPT_SDP_F2FS_XATTR_INDEX_ENCRYPTION, FSCRYPT_SDP_XATTR_NAME_ENCRYPTION_SDP_CONTEXT, ctx, len, fs_data, 0); } if (is_lock) inode_unlock(inode); return retval; } int fscrypt_sdp_set_context(struct inode *inode, void *ctx, size_t len, void *fs_data) { return __fscrypt_sdp_set_context(inode, ctx, len, true, fs_data); } int fscrypt_sdp_set_context_nolock(struct inode *inode, void *ctx, size_t len, void *fs_data) { return __fscrypt_sdp_set_context(inode, ctx, len, false, fs_data); } static int __fscrypt_knox_set_context(struct inode *inode, void *ctx, size_t len) { if (inode->i_sb->s_cop->set_knox_context) { return inode->i_sb->s_cop->set_knox_context(inode, NULL, ctx, len, NULL); } else { return -EOPNOTSUPP; } } int fscrypt_knox_set_context(struct inode *inode, void *ctx, size_t len) { return __fscrypt_knox_set_context(inode, ctx, len); }