aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-03-08 11:49:24 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-03-08 11:49:24 -0500
commit9446389ef612096704fdf18fa79bab423d4110f0 (patch)
tree3e4fda7270be58ae176d20d318e61fb115b325b5 /fs/nfs
parentcdd0972945dbcb8ea24db365d9b0e100af2a27bb (diff)
parent84c6f6046c5a2189160a8f0dca8b90427bf690ea (diff)
Merge commit 'origin' into devel
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/nfs/inode.c6
-rw-r--r--fs/nfs/internal.h3
-rw-r--r--fs/nfs/super.c64
4 files changed, 71 insertions, 4 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index ae04892a5e5d..6cea7479c5b4 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -710,6 +710,8 @@ int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
710{ 710{
711 struct nfs_server *server = NFS_SERVER(inode); 711 struct nfs_server *server = NFS_SERVER(inode);
712 712
713 if (test_bit(NFS_INO_MOUNTPOINT, &NFS_I(inode)->flags))
714 return 0;
713 if (nd != NULL) { 715 if (nd != NULL) {
714 /* VFS wants an on-the-wire revalidation */ 716 /* VFS wants an on-the-wire revalidation */
715 if (nd->flags & LOOKUP_REVAL) 717 if (nd->flags & LOOKUP_REVAL)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 36cb99985d22..c49f6d8b42d2 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -299,6 +299,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
299 else 299 else
300 inode->i_op = &nfs_mountpoint_inode_operations; 300 inode->i_op = &nfs_mountpoint_inode_operations;
301 inode->i_fop = NULL; 301 inode->i_fop = NULL;
302 set_bit(NFS_INO_MOUNTPOINT, &nfsi->flags);
302 } 303 }
303 } else if (S_ISLNK(inode->i_mode)) 304 } else if (S_ISLNK(inode->i_mode))
304 inode->i_op = &nfs_symlink_inode_operations; 305 inode->i_op = &nfs_symlink_inode_operations;
@@ -1007,8 +1008,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1007 1008
1008 server = NFS_SERVER(inode); 1009 server = NFS_SERVER(inode);
1009 /* Update the fsid? */ 1010 /* Update the fsid? */
1010 if (S_ISDIR(inode->i_mode) 1011 if (S_ISDIR(inode->i_mode) &&
1011 && !nfs_fsid_equal(&server->fsid, &fattr->fsid)) 1012 !nfs_fsid_equal(&server->fsid, &fattr->fsid) &&
1013 !test_bit(NFS_INO_MOUNTPOINT, &nfsi->flags))
1012 server->fsid = fattr->fsid; 1014 server->fsid = fattr->fsid;
1013 1015
1014 /* 1016 /*
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 985dc2931031..4c1122a13844 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -3,6 +3,7 @@
3 */ 3 */
4 4
5#include <linux/mount.h> 5#include <linux/mount.h>
6#include <linux/security.h>
6 7
7struct nfs_string; 8struct nfs_string;
8 9
@@ -57,6 +58,8 @@ struct nfs_parsed_mount_data {
57 char *export_path; 58 char *export_path;
58 int protocol; 59 int protocol;
59 } nfs_server; 60 } nfs_server;
61
62 struct security_mnt_opts lsm_opts;
60}; 63};
61 64
62/* client.c */ 65/* client.c */
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 1fb381843650..fcf4b982c885 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -684,8 +684,9 @@ static void nfs_parse_server_address(char *value,
684static int nfs_parse_mount_options(char *raw, 684static int nfs_parse_mount_options(char *raw,
685 struct nfs_parsed_mount_data *mnt) 685 struct nfs_parsed_mount_data *mnt)
686{ 686{
687 char *p, *string; 687 char *p, *string, *secdata;
688 unsigned short port = 0; 688 unsigned short port = 0;
689 int rc;
689 690
690 if (!raw) { 691 if (!raw) {
691 dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 692 dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
@@ -693,6 +694,20 @@ static int nfs_parse_mount_options(char *raw,
693 } 694 }
694 dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); 695 dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
695 696
697 secdata = alloc_secdata();
698 if (!secdata)
699 goto out_nomem;
700
701 rc = security_sb_copy_data(raw, secdata);
702 if (rc)
703 goto out_security_failure;
704
705 rc = security_sb_parse_opts_str(secdata, &mnt->lsm_opts);
706 if (rc)
707 goto out_security_failure;
708
709 free_secdata(secdata);
710
696 while ((p = strsep(&raw, ",")) != NULL) { 711 while ((p = strsep(&raw, ",")) != NULL) {
697 substring_t args[MAX_OPT_ARGS]; 712 substring_t args[MAX_OPT_ARGS];
698 int option, token; 713 int option, token;
@@ -1042,7 +1057,10 @@ static int nfs_parse_mount_options(char *raw,
1042out_nomem: 1057out_nomem:
1043 printk(KERN_INFO "NFS: not enough memory to parse option\n"); 1058 printk(KERN_INFO "NFS: not enough memory to parse option\n");
1044 return 0; 1059 return 0;
1045 1060out_security_failure:
1061 free_secdata(secdata);
1062 printk(KERN_INFO "NFS: security options invalid: %d\n", rc);
1063 return 0;
1046out_unrec_vers: 1064out_unrec_vers:
1047 printk(KERN_INFO "NFS: unrecognized NFS version number\n"); 1065 printk(KERN_INFO "NFS: unrecognized NFS version number\n");
1048 return 0; 1066 return 0;
@@ -1214,6 +1232,33 @@ static int nfs_validate_mount_data(void *options,
1214 args->namlen = data->namlen; 1232 args->namlen = data->namlen;
1215 args->bsize = data->bsize; 1233 args->bsize = data->bsize;
1216 args->auth_flavors[0] = data->pseudoflavor; 1234 args->auth_flavors[0] = data->pseudoflavor;
1235
1236 /*
1237 * The legacy version 6 binary mount data from userspace has a
1238 * field used only to transport selinux information into the
1239 * the kernel. To continue to support that functionality we
1240 * have a touch of selinux knowledge here in the NFS code. The
1241 * userspace code converted context=blah to just blah so we are
1242 * converting back to the full string selinux understands.
1243 */
1244 if (data->context[0]){
1245#ifdef CONFIG_SECURITY_SELINUX
1246 int rc;
1247 char *opts_str = kmalloc(sizeof(data->context) + 8, GFP_KERNEL);
1248 if (!opts_str)
1249 return -ENOMEM;
1250 strcpy(opts_str, "context=");
1251 data->context[NFS_MAX_CONTEXT_LEN] = '\0';
1252 strcat(opts_str, &data->context[0]);
1253 rc = security_sb_parse_opts_str(opts_str, &args->lsm_opts);
1254 kfree(opts_str);
1255 if (rc)
1256 return rc;
1257#else
1258 return -EINVAL;
1259#endif
1260 }
1261
1217 break; 1262 break;
1218 default: { 1263 default: {
1219 unsigned int len; 1264 unsigned int len;
@@ -1476,6 +1521,8 @@ static int nfs_get_sb(struct file_system_type *fs_type,
1476 }; 1521 };
1477 int error; 1522 int error;
1478 1523
1524 security_init_mnt_opts(&data.lsm_opts);
1525
1479 /* Validate the mount data */ 1526 /* Validate the mount data */
1480 error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name); 1527 error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name);
1481 if (error < 0) 1528 if (error < 0)
@@ -1515,6 +1562,10 @@ static int nfs_get_sb(struct file_system_type *fs_type,
1515 goto error_splat_super; 1562 goto error_splat_super;
1516 } 1563 }
1517 1564
1565 error = security_sb_set_mnt_opts(s, &data.lsm_opts);
1566 if (error)
1567 goto error_splat_root;
1568
1518 s->s_flags |= MS_ACTIVE; 1569 s->s_flags |= MS_ACTIVE;
1519 mnt->mnt_sb = s; 1570 mnt->mnt_sb = s;
1520 mnt->mnt_root = mntroot; 1571 mnt->mnt_root = mntroot;
@@ -1523,12 +1574,15 @@ static int nfs_get_sb(struct file_system_type *fs_type,
1523out: 1574out:
1524 kfree(data.nfs_server.hostname); 1575 kfree(data.nfs_server.hostname);
1525 kfree(data.mount_server.hostname); 1576 kfree(data.mount_server.hostname);
1577 security_free_mnt_opts(&data.lsm_opts);
1526 return error; 1578 return error;
1527 1579
1528out_err_nosb: 1580out_err_nosb:
1529 nfs_free_server(server); 1581 nfs_free_server(server);
1530 goto out; 1582 goto out;
1531 1583
1584error_splat_root:
1585 dput(mntroot);
1532error_splat_super: 1586error_splat_super:
1533 up_write(&s->s_umount); 1587 up_write(&s->s_umount);
1534 deactivate_super(s); 1588 deactivate_super(s);
@@ -1608,6 +1662,9 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
1608 mnt->mnt_sb = s; 1662 mnt->mnt_sb = s;
1609 mnt->mnt_root = mntroot; 1663 mnt->mnt_root = mntroot;
1610 1664
1665 /* clone any lsm security options from the parent to the new sb */
1666 security_sb_clone_mnt_opts(data->sb, s);
1667
1611 dprintk("<-- nfs_xdev_get_sb() = 0\n"); 1668 dprintk("<-- nfs_xdev_get_sb() = 0\n");
1612 return 0; 1669 return 0;
1613 1670
@@ -1850,6 +1907,8 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
1850 }; 1907 };
1851 int error; 1908 int error;
1852 1909
1910 security_init_mnt_opts(&data.lsm_opts);
1911
1853 /* Validate the mount data */ 1912 /* Validate the mount data */
1854 error = nfs4_validate_mount_data(raw_data, &data, dev_name); 1913 error = nfs4_validate_mount_data(raw_data, &data, dev_name);
1855 if (error < 0) 1914 if (error < 0)
@@ -1898,6 +1957,7 @@ out:
1898 kfree(data.client_address); 1957 kfree(data.client_address);
1899 kfree(data.nfs_server.export_path); 1958 kfree(data.nfs_server.export_path);
1900 kfree(data.nfs_server.hostname); 1959 kfree(data.nfs_server.hostname);
1960 security_free_mnt_opts(&data.lsm_opts);
1901 return error; 1961 return error;
1902 1962
1903out_free: 1963out_free: