aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKentaro Takeda <takedakn@nttdata.co.jp>2008-12-16 23:24:15 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2008-12-31 18:07:37 -0500
commitbe6d3e56a6b9b3a4ee44a0685e39e595073c6f0d (patch)
tree3a770f4cc676efeba443b28caa1ad195eeff49bc
parent6a94cb73064c952255336cc57731904174b2c58f (diff)
introduce new LSM hooks where vfsmount is available.
Add new LSM hooks for path-based checks. Call them on directory-modifying operations at the points where we still know the vfsmount involved. Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: Toshiharu Harada <haradats@nttdata.co.jp> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/namei.c36
-rw-r--r--fs/open.c5
-rw-r--r--include/linux/security.h137
-rw-r--r--net/unix/af_unix.c4
-rw-r--r--security/Kconfig9
-rw-r--r--security/capability.c57
-rw-r--r--security/security.c66
7 files changed, 314 insertions, 0 deletions
diff --git a/fs/namei.c b/fs/namei.c
index af3783fff1de..ab441af4196b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1556,6 +1556,9 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1556 * Refuse to truncate files with mandatory locks held on them. 1556 * Refuse to truncate files with mandatory locks held on them.
1557 */ 1557 */
1558 error = locks_verify_locked(inode); 1558 error = locks_verify_locked(inode);
1559 if (!error)
1560 error = security_path_truncate(&nd->path, 0,
1561 ATTR_MTIME|ATTR_CTIME|ATTR_OPEN);
1559 if (!error) { 1562 if (!error) {
1560 DQUOT_INIT(inode); 1563 DQUOT_INIT(inode);
1561 1564
@@ -1586,7 +1589,11 @@ static int __open_namei_create(struct nameidata *nd, struct path *path,
1586 1589
1587 if (!IS_POSIXACL(dir->d_inode)) 1590 if (!IS_POSIXACL(dir->d_inode))
1588 mode &= ~current->fs->umask; 1591 mode &= ~current->fs->umask;
1592 error = security_path_mknod(&nd->path, path->dentry, mode, 0);
1593 if (error)
1594 goto out_unlock;
1589 error = vfs_create(dir->d_inode, path->dentry, mode, nd); 1595 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
1596out_unlock:
1590 mutex_unlock(&dir->d_inode->i_mutex); 1597 mutex_unlock(&dir->d_inode->i_mutex);
1591 dput(nd->path.dentry); 1598 dput(nd->path.dentry);
1592 nd->path.dentry = path->dentry; 1599 nd->path.dentry = path->dentry;
@@ -1999,6 +2006,9 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
1999 error = mnt_want_write(nd.path.mnt); 2006 error = mnt_want_write(nd.path.mnt);
2000 if (error) 2007 if (error)
2001 goto out_dput; 2008 goto out_dput;
2009 error = security_path_mknod(&nd.path, dentry, mode, dev);
2010 if (error)
2011 goto out_drop_write;
2002 switch (mode & S_IFMT) { 2012 switch (mode & S_IFMT) {
2003 case 0: case S_IFREG: 2013 case 0: case S_IFREG:
2004 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); 2014 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
@@ -2011,6 +2021,7 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
2011 error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); 2021 error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0);
2012 break; 2022 break;
2013 } 2023 }
2024out_drop_write:
2014 mnt_drop_write(nd.path.mnt); 2025 mnt_drop_write(nd.path.mnt);
2015out_dput: 2026out_dput:
2016 dput(dentry); 2027 dput(dentry);
@@ -2070,7 +2081,11 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode)
2070 error = mnt_want_write(nd.path.mnt); 2081 error = mnt_want_write(nd.path.mnt);
2071 if (error) 2082 if (error)
2072 goto out_dput; 2083 goto out_dput;
2084 error = security_path_mkdir(&nd.path, dentry, mode);
2085 if (error)
2086 goto out_drop_write;
2073 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); 2087 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
2088out_drop_write:
2074 mnt_drop_write(nd.path.mnt); 2089 mnt_drop_write(nd.path.mnt);
2075out_dput: 2090out_dput:
2076 dput(dentry); 2091 dput(dentry);
@@ -2180,7 +2195,11 @@ static long do_rmdir(int dfd, const char __user *pathname)
2180 error = mnt_want_write(nd.path.mnt); 2195 error = mnt_want_write(nd.path.mnt);
2181 if (error) 2196 if (error)
2182 goto exit3; 2197 goto exit3;
2198 error = security_path_rmdir(&nd.path, dentry);
2199 if (error)
2200 goto exit4;
2183 error = vfs_rmdir(nd.path.dentry->d_inode, dentry); 2201 error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
2202exit4:
2184 mnt_drop_write(nd.path.mnt); 2203 mnt_drop_write(nd.path.mnt);
2185exit3: 2204exit3:
2186 dput(dentry); 2205 dput(dentry);
@@ -2265,7 +2284,11 @@ static long do_unlinkat(int dfd, const char __user *pathname)
2265 error = mnt_want_write(nd.path.mnt); 2284 error = mnt_want_write(nd.path.mnt);
2266 if (error) 2285 if (error)
2267 goto exit2; 2286 goto exit2;
2287 error = security_path_unlink(&nd.path, dentry);
2288 if (error)
2289 goto exit3;
2268 error = vfs_unlink(nd.path.dentry->d_inode, dentry); 2290 error = vfs_unlink(nd.path.dentry->d_inode, dentry);
2291exit3:
2269 mnt_drop_write(nd.path.mnt); 2292 mnt_drop_write(nd.path.mnt);
2270 exit2: 2293 exit2:
2271 dput(dentry); 2294 dput(dentry);
@@ -2346,7 +2369,11 @@ asmlinkage long sys_symlinkat(const char __user *oldname,
2346 error = mnt_want_write(nd.path.mnt); 2369 error = mnt_want_write(nd.path.mnt);
2347 if (error) 2370 if (error)
2348 goto out_dput; 2371 goto out_dput;
2372 error = security_path_symlink(&nd.path, dentry, from);
2373 if (error)
2374 goto out_drop_write;
2349 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); 2375 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
2376out_drop_write:
2350 mnt_drop_write(nd.path.mnt); 2377 mnt_drop_write(nd.path.mnt);
2351out_dput: 2378out_dput:
2352 dput(dentry); 2379 dput(dentry);
@@ -2443,7 +2470,11 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
2443 error = mnt_want_write(nd.path.mnt); 2470 error = mnt_want_write(nd.path.mnt);
2444 if (error) 2471 if (error)
2445 goto out_dput; 2472 goto out_dput;
2473 error = security_path_link(old_path.dentry, &nd.path, new_dentry);
2474 if (error)
2475 goto out_drop_write;
2446 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); 2476 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
2477out_drop_write:
2447 mnt_drop_write(nd.path.mnt); 2478 mnt_drop_write(nd.path.mnt);
2448out_dput: 2479out_dput:
2449 dput(new_dentry); 2480 dput(new_dentry);
@@ -2679,8 +2710,13 @@ asmlinkage long sys_renameat(int olddfd, const char __user *oldname,
2679 error = mnt_want_write(oldnd.path.mnt); 2710 error = mnt_want_write(oldnd.path.mnt);
2680 if (error) 2711 if (error)
2681 goto exit5; 2712 goto exit5;
2713 error = security_path_rename(&oldnd.path, old_dentry,
2714 &newnd.path, new_dentry);
2715 if (error)
2716 goto exit6;
2682 error = vfs_rename(old_dir->d_inode, old_dentry, 2717 error = vfs_rename(old_dir->d_inode, old_dentry,
2683 new_dir->d_inode, new_dentry); 2718 new_dir->d_inode, new_dentry);
2719exit6:
2684 mnt_drop_write(oldnd.path.mnt); 2720 mnt_drop_write(oldnd.path.mnt);
2685exit5: 2721exit5:
2686 dput(new_dentry); 2722 dput(new_dentry);
diff --git a/fs/open.c b/fs/open.c
index c0a426d5766c..1cd7d40e9991 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -272,6 +272,8 @@ static long do_sys_truncate(const char __user *pathname, loff_t length)
272 goto put_write_and_out; 272 goto put_write_and_out;
273 273
274 error = locks_verify_truncate(inode, NULL, length); 274 error = locks_verify_truncate(inode, NULL, length);
275 if (!error)
276 error = security_path_truncate(&path, length, 0);
275 if (!error) { 277 if (!error) {
276 DQUOT_INIT(inode); 278 DQUOT_INIT(inode);
277 error = do_truncate(path.dentry, length, 0, NULL); 279 error = do_truncate(path.dentry, length, 0, NULL);
@@ -329,6 +331,9 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
329 331
330 error = locks_verify_truncate(inode, file, length); 332 error = locks_verify_truncate(inode, file, length);
331 if (!error) 333 if (!error)
334 error = security_path_truncate(&file->f_path, length,
335 ATTR_MTIME|ATTR_CTIME);
336 if (!error)
332 error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); 337 error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
333out_putf: 338out_putf:
334 fput(file); 339 fput(file);
diff --git a/include/linux/security.h b/include/linux/security.h
index 3416cb85e77b..b92b5e453f64 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -335,17 +335,37 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
335 * @dir contains the inode structure of the parent directory of the new link. 335 * @dir contains the inode structure of the parent directory of the new link.
336 * @new_dentry contains the dentry structure for the new link. 336 * @new_dentry contains the dentry structure for the new link.
337 * Return 0 if permission is granted. 337 * Return 0 if permission is granted.
338 * @path_link:
339 * Check permission before creating a new hard link to a file.
340 * @old_dentry contains the dentry structure for an existing link
341 * to the file.
342 * @new_dir contains the path structure of the parent directory of
343 * the new link.
344 * @new_dentry contains the dentry structure for the new link.
345 * Return 0 if permission is granted.
338 * @inode_unlink: 346 * @inode_unlink:
339 * Check the permission to remove a hard link to a file. 347 * Check the permission to remove a hard link to a file.
340 * @dir contains the inode structure of parent directory of the file. 348 * @dir contains the inode structure of parent directory of the file.
341 * @dentry contains the dentry structure for file to be unlinked. 349 * @dentry contains the dentry structure for file to be unlinked.
342 * Return 0 if permission is granted. 350 * Return 0 if permission is granted.
351 * @path_unlink:
352 * Check the permission to remove a hard link to a file.
353 * @dir contains the path structure of parent directory of the file.
354 * @dentry contains the dentry structure for file to be unlinked.
355 * Return 0 if permission is granted.
343 * @inode_symlink: 356 * @inode_symlink:
344 * Check the permission to create a symbolic link to a file. 357 * Check the permission to create a symbolic link to a file.
345 * @dir contains the inode structure of parent directory of the symbolic link. 358 * @dir contains the inode structure of parent directory of the symbolic link.
346 * @dentry contains the dentry structure of the symbolic link. 359 * @dentry contains the dentry structure of the symbolic link.
347 * @old_name contains the pathname of file. 360 * @old_name contains the pathname of file.
348 * Return 0 if permission is granted. 361 * Return 0 if permission is granted.
362 * @path_symlink:
363 * Check the permission to create a symbolic link to a file.
364 * @dir contains the path structure of parent directory of
365 * the symbolic link.
366 * @dentry contains the dentry structure of the symbolic link.
367 * @old_name contains the pathname of file.
368 * Return 0 if permission is granted.
349 * @inode_mkdir: 369 * @inode_mkdir:
350 * Check permissions to create a new directory in the existing directory 370 * Check permissions to create a new directory in the existing directory
351 * associated with inode strcture @dir. 371 * associated with inode strcture @dir.
@@ -353,11 +373,25 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
353 * @dentry contains the dentry structure of new directory. 373 * @dentry contains the dentry structure of new directory.
354 * @mode contains the mode of new directory. 374 * @mode contains the mode of new directory.
355 * Return 0 if permission is granted. 375 * Return 0 if permission is granted.
376 * @path_mkdir:
377 * Check permissions to create a new directory in the existing directory
378 * associated with path strcture @path.
379 * @dir containst the path structure of parent of the directory
380 * to be created.
381 * @dentry contains the dentry structure of new directory.
382 * @mode contains the mode of new directory.
383 * Return 0 if permission is granted.
356 * @inode_rmdir: 384 * @inode_rmdir:
357 * Check the permission to remove a directory. 385 * Check the permission to remove a directory.
358 * @dir contains the inode structure of parent of the directory to be removed. 386 * @dir contains the inode structure of parent of the directory to be removed.
359 * @dentry contains the dentry structure of directory to be removed. 387 * @dentry contains the dentry structure of directory to be removed.
360 * Return 0 if permission is granted. 388 * Return 0 if permission is granted.
389 * @path_rmdir:
390 * Check the permission to remove a directory.
391 * @dir contains the path structure of parent of the directory to be
392 * removed.
393 * @dentry contains the dentry structure of directory to be removed.
394 * Return 0 if permission is granted.
361 * @inode_mknod: 395 * @inode_mknod:
362 * Check permissions when creating a special file (or a socket or a fifo 396 * Check permissions when creating a special file (or a socket or a fifo
363 * file created via the mknod system call). Note that if mknod operation 397 * file created via the mknod system call). Note that if mknod operation
@@ -368,6 +402,15 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
368 * @mode contains the mode of the new file. 402 * @mode contains the mode of the new file.
369 * @dev contains the device number. 403 * @dev contains the device number.
370 * Return 0 if permission is granted. 404 * Return 0 if permission is granted.
405 * @path_mknod:
406 * Check permissions when creating a file. Note that this hook is called
407 * even if mknod operation is being done for a regular file.
408 * @dir contains the path structure of parent of the new file.
409 * @dentry contains the dentry structure of the new file.
410 * @mode contains the mode of the new file.
411 * @dev contains the undecoded device number. Use new_decode_dev() to get
412 * the decoded device number.
413 * Return 0 if permission is granted.
371 * @inode_rename: 414 * @inode_rename:
372 * Check for permission to rename a file or directory. 415 * Check for permission to rename a file or directory.
373 * @old_dir contains the inode structure for parent of the old link. 416 * @old_dir contains the inode structure for parent of the old link.
@@ -375,6 +418,13 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
375 * @new_dir contains the inode structure for parent of the new link. 418 * @new_dir contains the inode structure for parent of the new link.
376 * @new_dentry contains the dentry structure of the new link. 419 * @new_dentry contains the dentry structure of the new link.
377 * Return 0 if permission is granted. 420 * Return 0 if permission is granted.
421 * @path_rename:
422 * Check for permission to rename a file or directory.
423 * @old_dir contains the path structure for parent of the old link.
424 * @old_dentry contains the dentry structure of the old link.
425 * @new_dir contains the path structure for parent of the new link.
426 * @new_dentry contains the dentry structure of the new link.
427 * Return 0 if permission is granted.
378 * @inode_readlink: 428 * @inode_readlink:
379 * Check the permission to read the symbolic link. 429 * Check the permission to read the symbolic link.
380 * @dentry contains the dentry structure for the file link. 430 * @dentry contains the dentry structure for the file link.
@@ -403,6 +453,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
403 * @dentry contains the dentry structure for the file. 453 * @dentry contains the dentry structure for the file.
404 * @attr is the iattr structure containing the new file attributes. 454 * @attr is the iattr structure containing the new file attributes.
405 * Return 0 if permission is granted. 455 * Return 0 if permission is granted.
456 * @path_truncate:
457 * Check permission before truncating a file.
458 * @path contains the path structure for the file.
459 * @length is the new length of the file.
460 * @time_attrs is the flags passed to do_truncate().
461 * Return 0 if permission is granted.
406 * @inode_getattr: 462 * @inode_getattr:
407 * Check permission before obtaining file attributes. 463 * Check permission before obtaining file attributes.
408 * @mnt is the vfsmount where the dentry was looked up 464 * @mnt is the vfsmount where the dentry was looked up
@@ -1331,6 +1387,22 @@ struct security_operations {
1331 struct super_block *newsb); 1387 struct super_block *newsb);
1332 int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts); 1388 int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts);
1333 1389
1390#ifdef CONFIG_SECURITY_PATH
1391 int (*path_unlink) (struct path *dir, struct dentry *dentry);
1392 int (*path_mkdir) (struct path *dir, struct dentry *dentry, int mode);
1393 int (*path_rmdir) (struct path *dir, struct dentry *dentry);
1394 int (*path_mknod) (struct path *dir, struct dentry *dentry, int mode,
1395 unsigned int dev);
1396 int (*path_truncate) (struct path *path, loff_t length,
1397 unsigned int time_attrs);
1398 int (*path_symlink) (struct path *dir, struct dentry *dentry,
1399 const char *old_name);
1400 int (*path_link) (struct dentry *old_dentry, struct path *new_dir,
1401 struct dentry *new_dentry);
1402 int (*path_rename) (struct path *old_dir, struct dentry *old_dentry,
1403 struct path *new_dir, struct dentry *new_dentry);
1404#endif
1405
1334 int (*inode_alloc_security) (struct inode *inode); 1406 int (*inode_alloc_security) (struct inode *inode);
1335 void (*inode_free_security) (struct inode *inode); 1407 void (*inode_free_security) (struct inode *inode);
1336 int (*inode_init_security) (struct inode *inode, struct inode *dir, 1408 int (*inode_init_security) (struct inode *inode, struct inode *dir,
@@ -2705,6 +2777,71 @@ static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi
2705 2777
2706#endif /* CONFIG_SECURITY_NETWORK_XFRM */ 2778#endif /* CONFIG_SECURITY_NETWORK_XFRM */
2707 2779
2780#ifdef CONFIG_SECURITY_PATH
2781int security_path_unlink(struct path *dir, struct dentry *dentry);
2782int security_path_mkdir(struct path *dir, struct dentry *dentry, int mode);
2783int security_path_rmdir(struct path *dir, struct dentry *dentry);
2784int security_path_mknod(struct path *dir, struct dentry *dentry, int mode,
2785 unsigned int dev);
2786int security_path_truncate(struct path *path, loff_t length,
2787 unsigned int time_attrs);
2788int security_path_symlink(struct path *dir, struct dentry *dentry,
2789 const char *old_name);
2790int security_path_link(struct dentry *old_dentry, struct path *new_dir,
2791 struct dentry *new_dentry);
2792int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
2793 struct path *new_dir, struct dentry *new_dentry);
2794#else /* CONFIG_SECURITY_PATH */
2795static inline int security_path_unlink(struct path *dir, struct dentry *dentry)
2796{
2797 return 0;
2798}
2799
2800static inline int security_path_mkdir(struct path *dir, struct dentry *dentry,
2801 int mode)
2802{
2803 return 0;
2804}
2805
2806static inline int security_path_rmdir(struct path *dir, struct dentry *dentry)
2807{
2808 return 0;
2809}
2810
2811static inline int security_path_mknod(struct path *dir, struct dentry *dentry,
2812 int mode, unsigned int dev)
2813{
2814 return 0;
2815}
2816
2817static inline int security_path_truncate(struct path *path, loff_t length,
2818 unsigned int time_attrs)
2819{
2820 return 0;
2821}
2822
2823static inline int security_path_symlink(struct path *dir, struct dentry *dentry,
2824 const char *old_name)
2825{
2826 return 0;
2827}
2828
2829static inline int security_path_link(struct dentry *old_dentry,
2830 struct path *new_dir,
2831 struct dentry *new_dentry)
2832{
2833 return 0;
2834}
2835
2836static inline int security_path_rename(struct path *old_dir,
2837 struct dentry *old_dentry,
2838 struct path *new_dir,
2839 struct dentry *new_dentry)
2840{
2841 return 0;
2842}
2843#endif /* CONFIG_SECURITY_PATH */
2844
2708#ifdef CONFIG_KEYS 2845#ifdef CONFIG_KEYS
2709#ifdef CONFIG_SECURITY 2846#ifdef CONFIG_SECURITY
2710 2847
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index c6250d0055d2..d1b89820ab4f 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -836,7 +836,11 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
836 err = mnt_want_write(nd.path.mnt); 836 err = mnt_want_write(nd.path.mnt);
837 if (err) 837 if (err)
838 goto out_mknod_dput; 838 goto out_mknod_dput;
839 err = security_path_mknod(&nd.path, dentry, mode, 0);
840 if (err)
841 goto out_mknod_drop_write;
839 err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); 842 err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
843out_mknod_drop_write:
840 mnt_drop_write(nd.path.mnt); 844 mnt_drop_write(nd.path.mnt);
841 if (err) 845 if (err)
842 goto out_mknod_dput; 846 goto out_mknod_dput;
diff --git a/security/Kconfig b/security/Kconfig
index d9f47ce7e207..9438535d7fd0 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -81,6 +81,15 @@ config SECURITY_NETWORK_XFRM
81 IPSec. 81 IPSec.
82 If you are unsure how to answer this question, answer N. 82 If you are unsure how to answer this question, answer N.
83 83
84config SECURITY_PATH
85 bool "Security hooks for pathname based access control"
86 depends on SECURITY
87 help
88 This enables the security hooks for pathname based access control.
89 If enabled, a security module can use these hooks to
90 implement pathname based access controls.
91 If you are unsure how to answer this question, answer N.
92
84config SECURITY_FILE_CAPABILITIES 93config SECURITY_FILE_CAPABILITIES
85 bool "File POSIX Capabilities" 94 bool "File POSIX Capabilities"
86 default n 95 default n
diff --git a/security/capability.c b/security/capability.c
index 2dce66fcb992..c545bd1300b5 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -263,6 +263,53 @@ static void cap_inode_getsecid(const struct inode *inode, u32 *secid)
263 *secid = 0; 263 *secid = 0;
264} 264}
265 265
266#ifdef CONFIG_SECURITY_PATH
267static int cap_path_mknod(struct path *dir, struct dentry *dentry, int mode,
268 unsigned int dev)
269{
270 return 0;
271}
272
273static int cap_path_mkdir(struct path *dir, struct dentry *dentry, int mode)
274{
275 return 0;
276}
277
278static int cap_path_rmdir(struct path *dir, struct dentry *dentry)
279{
280 return 0;
281}
282
283static int cap_path_unlink(struct path *dir, struct dentry *dentry)
284{
285 return 0;
286}
287
288static int cap_path_symlink(struct path *dir, struct dentry *dentry,
289 const char *old_name)
290{
291 return 0;
292}
293
294static int cap_path_link(struct dentry *old_dentry, struct path *new_dir,
295 struct dentry *new_dentry)
296{
297 return 0;
298}
299
300static int cap_path_rename(struct path *old_path, struct dentry *old_dentry,
301 struct path *new_path, struct dentry *new_dentry)
302{
303 return 0;
304}
305
306static int cap_path_truncate(struct path *path, loff_t length,
307 unsigned int time_attrs)
308{
309 return 0;
310}
311#endif
312
266static int cap_file_permission(struct file *file, int mask) 313static int cap_file_permission(struct file *file, int mask)
267{ 314{
268 return 0; 315 return 0;
@@ -883,6 +930,16 @@ void security_fixup_ops(struct security_operations *ops)
883 set_to_cap_if_null(ops, inode_setsecurity); 930 set_to_cap_if_null(ops, inode_setsecurity);
884 set_to_cap_if_null(ops, inode_listsecurity); 931 set_to_cap_if_null(ops, inode_listsecurity);
885 set_to_cap_if_null(ops, inode_getsecid); 932 set_to_cap_if_null(ops, inode_getsecid);
933#ifdef CONFIG_SECURITY_PATH
934 set_to_cap_if_null(ops, path_mknod);
935 set_to_cap_if_null(ops, path_mkdir);
936 set_to_cap_if_null(ops, path_rmdir);
937 set_to_cap_if_null(ops, path_unlink);
938 set_to_cap_if_null(ops, path_symlink);
939 set_to_cap_if_null(ops, path_link);
940 set_to_cap_if_null(ops, path_rename);
941 set_to_cap_if_null(ops, path_truncate);
942#endif
886 set_to_cap_if_null(ops, file_permission); 943 set_to_cap_if_null(ops, file_permission);
887 set_to_cap_if_null(ops, file_alloc_security); 944 set_to_cap_if_null(ops, file_alloc_security);
888 set_to_cap_if_null(ops, file_free_security); 945 set_to_cap_if_null(ops, file_free_security);
diff --git a/security/security.c b/security/security.c
index d85dbb37c972..678d4d07b852 100644
--- a/security/security.c
+++ b/security/security.c
@@ -355,6 +355,72 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
355} 355}
356EXPORT_SYMBOL(security_inode_init_security); 356EXPORT_SYMBOL(security_inode_init_security);
357 357
358#ifdef CONFIG_SECURITY_PATH
359int security_path_mknod(struct path *path, struct dentry *dentry, int mode,
360 unsigned int dev)
361{
362 if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
363 return 0;
364 return security_ops->path_mknod(path, dentry, mode, dev);
365}
366EXPORT_SYMBOL(security_path_mknod);
367
368int security_path_mkdir(struct path *path, struct dentry *dentry, int mode)
369{
370 if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
371 return 0;
372 return security_ops->path_mkdir(path, dentry, mode);
373}
374
375int security_path_rmdir(struct path *path, struct dentry *dentry)
376{
377 if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
378 return 0;
379 return security_ops->path_rmdir(path, dentry);
380}
381
382int security_path_unlink(struct path *path, struct dentry *dentry)
383{
384 if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
385 return 0;
386 return security_ops->path_unlink(path, dentry);
387}
388
389int security_path_symlink(struct path *path, struct dentry *dentry,
390 const char *old_name)
391{
392 if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
393 return 0;
394 return security_ops->path_symlink(path, dentry, old_name);
395}
396
397int security_path_link(struct dentry *old_dentry, struct path *new_dir,
398 struct dentry *new_dentry)
399{
400 if (unlikely(IS_PRIVATE(old_dentry->d_inode)))
401 return 0;
402 return security_ops->path_link(old_dentry, new_dir, new_dentry);
403}
404
405int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
406 struct path *new_dir, struct dentry *new_dentry)
407{
408 if (unlikely(IS_PRIVATE(old_dentry->d_inode) ||
409 (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode))))
410 return 0;
411 return security_ops->path_rename(old_dir, old_dentry, new_dir,
412 new_dentry);
413}
414
415int security_path_truncate(struct path *path, loff_t length,
416 unsigned int time_attrs)
417{
418 if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
419 return 0;
420 return security_ops->path_truncate(path, length, time_attrs);
421}
422#endif
423
358int security_inode_create(struct inode *dir, struct dentry *dentry, int mode) 424int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
359{ 425{
360 if (unlikely(IS_PRIVATE(dir))) 426 if (unlikely(IS_PRIVATE(dir)))