mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
sdcardfs: override umask on mkdir and create
The mode on files created on the lower fs should not be affected by the umask of the calling task's fs_struct. Instead, we create a copy and modify it as needed. This also lets us avoid the string shenanigans around .nomedia files. Bug: 27992761 Change-Id: Ia3a6e56c24c6e19b3b01c1827e46403bb71c2f4c Signed-off-by: Daniel Rosenberg <drosen@google.com>
This commit is contained in:
parent
b46375c331
commit
feccf66542
2 changed files with 34 additions and 35 deletions
|
@ -127,6 +127,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
|
||||||
}
|
}
|
||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(copy_fs_struct);
|
||||||
|
|
||||||
int unshare_fs_struct(void)
|
int unshare_fs_struct(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sdcardfs.h"
|
#include "sdcardfs.h"
|
||||||
|
#include <linux/fs_struct.h>
|
||||||
|
|
||||||
/* Do not directly use this function. Use OVERRIDE_CRED() instead. */
|
/* 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)
|
||||||
|
@ -56,6 +57,8 @@ static int sdcardfs_create(struct inode *dir, struct dentry *dentry,
|
||||||
struct dentry *lower_parent_dentry = NULL;
|
struct dentry *lower_parent_dentry = NULL;
|
||||||
struct path lower_path;
|
struct path lower_path;
|
||||||
const struct cred *saved_cred = NULL;
|
const struct cred *saved_cred = NULL;
|
||||||
|
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.name)) {
|
||||||
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
|
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
|
||||||
|
@ -78,6 +81,16 @@ static int sdcardfs_create(struct inode *dir, struct dentry *dentry,
|
||||||
|
|
||||||
/* set last 16bytes of mode field to 0664 */
|
/* set last 16bytes of mode field to 0664 */
|
||||||
mode = (mode & S_IFMT) | 00664;
|
mode = (mode & S_IFMT) | 00664;
|
||||||
|
|
||||||
|
/* temporarily change umask for lower fs write */
|
||||||
|
saved_fs = current->fs;
|
||||||
|
copied_fs = copy_fs_struct(current->fs);
|
||||||
|
if (!copied_fs) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
current->fs = copied_fs;
|
||||||
|
current->fs->umask = 0;
|
||||||
err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd);
|
err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -90,6 +103,8 @@ static int sdcardfs_create(struct inode *dir, struct dentry *dentry,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mnt_drop_write(lower_path.mnt);
|
mnt_drop_write(lower_path.mnt);
|
||||||
|
current->fs = saved_fs;
|
||||||
|
free_fs_struct(copied_fs);
|
||||||
out_unlock:
|
out_unlock:
|
||||||
unlock_dir(lower_parent_dentry);
|
unlock_dir(lower_parent_dentry);
|
||||||
sdcardfs_put_lower_path(dentry, &lower_path);
|
sdcardfs_put_lower_path(dentry, &lower_path);
|
||||||
|
@ -267,11 +282,9 @@ static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
|
||||||
struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
|
struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
|
||||||
const struct cred *saved_cred = NULL;
|
const struct cred *saved_cred = NULL;
|
||||||
struct sdcardfs_inode_info *pi = SDCARDFS_I(dir);
|
struct sdcardfs_inode_info *pi = SDCARDFS_I(dir);
|
||||||
char *page_buf;
|
|
||||||
char *nomedia_dir_name;
|
|
||||||
char *nomedia_fullpath;
|
|
||||||
int fullpath_namelen;
|
|
||||||
int touch_err = 0;
|
int touch_err = 0;
|
||||||
|
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.name)) {
|
||||||
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
|
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
|
||||||
|
@ -302,6 +315,16 @@ static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
|
||||||
|
|
||||||
/* set last 16bytes of mode field to 0775 */
|
/* set last 16bytes of mode field to 0775 */
|
||||||
mode = (mode & S_IFMT) | 00775;
|
mode = (mode & S_IFMT) | 00775;
|
||||||
|
|
||||||
|
/* temporarily change umask for lower fs write */
|
||||||
|
saved_fs = current->fs;
|
||||||
|
copied_fs = copy_fs_struct(current->fs);
|
||||||
|
if (!copied_fs) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
current->fs = copied_fs;
|
||||||
|
current->fs->umask = 0;
|
||||||
err = vfs_mkdir(lower_parent_dentry->d_inode, lower_dentry, mode);
|
err = vfs_mkdir(lower_parent_dentry->d_inode, lower_dentry, mode);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -342,43 +365,18 @@ static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
|
||||||
/* When creating /Android/data and /Android/obb, mark them as .nomedia */
|
/* When creating /Android/data and /Android/obb, mark them as .nomedia */
|
||||||
if (make_nomedia_in_obb ||
|
if (make_nomedia_in_obb ||
|
||||||
((pi->perm == PERM_ANDROID) && (!strcasecmp(dentry->d_name.name, "data")))) {
|
((pi->perm == PERM_ANDROID) && (!strcasecmp(dentry->d_name.name, "data")))) {
|
||||||
|
set_fs_pwd(current->fs, &lower_path);
|
||||||
page_buf = (char *)__get_free_page(GFP_KERNEL);
|
touch_err = touch(".nomedia", 0664);
|
||||||
if (!page_buf) {
|
|
||||||
printk(KERN_ERR "sdcardfs: failed to allocate page buf\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
nomedia_dir_name = d_absolute_path(&lower_path, page_buf, PAGE_SIZE);
|
|
||||||
if (IS_ERR(nomedia_dir_name)) {
|
|
||||||
free_page((unsigned long)page_buf);
|
|
||||||
printk(KERN_ERR "sdcardfs: failed to get .nomedia dir name\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
fullpath_namelen = page_buf + PAGE_SIZE - nomedia_dir_name - 1;
|
|
||||||
fullpath_namelen += strlen("/.nomedia");
|
|
||||||
nomedia_fullpath = kzalloc(fullpath_namelen + 1, GFP_KERNEL);
|
|
||||||
if (!nomedia_fullpath) {
|
|
||||||
free_page((unsigned long)page_buf);
|
|
||||||
printk(KERN_ERR "sdcardfs: failed to allocate .nomedia fullpath buf\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(nomedia_fullpath, nomedia_dir_name);
|
|
||||||
free_page((unsigned long)page_buf);
|
|
||||||
strcat(nomedia_fullpath, "/.nomedia");
|
|
||||||
touch_err = touch(nomedia_fullpath, 0664);
|
|
||||||
if (touch_err) {
|
if (touch_err) {
|
||||||
printk(KERN_ERR "sdcardfs: failed to touch(%s): %d\n",
|
printk(KERN_ERR "sdcardfs: failed to create .nomedia in %s: %d\n",
|
||||||
nomedia_fullpath, touch_err);
|
lower_path.dentry->d_name.name, touch_err);
|
||||||
kfree(nomedia_fullpath);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
kfree(nomedia_fullpath);
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
mnt_drop_write(lower_path.mnt);
|
mnt_drop_write(lower_path.mnt);
|
||||||
|
current->fs = saved_fs;
|
||||||
|
free_fs_struct(copied_fs);
|
||||||
out_unlock:
|
out_unlock:
|
||||||
unlock_dir(lower_parent_dentry);
|
unlock_dir(lower_parent_dentry);
|
||||||
sdcardfs_put_lower_path(dentry, &lower_path);
|
sdcardfs_put_lower_path(dentry, &lower_path);
|
||||||
|
|
Loading…
Reference in a new issue