Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82140443 authored by David Howells's avatar David Howells Committed by James Morris
Browse files

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: default avatarTetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent ced3b930
Loading
Loading
Loading
Loading
+44 −8
Original line number Original line Diff line number Diff line
@@ -275,6 +275,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
				  bool preemptive)
				  bool preemptive)
{
{
	struct dentry *grave, *trap;
	struct dentry *grave, *trap;
	struct path path, path_to_graveyard;
	char nbuffer[8 + 8 + 1];
	char nbuffer[8 + 8 + 1];
	int ret;
	int ret;


@@ -287,10 +288,18 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
	/* non-directories can just be unlinked */
	/* non-directories can just be unlinked */
	if (!S_ISDIR(rep->d_inode->i_mode)) {
	if (!S_ISDIR(rep->d_inode->i_mode)) {
		_debug("unlink stale object");
		_debug("unlink stale object");

		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);
			ret = vfs_unlink(dir->d_inode, rep);


			if (preemptive)
			if (preemptive)
				cachefiles_mark_object_buried(cache, rep);
				cachefiles_mark_object_buried(cache, rep);
		}


		mutex_unlock(&dir->d_inode->i_mutex);
		mutex_unlock(&dir->d_inode->i_mutex);


@@ -379,12 +388,23 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
	}
	}


	/* attempt the rename */
	/* attempt the rename */
	ret = vfs_rename(dir->d_inode, rep, cache->graveyard->d_inode, grave);
	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)
		if (ret != 0 && ret != -ENOMEM)
		cachefiles_io_error(cache, "Rename failed with error %d", ret);
			cachefiles_io_error(cache,
					    "Rename failed with error %d", ret);


		if (preemptive)
		if (preemptive)
			cachefiles_mark_object_buried(cache, rep);
			cachefiles_mark_object_buried(cache, rep);
	}


	unlock_rename(cache->graveyard, dir);
	unlock_rename(cache->graveyard, dir);
	dput(grave);
	dput(grave);
@@ -448,6 +468,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
{
{
	struct cachefiles_cache *cache;
	struct cachefiles_cache *cache;
	struct dentry *dir, *next = NULL;
	struct dentry *dir, *next = NULL;
	struct path path;
	unsigned long start;
	unsigned long start;
	const char *name;
	const char *name;
	int ret, nlen;
	int ret, nlen;
@@ -458,6 +479,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,


	cache = container_of(parent->fscache.cache,
	cache = container_of(parent->fscache.cache,
			     struct cachefiles_cache, cache);
			     struct cachefiles_cache, cache);
	path.mnt = cache->mnt;


	ASSERT(parent->dentry);
	ASSERT(parent->dentry);
	ASSERT(parent->dentry->d_inode);
	ASSERT(parent->dentry->d_inode);
@@ -511,6 +533,10 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
			if (ret < 0)
			if (ret < 0)
				goto create_error;
				goto create_error;


			path.dentry = dir;
			ret = security_path_mkdir(&path, next, 0);
			if (ret < 0)
				goto create_error;
			start = jiffies;
			start = jiffies;
			ret = vfs_mkdir(dir->d_inode, next, 0);
			ret = vfs_mkdir(dir->d_inode, next, 0);
			cachefiles_hist(cachefiles_mkdir_histogram, start);
			cachefiles_hist(cachefiles_mkdir_histogram, start);
@@ -536,6 +562,10 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
			if (ret < 0)
			if (ret < 0)
				goto create_error;
				goto create_error;


			path.dentry = dir;
			ret = security_path_mknod(&path, next, S_IFREG, 0);
			if (ret < 0)
				goto create_error;
			start = jiffies;
			start = jiffies;
			ret = vfs_create(dir->d_inode, next, S_IFREG, NULL);
			ret = vfs_create(dir->d_inode, next, S_IFREG, NULL);
			cachefiles_hist(cachefiles_create_histogram, start);
			cachefiles_hist(cachefiles_create_histogram, start);
@@ -692,6 +722,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
{
{
	struct dentry *subdir;
	struct dentry *subdir;
	unsigned long start;
	unsigned long start;
	struct path path;
	int ret;
	int ret;


	_enter(",,%s", dirname);
	_enter(",,%s", dirname);
@@ -719,6 +750,11 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,


		_debug("attempt mkdir");
		_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);
		ret = vfs_mkdir(dir->d_inode, subdir, 0700);
		if (ret < 0)
		if (ret < 0)
			goto mkdir_error;
			goto mkdir_error;
+3 −0
Original line number Original line Diff line number Diff line
@@ -360,6 +360,7 @@ int security_path_mkdir(struct path *dir, struct dentry *dentry, int mode)
		return 0;
		return 0;
	return security_ops->path_mkdir(dir, dentry, mode);
	return security_ops->path_mkdir(dir, dentry, mode);
}
}
EXPORT_SYMBOL(security_path_mkdir);


int security_path_rmdir(struct path *dir, struct dentry *dentry)
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 0;
	return security_ops->path_unlink(dir, dentry);
	return security_ops->path_unlink(dir, dentry);
}
}
EXPORT_SYMBOL(security_path_unlink);


int security_path_symlink(struct path *dir, struct dentry *dentry,
int security_path_symlink(struct path *dir, struct dentry *dentry,
			  const char *old_name)
			  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,
	return security_ops->path_rename(old_dir, old_dentry, new_dir,
					 new_dentry);
					 new_dentry);
}
}
EXPORT_SYMBOL(security_path_rename);


int security_path_truncate(struct path *path)
int security_path_truncate(struct path *path)
{
{