Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

NFSD: Add POSIX draft ACL support to the NFSv4 SETATTR operation

The POSIX ACL extension to NFSv4 enables clients to set access
and default ACLs via FATTR4_POSIX_ACCESS_ACL and
FATTR4_POSIX_DEFAULT_ACL attributes. Integration of these
attributes into SETATTR processing requires wiring them through
the nfsd_attrs structure and ensuring proper cleanup on all
code paths.

This patch connects the na_pacl and na_dpacl fields in
nfsd_attrs to the decoded ACL pointers from the NFSv4 SETATTR
decoder. Ownership of these ACL references transfers to attrs
immediately after initialization, with the decoder's pointers
cleared to NULL. This transfer ensures nfsd_attrs_free()
releases the ACLs on normal completion, while new error paths
call posix_acl_release() directly when cleanup occurs before
nfsd_attrs_free() runs.

Early returns in the nfsd4_setattr() function gain conversions
to goto statements that branch to proper cleanup handlers.
Error paths before fh_want_write() branch to out_err for ACL
release only; paths after fh_want_write() use the existing out
label for full cleanup via nfsd_attrs_free().

The patch adds mutual exclusion between NFSv4 ACLs (sa_acl) and
POSIX ACLs. Setting both types simultaneously returns
nfserr_inval because these ACL models cannot coexist on the
same file object.

Signed-off-by: Rick Macklem <rmacklem@uoguelph.ca>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

authored by

Rick Macklem and committed by
Chuck Lever
318579c0 d2ca5060

+19 -5
+19 -5
fs/nfsd/nfs4proc.c
··· 1214 1214 struct nfsd_attrs attrs = { 1215 1215 .na_iattr = &setattr->sa_iattr, 1216 1216 .na_seclabel = &setattr->sa_label, 1217 + .na_pacl = setattr->sa_pacl, 1218 + .na_dpacl = setattr->sa_dpacl, 1217 1219 }; 1218 1220 bool save_no_wcc, deleg_attrs; 1219 1221 struct nfs4_stid *st = NULL; 1220 1222 struct inode *inode; 1221 1223 __be32 status = nfs_ok; 1222 1224 int err; 1225 + 1226 + /* Transfer ownership to attrs for cleanup via nfsd_attrs_free() */ 1227 + setattr->sa_pacl = NULL; 1228 + setattr->sa_dpacl = NULL; 1223 1229 1224 1230 deleg_attrs = setattr->sa_bmval[2] & (FATTR4_WORD2_TIME_DELEG_ACCESS | 1225 1231 FATTR4_WORD2_TIME_DELEG_MODIFY); ··· 1240 1234 &cstate->current_fh, &setattr->sa_stateid, 1241 1235 flags, NULL, &st); 1242 1236 if (status) 1243 - return status; 1237 + goto out_err; 1244 1238 } 1245 1239 1246 1240 if (deleg_attrs) { ··· 1258 1252 if (st) 1259 1253 nfs4_put_stid(st); 1260 1254 if (status) 1261 - return status; 1255 + goto out_err; 1262 1256 1263 1257 err = fh_want_write(&cstate->current_fh); 1264 - if (err) 1265 - return nfserrno(err); 1258 + if (err) { 1259 + status = nfserrno(err); 1260 + goto out_err; 1261 + } 1266 1262 status = nfs_ok; 1267 1263 1268 1264 status = check_attr_support(cstate, setattr->sa_bmval, nfsd_attrmask); 1269 1265 if (status) 1270 1266 goto out; 1267 + 1268 + if (setattr->sa_acl && (attrs.na_dpacl || attrs.na_pacl)) { 1269 + status = nfserr_inval; 1270 + goto out; 1271 + } 1271 1272 1272 1273 inode = cstate->current_fh.fh_dentry->d_inode; 1273 1274 status = nfsd4_acl_to_attr(S_ISDIR(inode->i_mode) ? NF4DIR : NF4REG, ··· 1293 1280 if (!status) 1294 1281 status = nfserrno(attrs.na_paclerr); 1295 1282 out: 1296 - nfsd_attrs_free(&attrs); 1297 1283 fh_drop_write(&cstate->current_fh); 1284 + out_err: 1285 + nfsd_attrs_free(&attrs); 1298 1286 return status; 1299 1287 } 1300 1288