#include <linux/fs_struct.h>
/* Do not directly use this function. Use OVERRIDE_CRED() instead. */
-const struct cred * override_fsids(struct sdcardfs_sb_info* sbi)
+const struct cred * override_fsids(struct sdcardfs_sb_info* sbi, struct sdcardfs_inode_info *info)
{
struct cred * cred;
const struct cred * old_cred;
+ uid_t uid;
cred = prepare_creds();
if (!cred)
return NULL;
- cred->fsuid = make_kuid(&init_user_ns, sbi->options.fs_low_uid);
+ if (info->under_obb)
+ uid = AID_MEDIA_OBB;
+ else
+ uid = multiuser_get_uid(info->userid, sbi->options.fs_low_uid);
+ cred->fsuid = make_kuid(&init_user_ns, uid);
cred->fsgid = make_kgid(&init_user_ns, sbi->options.fs_low_gid);
old_cred = override_creds(cred);
struct fs_struct *saved_fs;
struct fs_struct *copied_fs;
- if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+ if(!check_caller_access_to_name(dir, &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
}
/* save current_cred and override it */
- OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred);
+ OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
sdcardfs_get_lower_path(dentry, &lower_path);
lower_dentry = lower_path.dentry;
goto out;
fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir));
fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry));
+ fixup_lower_ownership(dentry, dentry->d_name.name);
out:
current->fs = saved_fs;
struct path lower_path;
const struct cred *saved_cred = NULL;
- if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+ if(!check_caller_access_to_name(dir, &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
}
/* save current_cred and override it */
- OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred);
+ OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
sdcardfs_get_lower_path(dentry, &lower_path);
lower_dentry = lower_path.dentry;
int touch_err = 0;
struct fs_struct *saved_fs;
struct fs_struct *copied_fs;
+ struct qstr q_obb = QSTR_LITERAL("obb");
+ struct qstr q_data = QSTR_LITERAL("data");
- if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+ if(!check_caller_access_to_name(dir, &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
}
/* save current_cred and override it */
- OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred);
+ OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
/* check disk space */
if (!check_min_free_space(dentry, 0, 1)) {
fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry));
/* update number of links on parent directory */
set_nlink(dir, sdcardfs_lower_inode(dir)->i_nlink);
-
+ fixup_lower_ownership(dentry, dentry->d_name.name);
unlock_dir(lower_parent_dentry);
-
- if ((!sbi->options.multiuser) && (!strcasecmp(dentry->d_name.name, "obb"))
+ if ((!sbi->options.multiuser) && (qstr_case_eq(&dentry->d_name, &q_obb))
&& (pi->perm == PERM_ANDROID) && (pi->userid == 0))
make_nomedia_in_obb = 1;
/* When creating /Android/data and /Android/obb, mark them as .nomedia */
if (make_nomedia_in_obb ||
- ((pi->perm == PERM_ANDROID) && (!strcasecmp(dentry->d_name.name, "data")))) {
+ ((pi->perm == PERM_ANDROID) && (qstr_case_eq(&dentry->d_name, &q_data)))) {
+ REVERT_CRED(saved_cred);
+ OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(d_inode(dentry)));
set_fs_pwd(current->fs, &lower_path);
touch_err = touch(".nomedia", 0664);
if (touch_err) {
struct path lower_path;
const struct cred *saved_cred = NULL;
- if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+ if(!check_caller_access_to_name(dir, &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
}
/* save current_cred and override it */
- OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred);
+ OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
/* sdcardfs_get_real_lower(): in case of remove an user's obb dentry
* the dentry on the original path should be deleted. */
struct path lower_old_path, lower_new_path;
const struct cred *saved_cred = NULL;
- if(!check_caller_access_to_name(old_dir, old_dentry->d_name.name) ||
- !check_caller_access_to_name(new_dir, new_dentry->d_name.name)) {
+ if(!check_caller_access_to_name(old_dir, &old_dentry->d_name) ||
+ !check_caller_access_to_name(new_dir, &new_dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" new_dentry: %s, task:%s\n",
__func__, new_dentry->d_name.name, current->comm);
}
/* save current_cred and override it */
- OVERRIDE_CRED(SDCARDFS_SB(old_dir->i_sb), saved_cred);
+ OVERRIDE_CRED(SDCARDFS_SB(old_dir->i_sb), saved_cred, SDCARDFS_I(new_dir));
sdcardfs_get_real_lower(old_dentry, &lower_old_path);
sdcardfs_get_lower_path(new_dentry, &lower_new_path);
sdcardfs_copy_and_fix_attrs(old_dir, d_inode(lower_old_dir_dentry));
fsstack_copy_inode_size(old_dir, d_inode(lower_old_dir_dentry));
}
- /* At this point, not all dentry information has been moved, so
- * we pass along new_dentry for the name.*/
- get_derived_permission_new(new_dentry->d_parent, old_dentry, new_dentry);
+ get_derived_permission_new(new_dentry->d_parent, old_dentry, &new_dentry->d_name);
fixup_tmp_permissions(d_inode(old_dentry));
- fixup_top_recursive(old_dentry);
+ fixup_lower_ownership(old_dentry, new_dentry->d_name.name);
+ drop_recursive(old_dentry); /* Can't fixup ownership recursively :( */
out:
unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
dput(lower_old_dir_dentry);
if (!err) {
/* check the Android group ID */
parent = dget_parent(dentry);
- if(!check_caller_access_to_name(d_inode(parent), dentry->d_name.name)) {
+ if(!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
goto out_err;
/* save current_cred and override it */
- OVERRIDE_CRED(SDCARDFS_SB(dentry->d_sb), saved_cred);
+ OVERRIDE_CRED(SDCARDFS_SB(dentry->d_sb), saved_cred, SDCARDFS_I(inode));
sdcardfs_get_lower_path(dentry, &lower_path);
lower_dentry = lower_path.dentry;
int err;
parent = dget_parent(dentry);
- if(!check_caller_access_to_name(d_inode(parent), dentry->d_name.name)) {
+ if(!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);