Commit 821404434f3324bf23f545050ff64055a149766e

Authored by David Howells
Committed by James Morris
1 parent ced3b93018

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>

Showing 2 changed files with 47 additions and 8 deletions Side-by-side Diff

fs/cachefiles/namei.c
... ... @@ -275,6 +275,7 @@
275 275 bool preemptive)
276 276 {
277 277 struct dentry *grave, *trap;
  278 + struct path path, path_to_graveyard;
278 279 char nbuffer[8 + 8 + 1];
279 280 int ret;
280 281  
281 282  
282 283  
... ... @@ -287,11 +288,19 @@
287 288 /* non-directories can just be unlinked */
288 289 if (!S_ISDIR(rep->d_inode->i_mode)) {
289 290 _debug("unlink stale object");
290   - ret = vfs_unlink(dir->d_inode, rep);
291 291  
292   - if (preemptive)
293   - cachefiles_mark_object_buried(cache, rep);
  292 + path.mnt = cache->mnt;
  293 + path.dentry = dir;
  294 + ret = security_path_unlink(&path, rep);
  295 + if (ret < 0) {
  296 + cachefiles_io_error(cache, "Unlink security error");
  297 + } else {
  298 + ret = vfs_unlink(dir->d_inode, rep);
294 299  
  300 + if (preemptive)
  301 + cachefiles_mark_object_buried(cache, rep);
  302 + }
  303 +
295 304 mutex_unlock(&dir->d_inode->i_mutex);
296 305  
297 306 if (ret == -EIO)
298 307  
... ... @@ -379,12 +388,23 @@
379 388 }
380 389  
381 390 /* attempt the rename */
382   - ret = vfs_rename(dir->d_inode, rep, cache->graveyard->d_inode, grave);
383   - if (ret != 0 && ret != -ENOMEM)
384   - cachefiles_io_error(cache, "Rename failed with error %d", ret);
  391 + path.mnt = cache->mnt;
  392 + path.dentry = dir;
  393 + path_to_graveyard.mnt = cache->mnt;
  394 + path_to_graveyard.dentry = cache->graveyard;
  395 + ret = security_path_rename(&path, rep, &path_to_graveyard, grave);
  396 + if (ret < 0) {
  397 + cachefiles_io_error(cache, "Rename security error %d", ret);
  398 + } else {
  399 + ret = vfs_rename(dir->d_inode, rep,
  400 + cache->graveyard->d_inode, grave);
  401 + if (ret != 0 && ret != -ENOMEM)
  402 + cachefiles_io_error(cache,
  403 + "Rename failed with error %d", ret);
385 404  
386   - if (preemptive)
387   - cachefiles_mark_object_buried(cache, rep);
  405 + if (preemptive)
  406 + cachefiles_mark_object_buried(cache, rep);
  407 + }
388 408  
389 409 unlock_rename(cache->graveyard, dir);
390 410 dput(grave);
... ... @@ -448,6 +468,7 @@
448 468 {
449 469 struct cachefiles_cache *cache;
450 470 struct dentry *dir, *next = NULL;
  471 + struct path path;
451 472 unsigned long start;
452 473 const char *name;
453 474 int ret, nlen;
... ... @@ -458,6 +479,7 @@
458 479  
459 480 cache = container_of(parent->fscache.cache,
460 481 struct cachefiles_cache, cache);
  482 + path.mnt = cache->mnt;
461 483  
462 484 ASSERT(parent->dentry);
463 485 ASSERT(parent->dentry->d_inode);
... ... @@ -511,6 +533,10 @@
511 533 if (ret < 0)
512 534 goto create_error;
513 535  
  536 + path.dentry = dir;
  537 + ret = security_path_mkdir(&path, next, 0);
  538 + if (ret < 0)
  539 + goto create_error;
514 540 start = jiffies;
515 541 ret = vfs_mkdir(dir->d_inode, next, 0);
516 542 cachefiles_hist(cachefiles_mkdir_histogram, start);
... ... @@ -536,6 +562,10 @@
536 562 if (ret < 0)
537 563 goto create_error;
538 564  
  565 + path.dentry = dir;
  566 + ret = security_path_mknod(&path, next, S_IFREG, 0);
  567 + if (ret < 0)
  568 + goto create_error;
539 569 start = jiffies;
540 570 ret = vfs_create(dir->d_inode, next, S_IFREG, NULL);
541 571 cachefiles_hist(cachefiles_create_histogram, start);
... ... @@ -692,6 +722,7 @@
692 722 {
693 723 struct dentry *subdir;
694 724 unsigned long start;
  725 + struct path path;
695 726 int ret;
696 727  
697 728 _enter(",,%s", dirname);
... ... @@ -719,6 +750,11 @@
719 750  
720 751 _debug("attempt mkdir");
721 752  
  753 + path.mnt = cache->mnt;
  754 + path.dentry = dir;
  755 + ret = security_path_mkdir(&path, subdir, 0700);
  756 + if (ret < 0)
  757 + goto mkdir_error;
722 758 ret = vfs_mkdir(dir->d_inode, subdir, 0700);
723 759 if (ret < 0)
724 760 goto mkdir_error;
... ... @@ -360,6 +360,7 @@
360 360 return 0;
361 361 return security_ops->path_mkdir(dir, dentry, mode);
362 362 }
  363 +EXPORT_SYMBOL(security_path_mkdir);
363 364  
364 365 int security_path_rmdir(struct path *dir, struct dentry *dentry)
365 366 {
... ... @@ -374,6 +375,7 @@
374 375 return 0;
375 376 return security_ops->path_unlink(dir, dentry);
376 377 }
  378 +EXPORT_SYMBOL(security_path_unlink);
377 379  
378 380 int security_path_symlink(struct path *dir, struct dentry *dentry,
379 381 const char *old_name)
... ... @@ -400,6 +402,7 @@
400 402 return security_ops->path_rename(old_dir, old_dentry, new_dir,
401 403 new_dentry);
402 404 }
  405 +EXPORT_SYMBOL(security_path_rename);
403 406  
404 407 int security_path_truncate(struct path *path)
405 408 {