aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-06-28 16:29:51 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-06-28 16:29:51 -0400
commit959d921f5eb8878ea16049a7f6e9bcbb6dfbcb88 (patch)
tree83fb4d2756fab97f508b5dccaac7578ba63a76e0 /fs/nfs/nfs4proc.c
parentf112bb48994e56868870a080773c392f774fa9a2 (diff)
parent7017310ad737880d8520a7fc7e25a26b2e7e37f0 (diff)
Merge branch 'labeled-nfs' into linux-next
* labeled-nfs: NFS: Apply v4.1 capabilities to v4.2 NFS: Add in v4.2 callback operation NFS: Make callbacks minor version generic Kconfig: Add Kconfig entry for Labeled NFS V4 client NFS: Extend NFS xattr handlers to accept the security namespace NFS: Client implementation of Labeled-NFS NFS: Add label lifecycle management NFS:Add labels to client function prototypes NFSv4: Extend fattr bitmaps to support all 3 words NFSv4: Introduce new label structure NFSv4: Add label recommended attribute and NFSv4 flags NFSv4.2: Added NFS v4.2 support to the NFS client SELinux: Add new labeling type native labels LSM: Add flags field to security_sb_set_mnt_opts for in kernel mount data. Security: Add Hook to test if the particular xattr is part of a MAC model. Security: Add hook to calculate context based on a negative dentry. NFS: Add NFSv4.2 protocol constants Conflicts: fs/nfs/nfs4proc.c
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c529
1 files changed, 473 insertions, 56 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6d46f966d169..d95616f140ad 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -77,17 +77,68 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
77static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 77static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
78static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); 78static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
79static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); 79static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
80static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *); 80static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label);
81static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 81static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label);
82static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, 82static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
83 struct nfs_fattr *fattr, struct iattr *sattr, 83 struct nfs_fattr *fattr, struct iattr *sattr,
84 struct nfs4_state *state); 84 struct nfs4_state *state, struct nfs4_label *ilabel,
85 struct nfs4_label *olabel);
85#ifdef CONFIG_NFS_V4_1 86#ifdef CONFIG_NFS_V4_1
86static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *, 87static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *,
87 struct rpc_cred *); 88 struct rpc_cred *);
88static int nfs41_free_stateid(struct nfs_server *, nfs4_stateid *, 89static int nfs41_free_stateid(struct nfs_server *, nfs4_stateid *,
89 struct rpc_cred *); 90 struct rpc_cred *);
90#endif 91#endif
92
93#ifdef CONFIG_NFS_V4_SECURITY_LABEL
94static inline struct nfs4_label *
95nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
96 struct iattr *sattr, struct nfs4_label *label)
97{
98 int err;
99
100 if (label == NULL)
101 return NULL;
102
103 if (nfs_server_capable(dir, NFS_CAP_SECURITY_LABEL) == 0)
104 return NULL;
105
106 if (NFS_SERVER(dir)->nfs_client->cl_minorversion < 2)
107 return NULL;
108
109 err = security_dentry_init_security(dentry, sattr->ia_mode,
110 &dentry->d_name, (void **)&label->label, &label->len);
111 if (err == 0)
112 return label;
113
114 return NULL;
115}
116static inline void
117nfs4_label_release_security(struct nfs4_label *label)
118{
119 if (label)
120 security_release_secctx(label->label, label->len);
121}
122static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)
123{
124 if (label)
125 return server->attr_bitmask;
126
127 return server->attr_bitmask_nl;
128}
129#else
130static inline struct nfs4_label *
131nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
132 struct iattr *sattr, struct nfs4_label *l)
133{ return NULL; }
134static inline void
135nfs4_label_release_security(struct nfs4_label *label)
136{ return; }
137static inline u32 *
138nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)
139{ return server->attr_bitmask; }
140#endif
141
91/* Prevent leaks of NFSv4 errors into userland */ 142/* Prevent leaks of NFSv4 errors into userland */
92static int nfs4_map_errors(int err) 143static int nfs4_map_errors(int err)
93{ 144{
@@ -136,7 +187,10 @@ const u32 nfs4_fattr_bitmap[3] = {
136 | FATTR4_WORD1_SPACE_USED 187 | FATTR4_WORD1_SPACE_USED
137 | FATTR4_WORD1_TIME_ACCESS 188 | FATTR4_WORD1_TIME_ACCESS
138 | FATTR4_WORD1_TIME_METADATA 189 | FATTR4_WORD1_TIME_METADATA
139 | FATTR4_WORD1_TIME_MODIFY 190 | FATTR4_WORD1_TIME_MODIFY,
191#ifdef CONFIG_NFS_V4_SECURITY_LABEL
192 FATTR4_WORD2_SECURITY_LABEL
193#endif
140}; 194};
141 195
142static const u32 nfs4_pnfs_open_bitmap[3] = { 196static const u32 nfs4_pnfs_open_bitmap[3] = {
@@ -163,7 +217,7 @@ static const u32 nfs4_open_noattr_bitmap[3] = {
163 | FATTR4_WORD0_FILEID, 217 | FATTR4_WORD0_FILEID,
164}; 218};
165 219
166const u32 nfs4_statfs_bitmap[2] = { 220const u32 nfs4_statfs_bitmap[3] = {
167 FATTR4_WORD0_FILES_AVAIL 221 FATTR4_WORD0_FILES_AVAIL
168 | FATTR4_WORD0_FILES_FREE 222 | FATTR4_WORD0_FILES_FREE
169 | FATTR4_WORD0_FILES_TOTAL, 223 | FATTR4_WORD0_FILES_TOTAL,
@@ -172,7 +226,7 @@ const u32 nfs4_statfs_bitmap[2] = {
172 | FATTR4_WORD1_SPACE_TOTAL 226 | FATTR4_WORD1_SPACE_TOTAL
173}; 227};
174 228
175const u32 nfs4_pathconf_bitmap[2] = { 229const u32 nfs4_pathconf_bitmap[3] = {
176 FATTR4_WORD0_MAXLINK 230 FATTR4_WORD0_MAXLINK
177 | FATTR4_WORD0_MAXNAME, 231 | FATTR4_WORD0_MAXNAME,
178 0 232 0
@@ -187,7 +241,7 @@ const u32 nfs4_fsinfo_bitmap[3] = { FATTR4_WORD0_MAXFILESIZE
187 FATTR4_WORD2_LAYOUT_BLKSIZE 241 FATTR4_WORD2_LAYOUT_BLKSIZE
188}; 242};
189 243
190const u32 nfs4_fs_locations_bitmap[2] = { 244const u32 nfs4_fs_locations_bitmap[3] = {
191 FATTR4_WORD0_TYPE 245 FATTR4_WORD0_TYPE
192 | FATTR4_WORD0_CHANGE 246 | FATTR4_WORD0_CHANGE
193 | FATTR4_WORD0_SIZE 247 | FATTR4_WORD0_SIZE
@@ -203,7 +257,7 @@ const u32 nfs4_fs_locations_bitmap[2] = {
203 | FATTR4_WORD1_TIME_ACCESS 257 | FATTR4_WORD1_TIME_ACCESS
204 | FATTR4_WORD1_TIME_METADATA 258 | FATTR4_WORD1_TIME_METADATA
205 | FATTR4_WORD1_TIME_MODIFY 259 | FATTR4_WORD1_TIME_MODIFY
206 | FATTR4_WORD1_MOUNTED_ON_FILEID 260 | FATTR4_WORD1_MOUNTED_ON_FILEID,
207}; 261};
208 262
209static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry, 263static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry,
@@ -764,6 +818,7 @@ struct nfs4_opendata {
764 struct nfs4_string owner_name; 818 struct nfs4_string owner_name;
765 struct nfs4_string group_name; 819 struct nfs4_string group_name;
766 struct nfs_fattr f_attr; 820 struct nfs_fattr f_attr;
821 struct nfs4_label *f_label;
767 struct dentry *dir; 822 struct dentry *dir;
768 struct dentry *dentry; 823 struct dentry *dentry;
769 struct nfs4_state_owner *owner; 824 struct nfs4_state_owner *owner;
@@ -809,6 +864,7 @@ nfs4_map_atomic_open_claim(struct nfs_server *server,
809static void nfs4_init_opendata_res(struct nfs4_opendata *p) 864static void nfs4_init_opendata_res(struct nfs4_opendata *p)
810{ 865{
811 p->o_res.f_attr = &p->f_attr; 866 p->o_res.f_attr = &p->f_attr;
867 p->o_res.f_label = p->f_label;
812 p->o_res.seqid = p->o_arg.seqid; 868 p->o_res.seqid = p->o_arg.seqid;
813 p->c_res.seqid = p->c_arg.seqid; 869 p->c_res.seqid = p->c_arg.seqid;
814 p->o_res.server = p->o_arg.server; 870 p->o_res.server = p->o_arg.server;
@@ -820,6 +876,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
820static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, 876static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
821 struct nfs4_state_owner *sp, fmode_t fmode, int flags, 877 struct nfs4_state_owner *sp, fmode_t fmode, int flags,
822 const struct iattr *attrs, 878 const struct iattr *attrs,
879 struct nfs4_label *label,
823 enum open_claim_type4 claim, 880 enum open_claim_type4 claim,
824 gfp_t gfp_mask) 881 gfp_t gfp_mask)
825{ 882{
@@ -831,9 +888,14 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
831 p = kzalloc(sizeof(*p), gfp_mask); 888 p = kzalloc(sizeof(*p), gfp_mask);
832 if (p == NULL) 889 if (p == NULL)
833 goto err; 890 goto err;
891
892 p->f_label = nfs4_label_alloc(server, gfp_mask);
893 if (IS_ERR(p->f_label))
894 goto err_free_p;
895
834 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask); 896 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask);
835 if (p->o_arg.seqid == NULL) 897 if (p->o_arg.seqid == NULL)
836 goto err_free; 898 goto err_free_label;
837 nfs_sb_active(dentry->d_sb); 899 nfs_sb_active(dentry->d_sb);
838 p->dentry = dget(dentry); 900 p->dentry = dget(dentry);
839 p->dir = parent; 901 p->dir = parent;
@@ -854,8 +916,9 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
854 p->o_arg.id.uniquifier = sp->so_seqid.owner_id; 916 p->o_arg.id.uniquifier = sp->so_seqid.owner_id;
855 p->o_arg.name = &dentry->d_name; 917 p->o_arg.name = &dentry->d_name;
856 p->o_arg.server = server; 918 p->o_arg.server = server;
857 p->o_arg.bitmask = server->attr_bitmask; 919 p->o_arg.bitmask = nfs4_bitmask(server, label);
858 p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; 920 p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0];
921 p->o_arg.label = label;
859 p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim); 922 p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim);
860 switch (p->o_arg.claim) { 923 switch (p->o_arg.claim) {
861 case NFS4_OPEN_CLAIM_NULL: 924 case NFS4_OPEN_CLAIM_NULL:
@@ -886,7 +949,10 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
886 nfs4_init_opendata_res(p); 949 nfs4_init_opendata_res(p);
887 kref_init(&p->kref); 950 kref_init(&p->kref);
888 return p; 951 return p;
889err_free: 952
953err_free_label:
954 nfs4_label_free(p->f_label);
955err_free_p:
890 kfree(p); 956 kfree(p);
891err: 957err:
892 dput(parent); 958 dput(parent);
@@ -903,6 +969,9 @@ static void nfs4_opendata_free(struct kref *kref)
903 if (p->state != NULL) 969 if (p->state != NULL)
904 nfs4_put_open_state(p->state); 970 nfs4_put_open_state(p->state);
905 nfs4_put_state_owner(p->owner); 971 nfs4_put_state_owner(p->owner);
972
973 nfs4_label_free(p->f_label);
974
906 dput(p->dir); 975 dput(p->dir);
907 dput(p->dentry); 976 dput(p->dentry);
908 nfs_sb_deactive(sb); 977 nfs_sb_deactive(sb);
@@ -1181,6 +1250,8 @@ _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data)
1181 if (ret) 1250 if (ret)
1182 goto err; 1251 goto err;
1183 1252
1253 nfs_setsecurity(inode, &data->f_attr, data->f_label);
1254
1184 if (data->o_res.delegation_type != 0) 1255 if (data->o_res.delegation_type != 0)
1185 nfs4_opendata_check_deleg(data, state); 1256 nfs4_opendata_check_deleg(data, state);
1186 update_open_stateid(state, &data->o_res.stateid, NULL, 1257 update_open_stateid(state, &data->o_res.stateid, NULL,
@@ -1207,7 +1278,7 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
1207 ret = -EAGAIN; 1278 ret = -EAGAIN;
1208 if (!(data->f_attr.valid & NFS_ATTR_FATTR)) 1279 if (!(data->f_attr.valid & NFS_ATTR_FATTR))
1209 goto err; 1280 goto err;
1210 inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr); 1281 inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr, data->f_label);
1211 ret = PTR_ERR(inode); 1282 ret = PTR_ERR(inode);
1212 if (IS_ERR(inode)) 1283 if (IS_ERR(inode))
1213 goto err; 1284 goto err;
@@ -1260,7 +1331,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
1260 struct nfs4_opendata *opendata; 1331 struct nfs4_opendata *opendata;
1261 1332
1262 opendata = nfs4_opendata_alloc(ctx->dentry, state->owner, 0, 0, 1333 opendata = nfs4_opendata_alloc(ctx->dentry, state->owner, 0, 0,
1263 NULL, claim, GFP_NOFS); 1334 NULL, NULL, claim, GFP_NOFS);
1264 if (opendata == NULL) 1335 if (opendata == NULL)
1265 return ERR_PTR(-ENOMEM); 1336 return ERR_PTR(-ENOMEM);
1266 opendata->state = state; 1337 opendata->state = state;
@@ -1786,7 +1857,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1786 return status; 1857 return status;
1787 } 1858 }
1788 if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) 1859 if (!(o_res->f_attr->valid & NFS_ATTR_FATTR))
1789 _nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr); 1860 _nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr, o_res->f_label);
1790 return 0; 1861 return 0;
1791} 1862}
1792 1863
@@ -2017,7 +2088,8 @@ out:
2017static int _nfs4_do_open(struct inode *dir, 2088static int _nfs4_do_open(struct inode *dir,
2018 struct nfs_open_context *ctx, 2089 struct nfs_open_context *ctx,
2019 int flags, 2090 int flags,
2020 struct iattr *sattr) 2091 struct iattr *sattr,
2092 struct nfs4_label *label)
2021{ 2093{
2022 struct nfs4_state_owner *sp; 2094 struct nfs4_state_owner *sp;
2023 struct nfs4_state *state = NULL; 2095 struct nfs4_state *state = NULL;
@@ -2028,6 +2100,7 @@ static int _nfs4_do_open(struct inode *dir,
2028 struct nfs4_threshold **ctx_th = &ctx->mdsthreshold; 2100 struct nfs4_threshold **ctx_th = &ctx->mdsthreshold;
2029 fmode_t fmode = ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC); 2101 fmode_t fmode = ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC);
2030 enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL; 2102 enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
2103 struct nfs4_label *olabel = NULL;
2031 int status; 2104 int status;
2032 2105
2033 /* Protect against reboot recovery conflicts */ 2106 /* Protect against reboot recovery conflicts */
@@ -2046,14 +2119,22 @@ static int _nfs4_do_open(struct inode *dir,
2046 if (dentry->d_inode) 2119 if (dentry->d_inode)
2047 claim = NFS4_OPEN_CLAIM_FH; 2120 claim = NFS4_OPEN_CLAIM_FH;
2048 opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, sattr, 2121 opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, sattr,
2049 claim, GFP_KERNEL); 2122 label, claim, GFP_KERNEL);
2050 if (opendata == NULL) 2123 if (opendata == NULL)
2051 goto err_put_state_owner; 2124 goto err_put_state_owner;
2052 2125
2126 if (label) {
2127 olabel = nfs4_label_alloc(server, GFP_KERNEL);
2128 if (IS_ERR(olabel)) {
2129 status = PTR_ERR(olabel);
2130 goto err_opendata_put;
2131 }
2132 }
2133
2053 if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) { 2134 if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) {
2054 opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc(); 2135 opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc();
2055 if (!opendata->f_attr.mdsthreshold) 2136 if (!opendata->f_attr.mdsthreshold)
2056 goto err_opendata_put; 2137 goto err_free_label;
2057 opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0]; 2138 opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0];
2058 } 2139 }
2059 if (dentry->d_inode != NULL) 2140 if (dentry->d_inode != NULL)
@@ -2061,7 +2142,7 @@ static int _nfs4_do_open(struct inode *dir,
2061 2142
2062 status = _nfs4_open_and_get_state(opendata, fmode, flags, ctx); 2143 status = _nfs4_open_and_get_state(opendata, fmode, flags, ctx);
2063 if (status != 0) 2144 if (status != 0)
2064 goto err_opendata_put; 2145 goto err_free_label;
2065 state = ctx->state; 2146 state = ctx->state;
2066 2147
2067 if ((opendata->o_arg.open_flags & O_EXCL) && 2148 if ((opendata->o_arg.open_flags & O_EXCL) &&
@@ -2071,10 +2152,12 @@ static int _nfs4_do_open(struct inode *dir,
2071 nfs_fattr_init(opendata->o_res.f_attr); 2152 nfs_fattr_init(opendata->o_res.f_attr);
2072 status = nfs4_do_setattr(state->inode, cred, 2153 status = nfs4_do_setattr(state->inode, cred,
2073 opendata->o_res.f_attr, sattr, 2154 opendata->o_res.f_attr, sattr,
2074 state); 2155 state, label, olabel);
2075 if (status == 0) 2156 if (status == 0) {
2076 nfs_setattr_update_inode(state->inode, sattr); 2157 nfs_setattr_update_inode(state->inode, sattr);
2077 nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); 2158 nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr);
2159 nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel);
2160 }
2078 } 2161 }
2079 2162
2080 if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) 2163 if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server))
@@ -2083,9 +2166,13 @@ static int _nfs4_do_open(struct inode *dir,
2083 kfree(opendata->f_attr.mdsthreshold); 2166 kfree(opendata->f_attr.mdsthreshold);
2084 opendata->f_attr.mdsthreshold = NULL; 2167 opendata->f_attr.mdsthreshold = NULL;
2085 2168
2169 nfs4_label_free(olabel);
2170
2086 nfs4_opendata_put(opendata); 2171 nfs4_opendata_put(opendata);
2087 nfs4_put_state_owner(sp); 2172 nfs4_put_state_owner(sp);
2088 return 0; 2173 return 0;
2174err_free_label:
2175 nfs4_label_free(olabel);
2089err_opendata_put: 2176err_opendata_put:
2090 kfree(opendata->f_attr.mdsthreshold); 2177 kfree(opendata->f_attr.mdsthreshold);
2091 nfs4_opendata_put(opendata); 2178 nfs4_opendata_put(opendata);
@@ -2099,7 +2186,8 @@ out_err:
2099static struct nfs4_state *nfs4_do_open(struct inode *dir, 2186static struct nfs4_state *nfs4_do_open(struct inode *dir,
2100 struct nfs_open_context *ctx, 2187 struct nfs_open_context *ctx,
2101 int flags, 2188 int flags,
2102 struct iattr *sattr) 2189 struct iattr *sattr,
2190 struct nfs4_label *label)
2103{ 2191{
2104 struct nfs_server *server = NFS_SERVER(dir); 2192 struct nfs_server *server = NFS_SERVER(dir);
2105 struct nfs4_exception exception = { }; 2193 struct nfs4_exception exception = { };
@@ -2107,7 +2195,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
2107 int status; 2195 int status;
2108 2196
2109 do { 2197 do {
2110 status = _nfs4_do_open(dir, ctx, flags, sattr); 2198 status = _nfs4_do_open(dir, ctx, flags, sattr, label);
2111 res = ctx->state; 2199 res = ctx->state;
2112 if (status == 0) 2200 if (status == 0)
2113 break; 2201 break;
@@ -2154,7 +2242,8 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
2154 2242
2155static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, 2243static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
2156 struct nfs_fattr *fattr, struct iattr *sattr, 2244 struct nfs_fattr *fattr, struct iattr *sattr,
2157 struct nfs4_state *state) 2245 struct nfs4_state *state, struct nfs4_label *ilabel,
2246 struct nfs4_label *olabel)
2158{ 2247{
2159 struct nfs_server *server = NFS_SERVER(inode); 2248 struct nfs_server *server = NFS_SERVER(inode);
2160 struct nfs_setattrargs arg = { 2249 struct nfs_setattrargs arg = {
@@ -2162,9 +2251,11 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
2162 .iap = sattr, 2251 .iap = sattr,
2163 .server = server, 2252 .server = server,
2164 .bitmask = server->attr_bitmask, 2253 .bitmask = server->attr_bitmask,
2254 .label = ilabel,
2165 }; 2255 };
2166 struct nfs_setattrres res = { 2256 struct nfs_setattrres res = {
2167 .fattr = fattr, 2257 .fattr = fattr,
2258 .label = olabel,
2168 .server = server, 2259 .server = server,
2169 }; 2260 };
2170 struct rpc_message msg = { 2261 struct rpc_message msg = {
@@ -2178,6 +2269,10 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
2178 bool truncate; 2269 bool truncate;
2179 int status; 2270 int status;
2180 2271
2272 arg.bitmask = nfs4_bitmask(server, ilabel);
2273 if (ilabel)
2274 arg.bitmask = nfs4_bitmask(server, olabel);
2275
2181 nfs_fattr_init(fattr); 2276 nfs_fattr_init(fattr);
2182 2277
2183 /* Servers should only apply open mode checks for file size changes */ 2278 /* Servers should only apply open mode checks for file size changes */
@@ -2204,7 +2299,8 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
2204 2299
2205static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, 2300static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
2206 struct nfs_fattr *fattr, struct iattr *sattr, 2301 struct nfs_fattr *fattr, struct iattr *sattr,
2207 struct nfs4_state *state) 2302 struct nfs4_state *state, struct nfs4_label *ilabel,
2303 struct nfs4_label *olabel)
2208{ 2304{
2209 struct nfs_server *server = NFS_SERVER(inode); 2305 struct nfs_server *server = NFS_SERVER(inode);
2210 struct nfs4_exception exception = { 2306 struct nfs4_exception exception = {
@@ -2213,7 +2309,7 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
2213 }; 2309 };
2214 int err; 2310 int err;
2215 do { 2311 do {
2216 err = _nfs4_do_setattr(inode, cred, fattr, sattr, state); 2312 err = _nfs4_do_setattr(inode, cred, fattr, sattr, state, ilabel, olabel);
2217 switch (err) { 2313 switch (err) {
2218 case -NFS4ERR_OPENMODE: 2314 case -NFS4ERR_OPENMODE:
2219 if (!(sattr->ia_valid & ATTR_SIZE)) { 2315 if (!(sattr->ia_valid & ATTR_SIZE)) {
@@ -2458,9 +2554,15 @@ static struct inode *
2458nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags, struct iattr *attr) 2554nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags, struct iattr *attr)
2459{ 2555{
2460 struct nfs4_state *state; 2556 struct nfs4_state *state;
2557 struct nfs4_label l = {0, 0, 0, NULL}, *label = NULL;
2558
2559 label = nfs4_label_init_security(dir, ctx->dentry, attr, &l);
2461 2560
2462 /* Protect against concurrent sillydeletes */ 2561 /* Protect against concurrent sillydeletes */
2463 state = nfs4_do_open(dir, ctx, open_flags, attr); 2562 state = nfs4_do_open(dir, ctx, open_flags, attr, label);
2563
2564 nfs4_label_release_security(label);
2565
2464 if (IS_ERR(state)) 2566 if (IS_ERR(state))
2465 return ERR_CAST(state); 2567 return ERR_CAST(state);
2466 return state->inode; 2568 return state->inode;
@@ -2519,7 +2621,17 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
2519 server->caps |= NFS_CAP_CTIME; 2621 server->caps |= NFS_CAP_CTIME;
2520 if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY) 2622 if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY)
2521 server->caps |= NFS_CAP_MTIME; 2623 server->caps |= NFS_CAP_MTIME;
2624#ifdef CONFIG_NFS_V4_SECURITY_LABEL
2625 if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL)
2626 server->caps |= NFS_CAP_SECURITY_LABEL;
2627#endif
2628 memcpy(server->attr_bitmask_nl, res.attr_bitmask,
2629 sizeof(server->attr_bitmask));
2522 2630
2631 if (server->caps & NFS_CAP_SECURITY_LABEL) {
2632 server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
2633 res.attr_bitmask[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
2634 }
2523 memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask)); 2635 memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask));
2524 server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE; 2636 server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE;
2525 server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; 2637 server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
@@ -2545,8 +2657,9 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
2545static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, 2657static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
2546 struct nfs_fsinfo *info) 2658 struct nfs_fsinfo *info)
2547{ 2659{
2660 u32 bitmask[3];
2548 struct nfs4_lookup_root_arg args = { 2661 struct nfs4_lookup_root_arg args = {
2549 .bitmask = nfs4_fattr_bitmap, 2662 .bitmask = bitmask,
2550 }; 2663 };
2551 struct nfs4_lookup_res res = { 2664 struct nfs4_lookup_res res = {
2552 .server = server, 2665 .server = server,
@@ -2559,6 +2672,13 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
2559 .rpc_resp = &res, 2672 .rpc_resp = &res,
2560 }; 2673 };
2561 2674
2675 bitmask[0] = nfs4_fattr_bitmap[0];
2676 bitmask[1] = nfs4_fattr_bitmap[1];
2677 /*
2678 * Process the label in the upcoming getfattr
2679 */
2680 bitmask[2] = nfs4_fattr_bitmap[2] & ~FATTR4_WORD2_SECURITY_LABEL;
2681
2562 nfs_fattr_init(info->fattr); 2682 nfs_fattr_init(info->fattr);
2563 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); 2683 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
2564} 2684}
@@ -2678,6 +2798,7 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *mntfh,
2678{ 2798{
2679 int error; 2799 int error;
2680 struct nfs_fattr *fattr = info->fattr; 2800 struct nfs_fattr *fattr = info->fattr;
2801 struct nfs4_label *label = NULL;
2681 2802
2682 error = nfs4_server_capabilities(server, mntfh); 2803 error = nfs4_server_capabilities(server, mntfh);
2683 if (error < 0) { 2804 if (error < 0) {
@@ -2685,16 +2806,23 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *mntfh,
2685 return error; 2806 return error;
2686 } 2807 }
2687 2808
2688 error = nfs4_proc_getattr(server, mntfh, fattr); 2809 label = nfs4_label_alloc(server, GFP_KERNEL);
2810 if (IS_ERR(label))
2811 return PTR_ERR(label);
2812
2813 error = nfs4_proc_getattr(server, mntfh, fattr, label);
2689 if (error < 0) { 2814 if (error < 0) {
2690 dprintk("nfs4_get_root: getattr error = %d\n", -error); 2815 dprintk("nfs4_get_root: getattr error = %d\n", -error);
2691 return error; 2816 goto err_free_label;
2692 } 2817 }
2693 2818
2694 if (fattr->valid & NFS_ATTR_FATTR_FSID && 2819 if (fattr->valid & NFS_ATTR_FATTR_FSID &&
2695 !nfs_fsid_equal(&server->fsid, &fattr->fsid)) 2820 !nfs_fsid_equal(&server->fsid, &fattr->fsid))
2696 memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid)); 2821 memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
2697 2822
2823err_free_label:
2824 nfs4_label_free(label);
2825
2698 return error; 2826 return error;
2699} 2827}
2700 2828
@@ -2741,7 +2869,8 @@ out:
2741 return status; 2869 return status;
2742} 2870}
2743 2871
2744static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2872static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
2873 struct nfs_fattr *fattr, struct nfs4_label *label)
2745{ 2874{
2746 struct nfs4_getattr_arg args = { 2875 struct nfs4_getattr_arg args = {
2747 .fh = fhandle, 2876 .fh = fhandle,
@@ -2749,6 +2878,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
2749 }; 2878 };
2750 struct nfs4_getattr_res res = { 2879 struct nfs4_getattr_res res = {
2751 .fattr = fattr, 2880 .fattr = fattr,
2881 .label = label,
2752 .server = server, 2882 .server = server,
2753 }; 2883 };
2754 struct rpc_message msg = { 2884 struct rpc_message msg = {
@@ -2756,18 +2886,21 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
2756 .rpc_argp = &args, 2886 .rpc_argp = &args,
2757 .rpc_resp = &res, 2887 .rpc_resp = &res,
2758 }; 2888 };
2759 2889
2890 args.bitmask = nfs4_bitmask(server, label);
2891
2760 nfs_fattr_init(fattr); 2892 nfs_fattr_init(fattr);
2761 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); 2893 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
2762} 2894}
2763 2895
2764static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2896static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
2897 struct nfs_fattr *fattr, struct nfs4_label *label)
2765{ 2898{
2766 struct nfs4_exception exception = { }; 2899 struct nfs4_exception exception = { };
2767 int err; 2900 int err;
2768 do { 2901 do {
2769 err = nfs4_handle_exception(server, 2902 err = nfs4_handle_exception(server,
2770 _nfs4_proc_getattr(server, fhandle, fattr), 2903 _nfs4_proc_getattr(server, fhandle, fattr, label),
2771 &exception); 2904 &exception);
2772 } while (exception.retry); 2905 } while (exception.retry);
2773 return err; 2906 return err;
@@ -2797,6 +2930,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2797 struct inode *inode = dentry->d_inode; 2930 struct inode *inode = dentry->d_inode;
2798 struct rpc_cred *cred = NULL; 2931 struct rpc_cred *cred = NULL;
2799 struct nfs4_state *state = NULL; 2932 struct nfs4_state *state = NULL;
2933 struct nfs4_label *label = NULL;
2800 int status; 2934 int status;
2801 2935
2802 if (pnfs_ld_layoutret_on_setattr(inode)) 2936 if (pnfs_ld_layoutret_on_setattr(inode))
@@ -2823,15 +2957,22 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2823 } 2957 }
2824 } 2958 }
2825 2959
2826 status = nfs4_do_setattr(inode, cred, fattr, sattr, state); 2960 label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
2827 if (status == 0) 2961 if (IS_ERR(label))
2962 return PTR_ERR(label);
2963
2964 status = nfs4_do_setattr(inode, cred, fattr, sattr, state, NULL, label);
2965 if (status == 0) {
2828 nfs_setattr_update_inode(inode, sattr); 2966 nfs_setattr_update_inode(inode, sattr);
2967 nfs_setsecurity(inode, fattr, label);
2968 }
2969 nfs4_label_free(label);
2829 return status; 2970 return status;
2830} 2971}
2831 2972
2832static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, 2973static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
2833 const struct qstr *name, struct nfs_fh *fhandle, 2974 const struct qstr *name, struct nfs_fh *fhandle,
2834 struct nfs_fattr *fattr) 2975 struct nfs_fattr *fattr, struct nfs4_label *label)
2835{ 2976{
2836 struct nfs_server *server = NFS_SERVER(dir); 2977 struct nfs_server *server = NFS_SERVER(dir);
2837 int status; 2978 int status;
@@ -2843,6 +2984,7 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
2843 struct nfs4_lookup_res res = { 2984 struct nfs4_lookup_res res = {
2844 .server = server, 2985 .server = server,
2845 .fattr = fattr, 2986 .fattr = fattr,
2987 .label = label,
2846 .fh = fhandle, 2988 .fh = fhandle,
2847 }; 2989 };
2848 struct rpc_message msg = { 2990 struct rpc_message msg = {
@@ -2851,6 +2993,8 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
2851 .rpc_resp = &res, 2993 .rpc_resp = &res,
2852 }; 2994 };
2853 2995
2996 args.bitmask = nfs4_bitmask(server, label);
2997
2854 nfs_fattr_init(fattr); 2998 nfs_fattr_init(fattr);
2855 2999
2856 dprintk("NFS call lookup %s\n", name->name); 3000 dprintk("NFS call lookup %s\n", name->name);
@@ -2869,13 +3013,13 @@ static void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr)
2869 3013
2870static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir, 3014static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
2871 struct qstr *name, struct nfs_fh *fhandle, 3015 struct qstr *name, struct nfs_fh *fhandle,
2872 struct nfs_fattr *fattr) 3016 struct nfs_fattr *fattr, struct nfs4_label *label)
2873{ 3017{
2874 struct nfs4_exception exception = { }; 3018 struct nfs4_exception exception = { };
2875 struct rpc_clnt *client = *clnt; 3019 struct rpc_clnt *client = *clnt;
2876 int err; 3020 int err;
2877 do { 3021 do {
2878 err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr); 3022 err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr, label);
2879 switch (err) { 3023 switch (err) {
2880 case -NFS4ERR_BADNAME: 3024 case -NFS4ERR_BADNAME:
2881 err = -ENOENT; 3025 err = -ENOENT;
@@ -2909,12 +3053,13 @@ out:
2909} 3053}
2910 3054
2911static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, 3055static int nfs4_proc_lookup(struct inode *dir, struct qstr *name,
2912 struct nfs_fh *fhandle, struct nfs_fattr *fattr) 3056 struct nfs_fh *fhandle, struct nfs_fattr *fattr,
3057 struct nfs4_label *label)
2913{ 3058{
2914 int status; 3059 int status;
2915 struct rpc_clnt *client = NFS_CLIENT(dir); 3060 struct rpc_clnt *client = NFS_CLIENT(dir);
2916 3061
2917 status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr); 3062 status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, label);
2918 if (client != NFS_CLIENT(dir)) { 3063 if (client != NFS_CLIENT(dir)) {
2919 rpc_shutdown_client(client); 3064 rpc_shutdown_client(client);
2920 nfs_fixup_secinfo_attributes(fattr); 3065 nfs_fixup_secinfo_attributes(fattr);
@@ -2929,7 +3074,7 @@ nfs4_proc_lookup_mountpoint(struct inode *dir, struct qstr *name,
2929 int status; 3074 int status;
2930 struct rpc_clnt *client = rpc_clone_client(NFS_CLIENT(dir)); 3075 struct rpc_clnt *client = rpc_clone_client(NFS_CLIENT(dir));
2931 3076
2932 status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr); 3077 status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, NULL);
2933 if (status < 0) { 3078 if (status < 0) {
2934 rpc_shutdown_client(client); 3079 rpc_shutdown_client(client);
2935 return ERR_PTR(status); 3080 return ERR_PTR(status);
@@ -2954,7 +3099,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
2954 .rpc_cred = entry->cred, 3099 .rpc_cred = entry->cred,
2955 }; 3100 };
2956 int mode = entry->mask; 3101 int mode = entry->mask;
2957 int status; 3102 int status = 0;
2958 3103
2959 /* 3104 /*
2960 * Determine which access bits we want to ask for... 3105 * Determine which access bits we want to ask for...
@@ -3059,6 +3204,7 @@ static int
3059nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, 3204nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
3060 int flags) 3205 int flags)
3061{ 3206{
3207 struct nfs4_label l, *ilabel = NULL;
3062 struct nfs_open_context *ctx; 3208 struct nfs_open_context *ctx;
3063 struct nfs4_state *state; 3209 struct nfs4_state *state;
3064 int status = 0; 3210 int status = 0;
@@ -3067,13 +3213,16 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
3067 if (IS_ERR(ctx)) 3213 if (IS_ERR(ctx))
3068 return PTR_ERR(ctx); 3214 return PTR_ERR(ctx);
3069 3215
3216 ilabel = nfs4_label_init_security(dir, dentry, sattr, &l);
3217
3070 sattr->ia_mode &= ~current_umask(); 3218 sattr->ia_mode &= ~current_umask();
3071 state = nfs4_do_open(dir, ctx, flags, sattr); 3219 state = nfs4_do_open(dir, ctx, flags, sattr, ilabel);
3072 if (IS_ERR(state)) { 3220 if (IS_ERR(state)) {
3073 status = PTR_ERR(state); 3221 status = PTR_ERR(state);
3074 goto out; 3222 goto out;
3075 } 3223 }
3076out: 3224out:
3225 nfs4_label_release_security(ilabel);
3077 put_nfs_open_context(ctx); 3226 put_nfs_open_context(ctx);
3078 return status; 3227 return status;
3079} 3228}
@@ -3122,6 +3271,8 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
3122 res->server = server; 3271 res->server = server;
3123 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; 3272 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
3124 nfs41_init_sequence(&args->seq_args, &res->seq_res, 1); 3273 nfs41_init_sequence(&args->seq_args, &res->seq_res, 1);
3274
3275 nfs_fattr_init(res->dir_attr);
3125} 3276}
3126 3277
3127static void nfs4_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data) 3278static void nfs4_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data)
@@ -3197,7 +3348,7 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
3197 .rpc_resp = &res, 3348 .rpc_resp = &res,
3198 }; 3349 };
3199 int status = -ENOMEM; 3350 int status = -ENOMEM;
3200 3351
3201 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); 3352 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
3202 if (!status) { 3353 if (!status) {
3203 update_changeattr(old_dir, &res.old_cinfo); 3354 update_changeattr(old_dir, &res.old_cinfo);
@@ -3231,6 +3382,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
3231 }; 3382 };
3232 struct nfs4_link_res res = { 3383 struct nfs4_link_res res = {
3233 .server = server, 3384 .server = server,
3385 .label = NULL,
3234 }; 3386 };
3235 struct rpc_message msg = { 3387 struct rpc_message msg = {
3236 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK], 3388 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK],
@@ -3243,11 +3395,24 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
3243 if (res.fattr == NULL) 3395 if (res.fattr == NULL)
3244 goto out; 3396 goto out;
3245 3397
3398 res.label = nfs4_label_alloc(server, GFP_KERNEL);
3399 if (IS_ERR(res.label)) {
3400 status = PTR_ERR(res.label);
3401 goto out;
3402 }
3403 arg.bitmask = nfs4_bitmask(server, res.label);
3404
3246 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); 3405 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
3247 if (!status) { 3406 if (!status) {
3248 update_changeattr(dir, &res.cinfo); 3407 update_changeattr(dir, &res.cinfo);
3249 nfs_post_op_update_inode(inode, res.fattr); 3408 status = nfs_post_op_update_inode(inode, res.fattr);
3409 if (!status)
3410 nfs_setsecurity(inode, res.fattr, res.label);
3250 } 3411 }
3412
3413
3414 nfs4_label_free(res.label);
3415
3251out: 3416out:
3252 nfs_free_fattr(res.fattr); 3417 nfs_free_fattr(res.fattr);
3253 return status; 3418 return status;
@@ -3271,6 +3436,7 @@ struct nfs4_createdata {
3271 struct nfs4_create_res res; 3436 struct nfs4_create_res res;
3272 struct nfs_fh fh; 3437 struct nfs_fh fh;
3273 struct nfs_fattr fattr; 3438 struct nfs_fattr fattr;
3439 struct nfs4_label *label;
3274}; 3440};
3275 3441
3276static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, 3442static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
@@ -3282,6 +3448,10 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
3282 if (data != NULL) { 3448 if (data != NULL) {
3283 struct nfs_server *server = NFS_SERVER(dir); 3449 struct nfs_server *server = NFS_SERVER(dir);
3284 3450
3451 data->label = nfs4_label_alloc(server, GFP_KERNEL);
3452 if (IS_ERR(data->label))
3453 goto out_free;
3454
3285 data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE]; 3455 data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE];
3286 data->msg.rpc_argp = &data->arg; 3456 data->msg.rpc_argp = &data->arg;
3287 data->msg.rpc_resp = &data->res; 3457 data->msg.rpc_resp = &data->res;
@@ -3290,13 +3460,17 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
3290 data->arg.name = name; 3460 data->arg.name = name;
3291 data->arg.attrs = sattr; 3461 data->arg.attrs = sattr;
3292 data->arg.ftype = ftype; 3462 data->arg.ftype = ftype;
3293 data->arg.bitmask = server->attr_bitmask; 3463 data->arg.bitmask = nfs4_bitmask(server, data->label);
3294 data->res.server = server; 3464 data->res.server = server;
3295 data->res.fh = &data->fh; 3465 data->res.fh = &data->fh;
3296 data->res.fattr = &data->fattr; 3466 data->res.fattr = &data->fattr;
3467 data->res.label = data->label;
3297 nfs_fattr_init(data->res.fattr); 3468 nfs_fattr_init(data->res.fattr);
3298 } 3469 }
3299 return data; 3470 return data;
3471out_free:
3472 kfree(data);
3473 return NULL;
3300} 3474}
3301 3475
3302static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data) 3476static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data)
@@ -3305,18 +3479,20 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
3305 &data->arg.seq_args, &data->res.seq_res, 1); 3479 &data->arg.seq_args, &data->res.seq_res, 1);
3306 if (status == 0) { 3480 if (status == 0) {
3307 update_changeattr(dir, &data->res.dir_cinfo); 3481 update_changeattr(dir, &data->res.dir_cinfo);
3308 status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); 3482 status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, data->res.label);
3309 } 3483 }
3310 return status; 3484 return status;
3311} 3485}
3312 3486
3313static void nfs4_free_createdata(struct nfs4_createdata *data) 3487static void nfs4_free_createdata(struct nfs4_createdata *data)
3314{ 3488{
3489 nfs4_label_free(data->label);
3315 kfree(data); 3490 kfree(data);
3316} 3491}
3317 3492
3318static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, 3493static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
3319 struct page *page, unsigned int len, struct iattr *sattr) 3494 struct page *page, unsigned int len, struct iattr *sattr,
3495 struct nfs4_label *label)
3320{ 3496{
3321 struct nfs4_createdata *data; 3497 struct nfs4_createdata *data;
3322 int status = -ENAMETOOLONG; 3498 int status = -ENAMETOOLONG;
@@ -3332,6 +3508,7 @@ static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
3332 data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK]; 3508 data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK];
3333 data->arg.u.symlink.pages = &page; 3509 data->arg.u.symlink.pages = &page;
3334 data->arg.u.symlink.len = len; 3510 data->arg.u.symlink.len = len;
3511 data->arg.label = label;
3335 3512
3336 status = nfs4_do_create(dir, dentry, data); 3513 status = nfs4_do_create(dir, dentry, data);
3337 3514
@@ -3344,18 +3521,24 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
3344 struct page *page, unsigned int len, struct iattr *sattr) 3521 struct page *page, unsigned int len, struct iattr *sattr)
3345{ 3522{
3346 struct nfs4_exception exception = { }; 3523 struct nfs4_exception exception = { };
3524 struct nfs4_label l, *label = NULL;
3347 int err; 3525 int err;
3526
3527 label = nfs4_label_init_security(dir, dentry, sattr, &l);
3528
3348 do { 3529 do {
3349 err = nfs4_handle_exception(NFS_SERVER(dir), 3530 err = nfs4_handle_exception(NFS_SERVER(dir),
3350 _nfs4_proc_symlink(dir, dentry, page, 3531 _nfs4_proc_symlink(dir, dentry, page,
3351 len, sattr), 3532 len, sattr, label),
3352 &exception); 3533 &exception);
3353 } while (exception.retry); 3534 } while (exception.retry);
3535
3536 nfs4_label_release_security(label);
3354 return err; 3537 return err;
3355} 3538}
3356 3539
3357static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, 3540static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
3358 struct iattr *sattr) 3541 struct iattr *sattr, struct nfs4_label *label)
3359{ 3542{
3360 struct nfs4_createdata *data; 3543 struct nfs4_createdata *data;
3361 int status = -ENOMEM; 3544 int status = -ENOMEM;
@@ -3364,6 +3547,7 @@ static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
3364 if (data == NULL) 3547 if (data == NULL)
3365 goto out; 3548 goto out;
3366 3549
3550 data->arg.label = label;
3367 status = nfs4_do_create(dir, dentry, data); 3551 status = nfs4_do_create(dir, dentry, data);
3368 3552
3369 nfs4_free_createdata(data); 3553 nfs4_free_createdata(data);
@@ -3375,14 +3559,19 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
3375 struct iattr *sattr) 3559 struct iattr *sattr)
3376{ 3560{
3377 struct nfs4_exception exception = { }; 3561 struct nfs4_exception exception = { };
3562 struct nfs4_label l, *label = NULL;
3378 int err; 3563 int err;
3379 3564
3565 label = nfs4_label_init_security(dir, dentry, sattr, &l);
3566
3380 sattr->ia_mode &= ~current_umask(); 3567 sattr->ia_mode &= ~current_umask();
3381 do { 3568 do {
3382 err = nfs4_handle_exception(NFS_SERVER(dir), 3569 err = nfs4_handle_exception(NFS_SERVER(dir),
3383 _nfs4_proc_mkdir(dir, dentry, sattr), 3570 _nfs4_proc_mkdir(dir, dentry, sattr, label),
3384 &exception); 3571 &exception);
3385 } while (exception.retry); 3572 } while (exception.retry);
3573 nfs4_label_release_security(label);
3574
3386 return err; 3575 return err;
3387} 3576}
3388 3577
@@ -3440,7 +3629,7 @@ static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
3440} 3629}
3441 3630
3442static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, 3631static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
3443 struct iattr *sattr, dev_t rdev) 3632 struct iattr *sattr, struct nfs4_label *label, dev_t rdev)
3444{ 3633{
3445 struct nfs4_createdata *data; 3634 struct nfs4_createdata *data;
3446 int mode = sattr->ia_mode; 3635 int mode = sattr->ia_mode;
@@ -3465,7 +3654,8 @@ static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
3465 status = -EINVAL; 3654 status = -EINVAL;
3466 goto out_free; 3655 goto out_free;
3467 } 3656 }
3468 3657
3658 data->arg.label = label;
3469 status = nfs4_do_create(dir, dentry, data); 3659 status = nfs4_do_create(dir, dentry, data);
3470out_free: 3660out_free:
3471 nfs4_free_createdata(data); 3661 nfs4_free_createdata(data);
@@ -3477,14 +3667,20 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
3477 struct iattr *sattr, dev_t rdev) 3667 struct iattr *sattr, dev_t rdev)
3478{ 3668{
3479 struct nfs4_exception exception = { }; 3669 struct nfs4_exception exception = { };
3670 struct nfs4_label l, *label = NULL;
3480 int err; 3671 int err;
3481 3672
3673 label = nfs4_label_init_security(dir, dentry, sattr, &l);
3674
3482 sattr->ia_mode &= ~current_umask(); 3675 sattr->ia_mode &= ~current_umask();
3483 do { 3676 do {
3484 err = nfs4_handle_exception(NFS_SERVER(dir), 3677 err = nfs4_handle_exception(NFS_SERVER(dir),
3485 _nfs4_proc_mknod(dir, dentry, sattr, rdev), 3678 _nfs4_proc_mknod(dir, dentry, sattr, label, rdev),
3486 &exception); 3679 &exception);
3487 } while (exception.retry); 3680 } while (exception.retry);
3681
3682 nfs4_label_release_security(label);
3683
3488 return err; 3684 return err;
3489} 3685}
3490 3686
@@ -4211,6 +4407,155 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
4211 return err; 4407 return err;
4212} 4408}
4213 4409
4410#ifdef CONFIG_NFS_V4_SECURITY_LABEL
4411static int _nfs4_get_security_label(struct inode *inode, void *buf,
4412 size_t buflen)
4413{
4414 struct nfs_server *server = NFS_SERVER(inode);
4415 struct nfs_fattr fattr;
4416 struct nfs4_label label = {0, 0, buflen, buf};
4417
4418 u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL };
4419 struct nfs4_getattr_arg args = {
4420 .fh = NFS_FH(inode),
4421 .bitmask = bitmask,
4422 };
4423 struct nfs4_getattr_res res = {
4424 .fattr = &fattr,
4425 .label = &label,
4426 .server = server,
4427 };
4428 struct rpc_message msg = {
4429 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETATTR],
4430 .rpc_argp = &args,
4431 .rpc_resp = &res,
4432 };
4433 int ret;
4434
4435 nfs_fattr_init(&fattr);
4436
4437 ret = rpc_call_sync(server->client, &msg, 0);
4438 if (ret)
4439 return ret;
4440 if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL))
4441 return -ENOENT;
4442 if (buflen < label.len)
4443 return -ERANGE;
4444 return 0;
4445}
4446
4447static int nfs4_get_security_label(struct inode *inode, void *buf,
4448 size_t buflen)
4449{
4450 struct nfs4_exception exception = { };
4451 int err;
4452
4453 if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))
4454 return -EOPNOTSUPP;
4455
4456 do {
4457 err = nfs4_handle_exception(NFS_SERVER(inode),
4458 _nfs4_get_security_label(inode, buf, buflen),
4459 &exception);
4460 } while (exception.retry);
4461 return err;
4462}
4463
4464static int _nfs4_do_set_security_label(struct inode *inode,
4465 struct nfs4_label *ilabel,
4466 struct nfs_fattr *fattr,
4467 struct nfs4_label *olabel)
4468{
4469
4470 struct iattr sattr = {0};
4471 struct nfs_server *server = NFS_SERVER(inode);
4472 const u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL };
4473 struct nfs_setattrargs args = {
4474 .fh = NFS_FH(inode),
4475 .iap = &sattr,
4476 .server = server,
4477 .bitmask = bitmask,
4478 .label = ilabel,
4479 };
4480 struct nfs_setattrres res = {
4481 .fattr = fattr,
4482 .label = olabel,
4483 .server = server,
4484 };
4485 struct rpc_message msg = {
4486 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETATTR],
4487 .rpc_argp = &args,
4488 .rpc_resp = &res,
4489 };
4490 int status;
4491
4492 nfs4_stateid_copy(&args.stateid, &zero_stateid);
4493
4494 status = rpc_call_sync(server->client, &msg, 0);
4495 if (status)
4496 dprintk("%s failed: %d\n", __func__, status);
4497
4498 return status;
4499}
4500
4501static int nfs4_do_set_security_label(struct inode *inode,
4502 struct nfs4_label *ilabel,
4503 struct nfs_fattr *fattr,
4504 struct nfs4_label *olabel)
4505{
4506 struct nfs4_exception exception = { };
4507 int err;
4508
4509 do {
4510 err = nfs4_handle_exception(NFS_SERVER(inode),
4511 _nfs4_do_set_security_label(inode, ilabel,
4512 fattr, olabel),
4513 &exception);
4514 } while (exception.retry);
4515 return err;
4516}
4517
4518static int
4519nfs4_set_security_label(struct dentry *dentry, const void *buf, size_t buflen)
4520{
4521 struct nfs4_label ilabel, *olabel = NULL;
4522 struct nfs_fattr fattr;
4523 struct rpc_cred *cred;
4524 struct inode *inode = dentry->d_inode;
4525 int status;
4526
4527 if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))
4528 return -EOPNOTSUPP;
4529
4530 nfs_fattr_init(&fattr);
4531
4532 ilabel.pi = 0;
4533 ilabel.lfs = 0;
4534 ilabel.label = (char *)buf;
4535 ilabel.len = buflen;
4536
4537 cred = rpc_lookup_cred();
4538 if (IS_ERR(cred))
4539 return PTR_ERR(cred);
4540
4541 olabel = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
4542 if (IS_ERR(olabel)) {
4543 status = -PTR_ERR(olabel);
4544 goto out;
4545 }
4546
4547 status = nfs4_do_set_security_label(inode, &ilabel, &fattr, olabel);
4548 if (status == 0)
4549 nfs_setsecurity(inode, &fattr, olabel);
4550
4551 nfs4_label_free(olabel);
4552out:
4553 put_rpccred(cred);
4554 return status;
4555}
4556#endif /* CONFIG_NFS_V4_SECURITY_LABEL */
4557
4558
4214static int 4559static int
4215nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state) 4560nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state)
4216{ 4561{
@@ -5324,6 +5669,53 @@ static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list,
5324 return len; 5669 return len;
5325} 5670}
5326 5671
5672#ifdef CONFIG_NFS_V4_SECURITY_LABEL
5673static inline int nfs4_server_supports_labels(struct nfs_server *server)
5674{
5675 return server->caps & NFS_CAP_SECURITY_LABEL;
5676}
5677
5678static int nfs4_xattr_set_nfs4_label(struct dentry *dentry, const char *key,
5679 const void *buf, size_t buflen,
5680 int flags, int type)
5681{
5682 if (security_ismaclabel(key))
5683 return nfs4_set_security_label(dentry, buf, buflen);
5684
5685 return -EOPNOTSUPP;
5686}
5687
5688static int nfs4_xattr_get_nfs4_label(struct dentry *dentry, const char *key,
5689 void *buf, size_t buflen, int type)
5690{
5691 if (security_ismaclabel(key))
5692 return nfs4_get_security_label(dentry->d_inode, buf, buflen);
5693 return -EOPNOTSUPP;
5694}
5695
5696static size_t nfs4_xattr_list_nfs4_label(struct dentry *dentry, char *list,
5697 size_t list_len, const char *name,
5698 size_t name_len, int type)
5699{
5700 size_t len = 0;
5701
5702 if (nfs_server_capable(dentry->d_inode, NFS_CAP_SECURITY_LABEL)) {
5703 len = security_inode_listsecurity(dentry->d_inode, NULL, 0);
5704 if (list && len <= list_len)
5705 security_inode_listsecurity(dentry->d_inode, list, len);
5706 }
5707 return len;
5708}
5709
5710static const struct xattr_handler nfs4_xattr_nfs4_label_handler = {
5711 .prefix = XATTR_SECURITY_PREFIX,
5712 .list = nfs4_xattr_list_nfs4_label,
5713 .get = nfs4_xattr_get_nfs4_label,
5714 .set = nfs4_xattr_set_nfs4_label,
5715};
5716#endif
5717
5718
5327/* 5719/*
5328 * nfs_fhget will use either the mounted_on_fileid or the fileid 5720 * nfs_fhget will use either the mounted_on_fileid or the fileid
5329 */ 5721 */
@@ -5347,7 +5739,7 @@ static int _nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
5347 struct page *page) 5739 struct page *page)
5348{ 5740{
5349 struct nfs_server *server = NFS_SERVER(dir); 5741 struct nfs_server *server = NFS_SERVER(dir);
5350 u32 bitmask[2] = { 5742 u32 bitmask[3] = {
5351 [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, 5743 [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
5352 }; 5744 };
5353 struct nfs4_fs_locations_arg args = { 5745 struct nfs4_fs_locations_arg args = {
@@ -7052,11 +7444,33 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
7052}; 7444};
7053#endif 7445#endif
7054 7446
7447#if defined(CONFIG_NFS_V4_2)
7448static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
7449 .minor_version = 2,
7450 .init_caps = NFS_CAP_READDIRPLUS
7451 | NFS_CAP_ATOMIC_OPEN
7452 | NFS_CAP_CHANGE_ATTR
7453 | NFS_CAP_POSIX_LOCK
7454 | NFS_CAP_STATEID_NFSV41
7455 | NFS_CAP_ATOMIC_OPEN_V1,
7456 .call_sync = nfs4_call_sync_sequence,
7457 .match_stateid = nfs41_match_stateid,
7458 .find_root_sec = nfs41_find_root_sec,
7459 .free_lock_state = nfs41_free_lock_state,
7460 .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
7461 .nograce_recovery_ops = &nfs41_nograce_recovery_ops,
7462 .state_renewal_ops = &nfs41_state_renewal_ops,
7463};
7464#endif
7465
7055const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = { 7466const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
7056 [0] = &nfs_v4_0_minor_ops, 7467 [0] = &nfs_v4_0_minor_ops,
7057#if defined(CONFIG_NFS_V4_1) 7468#if defined(CONFIG_NFS_V4_1)
7058 [1] = &nfs_v4_1_minor_ops, 7469 [1] = &nfs_v4_1_minor_ops,
7059#endif 7470#endif
7471#if defined(CONFIG_NFS_V4_2)
7472 [2] = &nfs_v4_2_minor_ops,
7473#endif
7060}; 7474};
7061 7475
7062const struct inode_operations nfs4_dir_inode_operations = { 7476const struct inode_operations nfs4_dir_inode_operations = {
@@ -7156,6 +7570,9 @@ static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
7156 7570
7157const struct xattr_handler *nfs4_xattr_handlers[] = { 7571const struct xattr_handler *nfs4_xattr_handlers[] = {
7158 &nfs4_xattr_nfs4_acl_handler, 7572 &nfs4_xattr_nfs4_acl_handler,
7573#ifdef CONFIG_NFS_V4_SECURITY_LABEL
7574 &nfs4_xattr_nfs4_label_handler,
7575#endif
7159 NULL 7576 NULL
7160}; 7577};
7161 7578