blob: 0d172d68d1d798ca8999896adfabe027014e998c [file] [log] [blame]
/*
* sdp_name.c
*
*/
#include <linux/crypto.h>
#include <sdp/fs_handler.h>
#if defined(CONFIG_EXT4CRYPT_SDP) || defined(CONFIG_DDAR)
#include "../fscrypt_knox_private.h"
#endif
#ifdef CONFIG_EXT4CRYPT_SDP
#include "../ext4.h"
#include "../ext4_crypto.h"
#include "fscrypto_sdp_dek_private.h"
#include "fscrypto_sdp_name.h"
#endif
struct fscrypt_sdp_renament {
struct inode *dir;
struct dentry *dentry;
struct inode *inode;
};
static int fscrypt_sdp_get_storage_type(struct dentry *target_dentry)
{
if (!target_dentry)
return FSCRYPT_SDP_NAME_FUNC_ERROR;
else {
int p_type = FSCRYPT_SDP_NAME_FUNC_ERROR;
struct dentry *t_dentry = target_dentry;
while (strcasecmp(t_dentry->d_name.name, "/")) {// "/" means "/data"
if (!strcasecmp(t_dentry->d_name.name, "user")) {
p_type = FSCRYPT_STORAGE_TYPE_DATA_CE;
} else if (!strcasecmp(t_dentry->d_name.name, "media")) {
p_type = FSCRYPT_STORAGE_TYPE_MEDIA_CE;
} else if (!strcasecmp(t_dentry->d_name.name, "system_ce")) {
p_type = FSCRYPT_STORAGE_TYPE_SYSTEM_CE;
} else if (!strcasecmp(t_dentry->d_name.name, "misc_ce")) {
p_type = FSCRYPT_STORAGE_TYPE_MISC_CE;
} else if (!strcasecmp(t_dentry->d_name.name, "user_de")) {
p_type = FSCRYPT_STORAGE_TYPE_DATA_DE;
} else if (!strcasecmp(t_dentry->d_name.name, "system_de")) {
p_type = FSCRYPT_STORAGE_TYPE_SYSTEM_DE;
} else if (!strcasecmp(t_dentry->d_name.name, "misc_de")) {
p_type = FSCRYPT_STORAGE_TYPE_MISC_DE;
} else if (!strcasecmp(t_dentry->d_name.name, "enc_user")) {
p_type = FSCRYPT_STORAGE_TYPE_SDP_ENC_USER;
} else if (!strcasecmp(t_dentry->d_name.name, "knox")) {
p_type = FSCRYPT_STORAGE_TYPE_SDP_ENC_EMULATED;
} else {
p_type = FSCRYPT_SDP_NAME_FUNC_ERROR;
}
t_dentry = t_dentry->d_parent;
}
return p_type;
}
}
void fscrypt_sdp_check_chamber_event(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
struct fscrypt_sdp_renament old = {
.dir = old_dir,
.dentry = old_dentry,
.inode = d_inode(old_dentry),
};
struct fscrypt_sdp_renament new = {
.dir = new_dir,
.dentry = new_dentry,
.inode = d_inode(new_dentry),
};
/* EXT4CRYPT-dedicated */
if (EXT4_I(old_dir)->i_crypt_info &&
EXT4_I(new_dir)->i_crypt_info) {
sdp_fs_command_t *cmd = NULL;
int rename_event = 0x00;
if (FSCRYPT_IS_SENSITIVE_DENTRY(old.dentry->d_parent) &&
!FSCRYPT_IS_SENSITIVE_DENTRY(new.dentry->d_parent)) {
rename_event |= FSCRYPT_EVT_RENAME_OUT_OF_CHAMBER;
}
if (!FSCRYPT_IS_SENSITIVE_DENTRY(old.dentry->d_parent) &&
FSCRYPT_IS_SENSITIVE_DENTRY(new.dentry->d_parent)) {
rename_event |= FSCRYPT_EVT_RENAME_TO_CHAMBER;
}
if ((rename_event & FSCRYPT_EVT_RENAME_TO_CHAMBER) &&
!FSCRYPT_IS_SENSITIVE_DENTRY(old.dentry)) {//Protected dir to Sensitive area
cmd = sdp_fs_command_alloc(FSOP_SDP_SET_SENSITIVE, current->pid,
fscrypt_sdp_get_engine_id(new.dir),
fscrypt_sdp_get_storage_type(new.dentry->d_parent),
old.inode->i_ino,
GFP_NOFS);
} else if (rename_event & FSCRYPT_EVT_RENAME_OUT_OF_CHAMBER) {//Sensitive dir to Protected area
cmd = sdp_fs_command_alloc(FSOP_SDP_SET_PROTECTED, current->pid,
fscrypt_sdp_get_engine_id(old.dir),
fscrypt_sdp_get_storage_type(new.dentry->d_parent),
old.inode->i_ino,
GFP_NOFS);
}
if (cmd != NULL) {
sdp_fs_request(cmd, NULL);
sdp_fs_command_free(cmd);
}
}
}
int fscrypt_sdp_check_rename_pre(struct dentry *old_dentry)
{
/* EXT4CRYPT-dedicated */
if (EXT4_I(old_dentry->d_inode)->i_crypt_info &&
EXT4_I(old_dentry->d_inode)->i_crypt_info->ci_sdp_info &&
FSCRYPT_IS_CHAMBER_DENTRY(old_dentry)) {
printk_once(KERN_WARNING
"Renaming Chamber directory, I/O error\n");
return -EIO;
}
return 0;
}
void fscrypt_sdp_check_rename_post(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
// if (IS_ENCRYPTED(d_inode(old_dentry))) {
fscrypt_sdp_check_chamber_event(old_dir, old_dentry, new_dir, new_dentry);
// }
}
int fscrypt_sdp_check_rmdir(struct dentry *dentry)
{
/* EXT4CRYPT-dedicated */
if (EXT4_I(dentry->d_inode)->i_crypt_info &&
EXT4_I(dentry->d_inode)->i_crypt_info->ci_sdp_info &&
FSCRYPT_IS_CHAMBER_DENTRY(dentry)) {
printk_once(KERN_WARNING
"You're removing Chamber directory, I/O error\n");
return -EIO;
}
return 0;
}