diff options
-rw-r--r-- | fs/cachefiles/namei.c | 52 | ||||
-rw-r--r-- | security/security.c | 3 |
2 files changed, 47 insertions, 8 deletions
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 42c7fafc8bfe..a0358c2189cb 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c | |||
@@ -275,6 +275,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, | |||
275 | bool preemptive) | 275 | bool preemptive) |
276 | { | 276 | { |
277 | struct dentry *grave, *trap; | 277 | struct dentry *grave, *trap; |
278 | struct path path, path_to_graveyard; | ||
278 | char nbuffer[8 + 8 + 1]; | 279 | char nbuffer[8 + 8 + 1]; |
279 | int ret; | 280 | int ret; |
280 | 281 | ||
@@ -287,10 +288,18 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, | |||
287 | /* non-directories can just be unlinked */ | 288 | /* non-directories can just be unlinked */ |
288 | if (!S_ISDIR(rep->d_inode->i_mode)) { | 289 | if (!S_ISDIR(rep->d_inode->i_mode)) { |
289 | _debug("unlink stale object"); | 290 | _debug("unlink stale object"); |
290 | ret = vfs_unlink(dir->d_inode, rep); | ||
291 | 291 | ||
292 | if (preemptive) | 292 | path.mnt = cache->mnt; |
293 | cachefiles_mark_object_buried(cache, rep); | 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); | ||
299 | |||
300 | if (preemptive) | ||
301 | cachefiles_mark_object_buried(cache, rep); | ||
302 | } | ||
294 | 303 | ||
295 | mutex_unlock(&dir->d_inode->i_mutex); | 304 | mutex_unlock(&dir->d_inode->i_mutex); |
296 | 305 | ||
@@ -379,12 +388,23 @@ try_again: | |||
379 | } | 388 | } |
380 | 389 | ||
381 | /* attempt the rename */ | 390 | /* attempt the rename */ |
382 | ret = vfs_rename(dir->d_inode, rep, cache->graveyard->d_inode, grave); | 391 | path.mnt = cache->mnt; |
383 | if (ret != 0 && ret != -ENOMEM) | 392 | path.dentry = dir; |
384 | cachefiles_io_error(cache, "Rename failed with error %d", ret); | 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) | 405 | if (preemptive) |
387 | cachefiles_mark_object_buried(cache, rep); | 406 | cachefiles_mark_object_buried(cache, rep); |
407 | } | ||
388 | 408 | ||
389 | unlock_rename(cache->graveyard, dir); | 409 | unlock_rename(cache->graveyard, dir); |
390 | dput(grave); | 410 | dput(grave); |
@@ -448,6 +468,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, | |||
448 | { | 468 | { |
449 | struct cachefiles_cache *cache; | 469 | struct cachefiles_cache *cache; |
450 | struct dentry *dir, *next = NULL; | 470 | struct dentry *dir, *next = NULL; |
471 | struct path path; | ||
451 | unsigned long start; | 472 | unsigned long start; |
452 | const char *name; | 473 | const char *name; |
453 | int ret, nlen; | 474 | int ret, nlen; |
@@ -458,6 +479,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, | |||
458 | 479 | ||
459 | cache = container_of(parent->fscache.cache, | 480 | cache = container_of(parent->fscache.cache, |
460 | struct cachefiles_cache, cache); | 481 | struct cachefiles_cache, cache); |
482 | path.mnt = cache->mnt; | ||
461 | 483 | ||
462 | ASSERT(parent->dentry); | 484 | ASSERT(parent->dentry); |
463 | ASSERT(parent->dentry->d_inode); | 485 | ASSERT(parent->dentry->d_inode); |
@@ -511,6 +533,10 @@ lookup_again: | |||
511 | if (ret < 0) | 533 | if (ret < 0) |
512 | goto create_error; | 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 | start = jiffies; | 540 | start = jiffies; |
515 | ret = vfs_mkdir(dir->d_inode, next, 0); | 541 | ret = vfs_mkdir(dir->d_inode, next, 0); |
516 | cachefiles_hist(cachefiles_mkdir_histogram, start); | 542 | cachefiles_hist(cachefiles_mkdir_histogram, start); |
@@ -536,6 +562,10 @@ lookup_again: | |||
536 | if (ret < 0) | 562 | if (ret < 0) |
537 | goto create_error; | 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 | start = jiffies; | 569 | start = jiffies; |
540 | ret = vfs_create(dir->d_inode, next, S_IFREG, NULL); | 570 | ret = vfs_create(dir->d_inode, next, S_IFREG, NULL); |
541 | cachefiles_hist(cachefiles_create_histogram, start); | 571 | cachefiles_hist(cachefiles_create_histogram, start); |
@@ -692,6 +722,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, | |||
692 | { | 722 | { |
693 | struct dentry *subdir; | 723 | struct dentry *subdir; |
694 | unsigned long start; | 724 | unsigned long start; |
725 | struct path path; | ||
695 | int ret; | 726 | int ret; |
696 | 727 | ||
697 | _enter(",,%s", dirname); | 728 | _enter(",,%s", dirname); |
@@ -719,6 +750,11 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, | |||
719 | 750 | ||
720 | _debug("attempt mkdir"); | 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 | ret = vfs_mkdir(dir->d_inode, subdir, 0700); | 758 | ret = vfs_mkdir(dir->d_inode, subdir, 0700); |
723 | if (ret < 0) | 759 | if (ret < 0) |
724 | goto mkdir_error; | 760 | goto mkdir_error; |
diff --git a/security/security.c b/security/security.c index 739e40362f44..b84a89dd59c6 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -360,6 +360,7 @@ int security_path_mkdir(struct path *dir, struct dentry *dentry, int mode) | |||
360 | return 0; | 360 | return 0; |
361 | return security_ops->path_mkdir(dir, dentry, mode); | 361 | return security_ops->path_mkdir(dir, dentry, mode); |
362 | } | 362 | } |
363 | EXPORT_SYMBOL(security_path_mkdir); | ||
363 | 364 | ||
364 | int security_path_rmdir(struct path *dir, struct dentry *dentry) | 365 | int security_path_rmdir(struct path *dir, struct dentry *dentry) |
365 | { | 366 | { |
@@ -374,6 +375,7 @@ int security_path_unlink(struct path *dir, struct dentry *dentry) | |||
374 | return 0; | 375 | return 0; |
375 | return security_ops->path_unlink(dir, dentry); | 376 | return security_ops->path_unlink(dir, dentry); |
376 | } | 377 | } |
378 | EXPORT_SYMBOL(security_path_unlink); | ||
377 | 379 | ||
378 | int security_path_symlink(struct path *dir, struct dentry *dentry, | 380 | int security_path_symlink(struct path *dir, struct dentry *dentry, |
379 | const char *old_name) | 381 | const char *old_name) |
@@ -400,6 +402,7 @@ int security_path_rename(struct path *old_dir, struct dentry *old_dentry, | |||
400 | return security_ops->path_rename(old_dir, old_dentry, new_dir, | 402 | return security_ops->path_rename(old_dir, old_dentry, new_dir, |
401 | new_dentry); | 403 | new_dentry); |
402 | } | 404 | } |
405 | EXPORT_SYMBOL(security_path_rename); | ||
403 | 406 | ||
404 | int security_path_truncate(struct path *path) | 407 | int security_path_truncate(struct path *path) |
405 | { | 408 | { |