CacheFiles: Add calls to path-based security hooks
Add calls to path-based security hooks into CacheFiles as, unlike inode-based security, these aren't implicit in the vfs_mkdir() and similar calls. Reported-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
parent
ced3b93018
commit
821404434f
|
@ -275,6 +275,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
|
|||
bool preemptive)
|
||||
{
|
||||
struct dentry *grave, *trap;
|
||||
struct path path, path_to_graveyard;
|
||||
char nbuffer[8 + 8 + 1];
|
||||
int ret;
|
||||
|
||||
|
@ -287,10 +288,18 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
|
|||
/* non-directories can just be unlinked */
|
||||
if (!S_ISDIR(rep->d_inode->i_mode)) {
|
||||
_debug("unlink stale object");
|
||||
ret = vfs_unlink(dir->d_inode, rep);
|
||||
|
||||
if (preemptive)
|
||||
cachefiles_mark_object_buried(cache, rep);
|
||||
path.mnt = cache->mnt;
|
||||
path.dentry = dir;
|
||||
ret = security_path_unlink(&path, rep);
|
||||
if (ret < 0) {
|
||||
cachefiles_io_error(cache, "Unlink security error");
|
||||
} else {
|
||||
ret = vfs_unlink(dir->d_inode, rep);
|
||||
|
||||
if (preemptive)
|
||||
cachefiles_mark_object_buried(cache, rep);
|
||||
}
|
||||
|
||||
mutex_unlock(&dir->d_inode->i_mutex);
|
||||
|
||||
|
@ -379,12 +388,23 @@ try_again:
|
|||
}
|
||||
|
||||
/* attempt the rename */
|
||||
ret = vfs_rename(dir->d_inode, rep, cache->graveyard->d_inode, grave);
|
||||
if (ret != 0 && ret != -ENOMEM)
|
||||
cachefiles_io_error(cache, "Rename failed with error %d", ret);
|
||||
path.mnt = cache->mnt;
|
||||
path.dentry = dir;
|
||||
path_to_graveyard.mnt = cache->mnt;
|
||||
path_to_graveyard.dentry = cache->graveyard;
|
||||
ret = security_path_rename(&path, rep, &path_to_graveyard, grave);
|
||||
if (ret < 0) {
|
||||
cachefiles_io_error(cache, "Rename security error %d", ret);
|
||||
} else {
|
||||
ret = vfs_rename(dir->d_inode, rep,
|
||||
cache->graveyard->d_inode, grave);
|
||||
if (ret != 0 && ret != -ENOMEM)
|
||||
cachefiles_io_error(cache,
|
||||
"Rename failed with error %d", ret);
|
||||
|
||||
if (preemptive)
|
||||
cachefiles_mark_object_buried(cache, rep);
|
||||
if (preemptive)
|
||||
cachefiles_mark_object_buried(cache, rep);
|
||||
}
|
||||
|
||||
unlock_rename(cache->graveyard, dir);
|
||||
dput(grave);
|
||||
|
@ -448,6 +468,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
|
|||
{
|
||||
struct cachefiles_cache *cache;
|
||||
struct dentry *dir, *next = NULL;
|
||||
struct path path;
|
||||
unsigned long start;
|
||||
const char *name;
|
||||
int ret, nlen;
|
||||
|
@ -458,6 +479,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
|
|||
|
||||
cache = container_of(parent->fscache.cache,
|
||||
struct cachefiles_cache, cache);
|
||||
path.mnt = cache->mnt;
|
||||
|
||||
ASSERT(parent->dentry);
|
||||
ASSERT(parent->dentry->d_inode);
|
||||
|
@ -511,6 +533,10 @@ lookup_again:
|
|||
if (ret < 0)
|
||||
goto create_error;
|
||||
|
||||
path.dentry = dir;
|
||||
ret = security_path_mkdir(&path, next, 0);
|
||||
if (ret < 0)
|
||||
goto create_error;
|
||||
start = jiffies;
|
||||
ret = vfs_mkdir(dir->d_inode, next, 0);
|
||||
cachefiles_hist(cachefiles_mkdir_histogram, start);
|
||||
|
@ -536,6 +562,10 @@ lookup_again:
|
|||
if (ret < 0)
|
||||
goto create_error;
|
||||
|
||||
path.dentry = dir;
|
||||
ret = security_path_mknod(&path, next, S_IFREG, 0);
|
||||
if (ret < 0)
|
||||
goto create_error;
|
||||
start = jiffies;
|
||||
ret = vfs_create(dir->d_inode, next, S_IFREG, NULL);
|
||||
cachefiles_hist(cachefiles_create_histogram, start);
|
||||
|
@ -692,6 +722,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
|
|||
{
|
||||
struct dentry *subdir;
|
||||
unsigned long start;
|
||||
struct path path;
|
||||
int ret;
|
||||
|
||||
_enter(",,%s", dirname);
|
||||
|
@ -719,6 +750,11 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
|
|||
|
||||
_debug("attempt mkdir");
|
||||
|
||||
path.mnt = cache->mnt;
|
||||
path.dentry = dir;
|
||||
ret = security_path_mkdir(&path, subdir, 0700);
|
||||
if (ret < 0)
|
||||
goto mkdir_error;
|
||||
ret = vfs_mkdir(dir->d_inode, subdir, 0700);
|
||||
if (ret < 0)
|
||||
goto mkdir_error;
|
||||
|
|
|
@ -360,6 +360,7 @@ int security_path_mkdir(struct path *dir, struct dentry *dentry, int mode)
|
|||
return 0;
|
||||
return security_ops->path_mkdir(dir, dentry, mode);
|
||||
}
|
||||
EXPORT_SYMBOL(security_path_mkdir);
|
||||
|
||||
int security_path_rmdir(struct path *dir, struct dentry *dentry)
|
||||
{
|
||||
|
@ -374,6 +375,7 @@ int security_path_unlink(struct path *dir, struct dentry *dentry)
|
|||
return 0;
|
||||
return security_ops->path_unlink(dir, dentry);
|
||||
}
|
||||
EXPORT_SYMBOL(security_path_unlink);
|
||||
|
||||
int security_path_symlink(struct path *dir, struct dentry *dentry,
|
||||
const char *old_name)
|
||||
|
@ -400,6 +402,7 @@ int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
|
|||
return security_ops->path_rename(old_dir, old_dentry, new_dir,
|
||||
new_dentry);
|
||||
}
|
||||
EXPORT_SYMBOL(security_path_rename);
|
||||
|
||||
int security_path_truncate(struct path *path)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue