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

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

+1123 -171
+14
fs/nfs/Kconfig
··· 104 104 105 105 If unsure, say N. 106 106 107 + config NFS_V4_2 108 + bool "NFS client support for NFSv4.2" 109 + depends on NFS_V4_1 110 + help 111 + This option enables support for minor version 2 of the NFSv4 protocol 112 + in the kernel's NFS client. 113 + 114 + If unsure, say N. 115 + 107 116 config PNFS_FILE_LAYOUT 108 117 tristate 109 118 depends on NFS_V4_1 ··· 139 130 name of the distribution. 140 131 If the NFS client is unchanged from the upstream kernel, this 141 132 option should be set to the default "kernel.org". 133 + 134 + config NFS_V4_SECURITY_LABEL 135 + bool 136 + depends on NFS_V4_2 && SECURITY 137 + default y 142 138 143 139 config ROOT_NFS 144 140 bool "Root file system on NFS"
+1
fs/nfs/callback.c
··· 282 282 ret = nfs4_callback_up_net(serv, net); 283 283 break; 284 284 case 1: 285 + case 2: 285 286 ret = nfs41_callback_up_net(serv, net); 286 287 break; 287 288 default:
+3
fs/nfs/callback.h
··· 32 32 OP_CB_WANTS_CANCELLED = 12, 33 33 OP_CB_NOTIFY_LOCK = 13, 34 34 OP_CB_NOTIFY_DEVICEID = 14, 35 + /* Callback operations new to NFSv4.2 */ 36 + OP_CB_OFFLOAD = 15, 35 37 OP_CB_ILLEGAL = 10044, 36 38 }; 37 39 ··· 41 39 __be32 drc_status; 42 40 struct nfs_client *clp; 43 41 u32 slotid; 42 + u32 minorversion; 44 43 struct net *net; 45 44 }; 46 45
+2 -1
fs/nfs/callback_proc.c
··· 406 406 int i; 407 407 __be32 status = htonl(NFS4ERR_BADSESSION); 408 408 409 - clp = nfs4_find_client_sessionid(cps->net, args->csa_addr, &args->csa_sessionid); 409 + clp = nfs4_find_client_sessionid(cps->net, args->csa_addr, 410 + &args->csa_sessionid, cps->minorversion); 410 411 if (clp == NULL) 411 412 goto out; 412 413
+42 -10
fs/nfs/callback_xdr.c
··· 166 166 if (unlikely(p == NULL)) 167 167 return htonl(NFS4ERR_RESOURCE); 168 168 hdr->minorversion = ntohl(*p++); 169 - /* Check minor version is zero or one. */ 170 - if (hdr->minorversion <= 1) { 171 - hdr->cb_ident = ntohl(*p++); /* ignored by v4.1 */ 169 + /* Check for minor version support */ 170 + if (hdr->minorversion <= NFS4_MAX_MINOR_VERSION) { 171 + hdr->cb_ident = ntohl(*p++); /* ignored by v4.1 and v4.2 */ 172 172 } else { 173 173 pr_warn_ratelimited("NFS: %s: NFSv4 server callback with " 174 174 "illegal minor version %u!\n", ··· 786 786 } 787 787 #endif /* CONFIG_NFS_V4_1 */ 788 788 789 + #ifdef CONFIG_NFS_V4_2 790 + static __be32 791 + preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op) 792 + { 793 + __be32 status = preprocess_nfs41_op(nop, op_nr, op); 794 + if (status != htonl(NFS4ERR_OP_ILLEGAL)) 795 + return status; 796 + 797 + if (op_nr == OP_CB_OFFLOAD) 798 + return htonl(NFS4ERR_NOTSUPP); 799 + return htonl(NFS4ERR_OP_ILLEGAL); 800 + } 801 + #else /* CONFIG_NFS_V4_2 */ 802 + static __be32 803 + preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op) 804 + { 805 + return htonl(NFS4ERR_MINOR_VERS_MISMATCH); 806 + } 807 + #endif /* CONFIG_NFS_V4_2 */ 808 + 789 809 static __be32 790 810 preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op) 791 811 { ··· 821 801 return htonl(NFS_OK); 822 802 } 823 803 824 - static __be32 process_op(uint32_t minorversion, int nop, 825 - struct svc_rqst *rqstp, 804 + static __be32 process_op(int nop, struct svc_rqst *rqstp, 826 805 struct xdr_stream *xdr_in, void *argp, 827 806 struct xdr_stream *xdr_out, void *resp, 828 807 struct cb_process_state *cps) ··· 838 819 return status; 839 820 840 821 dprintk("%s: minorversion=%d nop=%d op_nr=%u\n", 841 - __func__, minorversion, nop, op_nr); 822 + __func__, cps->minorversion, nop, op_nr); 842 823 843 - status = minorversion ? preprocess_nfs41_op(nop, op_nr, &op) : 844 - preprocess_nfs4_op(op_nr, &op); 824 + switch (cps->minorversion) { 825 + case 0: 826 + status = preprocess_nfs4_op(op_nr, &op); 827 + break; 828 + case 1: 829 + status = preprocess_nfs41_op(nop, op_nr, &op); 830 + break; 831 + case 2: 832 + status = preprocess_nfs42_op(nop, op_nr, &op); 833 + break; 834 + default: 835 + status = htonl(NFS4ERR_MINOR_VERS_MISMATCH); 836 + } 837 + 845 838 if (status == htonl(NFS4ERR_OP_ILLEGAL)) 846 839 op_nr = OP_CB_ILLEGAL; 847 840 if (status) ··· 916 885 return rpc_drop_reply; 917 886 } 918 887 888 + cps.minorversion = hdr_arg.minorversion; 919 889 hdr_res.taglen = hdr_arg.taglen; 920 890 hdr_res.tag = hdr_arg.tag; 921 891 if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0) 922 892 return rpc_system_err; 923 893 924 894 while (status == 0 && nops != hdr_arg.nops) { 925 - status = process_op(hdr_arg.minorversion, nops, rqstp, 926 - &xdr_in, argp, &xdr_out, resp, &cps); 895 + status = process_op(nops, rqstp, &xdr_in, 896 + argp, &xdr_out, resp, &cps); 927 897 nops++; 928 898 } 929 899
+1 -1
fs/nfs/client.c
··· 1074 1074 } 1075 1075 1076 1076 if (!(fattr->valid & NFS_ATTR_FATTR)) { 1077 - error = nfs_mod->rpc_ops->getattr(server, mount_info->mntfh, fattr); 1077 + error = nfs_mod->rpc_ops->getattr(server, mount_info->mntfh, fattr, NULL); 1078 1078 if (error < 0) { 1079 1079 dprintk("nfs_create_server: getattr error = %d\n", -error); 1080 1080 goto error;
+39 -10
fs/nfs/dir.c
··· 435 435 struct dentry *alias; 436 436 struct inode *dir = parent->d_inode; 437 437 struct inode *inode; 438 + int status; 438 439 439 440 if (filename.name[0] == '.') { 440 441 if (filename.len == 1) ··· 448 447 dentry = d_lookup(parent, &filename); 449 448 if (dentry != NULL) { 450 449 if (nfs_same_file(dentry, entry)) { 451 - nfs_refresh_inode(dentry->d_inode, entry->fattr); 450 + status = nfs_refresh_inode(dentry->d_inode, entry->fattr); 451 + if (!status) 452 + nfs_setsecurity(dentry->d_inode, entry->fattr, entry->label); 452 453 goto out; 453 454 } else { 454 455 if (d_invalidate(dentry) != 0) ··· 463 460 if (dentry == NULL) 464 461 return; 465 462 466 - inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); 463 + inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr, entry->label); 467 464 if (IS_ERR(inode)) 468 465 goto out; 469 466 ··· 588 585 if (entry.fh == NULL || entry.fattr == NULL) 589 586 goto out; 590 587 588 + entry.label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT); 589 + if (IS_ERR(entry.label)) { 590 + status = PTR_ERR(entry.label); 591 + goto out; 592 + } 593 + 591 594 array = nfs_readdir_get_array(page); 592 595 if (IS_ERR(array)) { 593 596 status = PTR_ERR(array); 594 - goto out; 597 + goto out_label_free; 595 598 } 596 599 memset(array, 0, sizeof(struct nfs_cache_array)); 597 600 array->eof_index = -1; ··· 623 614 nfs_readdir_free_large_page(pages_ptr, pages, array_size); 624 615 out_release_array: 625 616 nfs_readdir_release_array(page); 617 + out_label_free: 618 + nfs4_label_free(entry.label); 626 619 out: 627 620 nfs_free_fattr(entry.fattr); 628 621 nfs_free_fhandle(entry.fh); ··· 1051 1040 struct dentry *parent; 1052 1041 struct nfs_fh *fhandle = NULL; 1053 1042 struct nfs_fattr *fattr = NULL; 1043 + struct nfs4_label *label = NULL; 1054 1044 int error; 1055 1045 1056 1046 if (flags & LOOKUP_RCU) ··· 1094 1082 if (fhandle == NULL || fattr == NULL) 1095 1083 goto out_error; 1096 1084 1097 - error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); 1085 + label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT); 1086 + if (IS_ERR(label)) 1087 + goto out_error; 1088 + 1089 + error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label); 1098 1090 if (error) 1099 1091 goto out_bad; 1100 1092 if (nfs_compare_fh(NFS_FH(inode), fhandle)) ··· 1106 1090 if ((error = nfs_refresh_inode(inode, fattr)) != 0) 1107 1091 goto out_bad; 1108 1092 1093 + nfs_setsecurity(inode, fattr, label); 1094 + 1109 1095 nfs_free_fattr(fattr); 1110 1096 nfs_free_fhandle(fhandle); 1097 + nfs4_label_free(label); 1098 + 1111 1099 out_set_verifier: 1112 1100 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1113 1101 out_valid: ··· 1128 1108 out_bad: 1129 1109 nfs_free_fattr(fattr); 1130 1110 nfs_free_fhandle(fhandle); 1111 + nfs4_label_free(label); 1131 1112 nfs_mark_for_revalidate(dir); 1132 1113 if (inode && S_ISDIR(inode->i_mode)) { 1133 1114 /* Purge readdir caches. */ ··· 1149 1128 out_error: 1150 1129 nfs_free_fattr(fattr); 1151 1130 nfs_free_fhandle(fhandle); 1131 + nfs4_label_free(label); 1152 1132 dput(parent); 1153 1133 dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) lookup returned error %d\n", 1154 1134 __func__, dentry->d_parent->d_name.name, ··· 1278 1256 struct inode *inode = NULL; 1279 1257 struct nfs_fh *fhandle = NULL; 1280 1258 struct nfs_fattr *fattr = NULL; 1259 + struct nfs4_label *label = NULL; 1281 1260 int error; 1282 1261 1283 1262 dfprintk(VFS, "NFS: lookup(%s/%s)\n", ··· 1305 1282 if (fhandle == NULL || fattr == NULL) 1306 1283 goto out; 1307 1284 1285 + label = nfs4_label_alloc(NFS_SERVER(dir), GFP_NOWAIT); 1286 + if (IS_ERR(label)) 1287 + goto out; 1288 + 1308 1289 parent = dentry->d_parent; 1309 1290 /* Protect against concurrent sillydeletes */ 1310 1291 nfs_block_sillyrename(parent); 1311 - error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); 1292 + error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label); 1312 1293 if (error == -ENOENT) 1313 1294 goto no_entry; 1314 1295 if (error < 0) { 1315 1296 res = ERR_PTR(error); 1316 1297 goto out_unblock_sillyrename; 1317 1298 } 1318 - inode = nfs_fhget(dentry->d_sb, fhandle, fattr); 1299 + inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label); 1319 1300 res = ERR_CAST(inode); 1320 1301 if (IS_ERR(res)) 1321 1302 goto out_unblock_sillyrename; ··· 1337 1310 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1338 1311 out_unblock_sillyrename: 1339 1312 nfs_unblock_sillyrename(parent); 1313 + nfs4_label_free(label); 1340 1314 out: 1341 1315 nfs_free_fattr(fattr); 1342 1316 nfs_free_fhandle(fhandle); ··· 1536 1508 * Code common to create, mkdir, and mknod. 1537 1509 */ 1538 1510 int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, 1539 - struct nfs_fattr *fattr) 1511 + struct nfs_fattr *fattr, 1512 + struct nfs4_label *label) 1540 1513 { 1541 1514 struct dentry *parent = dget_parent(dentry); 1542 1515 struct inode *dir = parent->d_inode; ··· 1550 1521 if (dentry->d_inode) 1551 1522 goto out; 1552 1523 if (fhandle->size == 0) { 1553 - error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); 1524 + error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, NULL); 1554 1525 if (error) 1555 1526 goto out_error; 1556 1527 } 1557 1528 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1558 1529 if (!(fattr->valid & NFS_ATTR_FATTR)) { 1559 1530 struct nfs_server *server = NFS_SB(dentry->d_sb); 1560 - error = server->nfs_client->rpc_ops->getattr(server, fhandle, fattr); 1531 + error = server->nfs_client->rpc_ops->getattr(server, fhandle, fattr, NULL); 1561 1532 if (error < 0) 1562 1533 goto out_error; 1563 1534 } 1564 - inode = nfs_fhget(dentry->d_sb, fhandle, fattr); 1535 + inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label); 1565 1536 error = PTR_ERR(inode); 1566 1537 if (IS_ERR(inode)) 1567 1538 goto out_error;
+1 -1
fs/nfs/getroot.c
··· 95 95 goto out; 96 96 } 97 97 98 - inode = nfs_fhget(sb, mntfh, fsinfo.fattr); 98 + inode = nfs_fhget(sb, mntfh, fsinfo.fattr, NULL); 99 99 if (IS_ERR(inode)) { 100 100 dprintk("nfs_get_root: get root inode failed\n"); 101 101 ret = ERR_CAST(inode);
+97 -12
fs/nfs/inode.c
··· 161 161 162 162 memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); 163 163 if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { 164 - nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; 165 164 nfs_fscache_invalidate(inode); 166 - } else { 167 - nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; 168 - } 165 + nfsi->cache_validity |= NFS_INO_INVALID_ATTR 166 + | NFS_INO_INVALID_LABEL 167 + | NFS_INO_INVALID_DATA 168 + | NFS_INO_INVALID_ACCESS 169 + | NFS_INO_INVALID_ACL 170 + | NFS_INO_REVAL_PAGECACHE; 171 + } else 172 + nfsi->cache_validity |= NFS_INO_INVALID_ATTR 173 + | NFS_INO_INVALID_LABEL 174 + | NFS_INO_INVALID_ACCESS 175 + | NFS_INO_INVALID_ACL 176 + | NFS_INO_REVAL_PAGECACHE; 169 177 } 170 178 171 179 void nfs_zap_caches(struct inode *inode) ··· 264 256 return 0; 265 257 } 266 258 259 + #ifdef CONFIG_NFS_V4_SECURITY_LABEL 260 + void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, 261 + struct nfs4_label *label) 262 + { 263 + int error; 264 + 265 + if (label == NULL) 266 + return; 267 + 268 + if (nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL) == 0) 269 + return; 270 + 271 + if (NFS_SERVER(inode)->nfs_client->cl_minorversion < 2) 272 + return; 273 + 274 + if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) { 275 + error = security_inode_notifysecctx(inode, label->label, 276 + label->len); 277 + if (error) 278 + printk(KERN_ERR "%s() %s %d " 279 + "security_inode_notifysecctx() %d\n", 280 + __func__, 281 + (char *)label->label, 282 + label->len, error); 283 + } 284 + } 285 + 286 + struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) 287 + { 288 + struct nfs4_label *label = NULL; 289 + int minor_version = server->nfs_client->cl_minorversion; 290 + 291 + if (minor_version < 2) 292 + return label; 293 + 294 + if (!(server->caps & NFS_CAP_SECURITY_LABEL)) 295 + return label; 296 + 297 + label = kzalloc(sizeof(struct nfs4_label), flags); 298 + if (label == NULL) 299 + return ERR_PTR(-ENOMEM); 300 + 301 + label->label = kzalloc(NFS4_MAXLABELLEN, flags); 302 + if (label->label == NULL) { 303 + kfree(label); 304 + return ERR_PTR(-ENOMEM); 305 + } 306 + label->len = NFS4_MAXLABELLEN; 307 + 308 + return label; 309 + } 310 + EXPORT_SYMBOL_GPL(nfs4_label_alloc); 311 + #else 312 + void inline nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, 313 + struct nfs4_label *label) 314 + { 315 + } 316 + #endif 317 + EXPORT_SYMBOL_GPL(nfs_setsecurity); 318 + 267 319 /* 268 320 * This is our front-end to iget that looks up inodes by file handle 269 321 * instead of inode number. 270 322 */ 271 323 struct inode * 272 - nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) 324 + nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, struct nfs4_label *label) 273 325 { 274 326 struct nfs_find_desc desc = { 275 327 .fh = fh, ··· 451 383 */ 452 384 inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used); 453 385 } 386 + 387 + nfs_setsecurity(inode, fattr, label); 388 + 454 389 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); 455 390 nfsi->attrtimeo_timestamp = now; 456 391 nfsi->access_cache = RB_ROOT; ··· 463 392 unlock_new_inode(inode); 464 393 } else 465 394 nfs_refresh_inode(inode, fattr); 395 + nfs_setsecurity(inode, fattr, label); 466 396 dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", 467 397 inode->i_sb->s_id, 468 398 (long long)NFS_FILEID(inode), ··· 520 448 NFS_PROTO(inode)->return_delegation(inode); 521 449 error = NFS_PROTO(inode)->setattr(dentry, fattr, attr); 522 450 if (error == 0) 523 - nfs_refresh_inode(inode, fattr); 451 + error = nfs_refresh_inode(inode, fattr); 524 452 nfs_free_fattr(fattr); 525 453 out: 526 454 return error; ··· 869 797 __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) 870 798 { 871 799 int status = -ESTALE; 800 + struct nfs4_label *label = NULL; 872 801 struct nfs_fattr *fattr = NULL; 873 802 struct nfs_inode *nfsi = NFS_I(inode); 874 803 ··· 887 814 goto out; 888 815 889 816 nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); 890 - status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr); 817 + 818 + label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL); 819 + if (IS_ERR(label)) { 820 + status = PTR_ERR(label); 821 + goto out; 822 + } 823 + 824 + status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr, label); 891 825 if (status != 0) { 892 826 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", 893 827 inode->i_sb->s_id, ··· 904 824 if (!S_ISDIR(inode->i_mode)) 905 825 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); 906 826 } 907 - goto out; 827 + goto err_out; 908 828 } 909 829 910 830 status = nfs_refresh_inode(inode, fattr); ··· 912 832 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", 913 833 inode->i_sb->s_id, 914 834 (long long)NFS_FILEID(inode), status); 915 - goto out; 835 + goto err_out; 916 836 } 917 837 918 838 if (nfsi->cache_validity & NFS_INO_INVALID_ACL) ··· 922 842 inode->i_sb->s_id, 923 843 (long long)NFS_FILEID(inode)); 924 844 925 - out: 845 + err_out: 846 + nfs4_label_free(label); 847 + out: 926 848 nfs_free_fattr(fattr); 927 849 return status; 928 850 } ··· 952 870 */ 953 871 int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) 954 872 { 955 - if (!(NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATTR) 873 + if (!(NFS_I(inode)->cache_validity & 874 + (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) 956 875 && !nfs_attribute_cache_expired(inode)) 957 876 return NFS_STALE(inode) ? -ESTALE : 0; 958 877 return __nfs_revalidate_inode(server, inode); ··· 1333 1250 spin_lock(&inode->i_lock); 1334 1251 status = nfs_post_op_update_inode_locked(inode, fattr); 1335 1252 spin_unlock(&inode->i_lock); 1253 + 1336 1254 return status; 1337 1255 } 1338 1256 EXPORT_SYMBOL_GPL(nfs_post_op_update_inode); ··· 1574 1490 inode->i_blocks = fattr->du.nfs2.blocks; 1575 1491 1576 1492 /* Update attrtimeo value if we're out of the unstable period */ 1577 - if (invalid & NFS_INO_INVALID_ATTR) { 1493 + if (invalid & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) { 1578 1494 nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE); 1579 1495 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); 1580 1496 nfsi->attrtimeo_timestamp = now; ··· 1587 1503 } 1588 1504 } 1589 1505 invalid &= ~NFS_INO_INVALID_ATTR; 1506 + invalid &= ~NFS_INO_INVALID_LABEL; 1590 1507 /* Don't invalidate the data if we were to blame */ 1591 1508 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) 1592 1509 || S_ISLNK(inode->i_mode)))
+1 -1
fs/nfs/internal.h
··· 165 165 extern struct nfs_client *nfs4_find_client_ident(struct net *, int); 166 166 extern struct nfs_client * 167 167 nfs4_find_client_sessionid(struct net *, const struct sockaddr *, 168 - struct nfs4_sessionid *); 168 + struct nfs4_sessionid *, u32); 169 169 extern struct nfs_server *nfs_create_server(struct nfs_mount_info *, 170 170 struct nfs_subversion *); 171 171 extern struct nfs_server *nfs4_create_server(
+1 -1
fs/nfs/namespace.c
··· 280 280 struct dentry *parent = dget_parent(dentry); 281 281 282 282 /* Look it up again to get its attributes */ 283 - err = server->nfs_client->rpc_ops->lookup(parent->d_inode, &dentry->d_name, fh, fattr); 283 + err = server->nfs_client->rpc_ops->lookup(parent->d_inode, &dentry->d_name, fh, fattr, NULL); 284 284 dput(parent); 285 285 if (err != 0) 286 286 return ERR_PTR(err);
+4 -3
fs/nfs/nfs3proc.c
··· 98 98 */ 99 99 static int 100 100 nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, 101 - struct nfs_fattr *fattr) 101 + struct nfs_fattr *fattr, struct nfs4_label *label) 102 102 { 103 103 struct rpc_message msg = { 104 104 .rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR], ··· 143 143 144 144 static int 145 145 nfs3_proc_lookup(struct inode *dir, struct qstr *name, 146 - struct nfs_fh *fhandle, struct nfs_fattr *fattr) 146 + struct nfs_fh *fhandle, struct nfs_fattr *fattr, 147 + struct nfs4_label *label) 147 148 { 148 149 struct nfs3_diropargs arg = { 149 150 .fh = NFS_FH(dir), ··· 301 300 status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0); 302 301 nfs_post_op_update_inode(dir, data->res.dir_attr); 303 302 if (status == 0) 304 - status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); 303 + status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL); 305 304 return status; 306 305 } 307 306
+3 -3
fs/nfs/nfs4_fs.h
··· 303 303 extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[]; 304 304 305 305 extern const u32 nfs4_fattr_bitmap[3]; 306 - extern const u32 nfs4_statfs_bitmap[2]; 307 - extern const u32 nfs4_pathconf_bitmap[2]; 306 + extern const u32 nfs4_statfs_bitmap[3]; 307 + extern const u32 nfs4_pathconf_bitmap[3]; 308 308 extern const u32 nfs4_fsinfo_bitmap[3]; 309 - extern const u32 nfs4_fs_locations_bitmap[2]; 309 + extern const u32 nfs4_fs_locations_bitmap[3]; 310 310 311 311 void nfs4_free_client(struct nfs_client *); 312 312
+8 -3
fs/nfs/nfs4client.c
··· 66 66 if (err) 67 67 goto error; 68 68 69 + if (cl_init->minorversion > NFS4_MAX_MINOR_VERSION) { 70 + err = -EINVAL; 71 + goto error; 72 + } 73 + 69 74 spin_lock_init(&clp->cl_lock); 70 75 INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); 71 76 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); ··· 567 562 */ 568 563 struct nfs_client * 569 564 nfs4_find_client_sessionid(struct net *net, const struct sockaddr *addr, 570 - struct nfs4_sessionid *sid) 565 + struct nfs4_sessionid *sid, u32 minorversion) 571 566 { 572 567 struct nfs_client *clp; 573 568 struct nfs_net *nn = net_generic(net, nfs_net_id); 574 569 575 570 spin_lock(&nn->nfs_client_lock); 576 571 list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) { 577 - if (nfs4_cb_match_client(addr, clp, 1) == false) 572 + if (nfs4_cb_match_client(addr, clp, minorversion) == false) 578 573 continue; 579 574 580 575 if (!nfs4_has_session(clp)) ··· 597 592 598 593 struct nfs_client * 599 594 nfs4_find_client_sessionid(struct net *net, const struct sockaddr *addr, 600 - struct nfs4_sessionid *sid) 595 + struct nfs4_sessionid *sid, u32 minorversion) 601 596 { 602 597 return NULL; 603 598 }
+473 -56
fs/nfs/nfs4proc.c
··· 77 77 static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 78 78 static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); 79 79 static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); 80 - static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *); 81 - static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 80 + static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label); 81 + static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label); 82 82 static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, 83 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 86 #ifdef CONFIG_NFS_V4_1 86 87 static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *, 87 88 struct rpc_cred *); 88 89 static int nfs41_free_stateid(struct nfs_server *, nfs4_stateid *, 89 90 struct rpc_cred *); 90 91 #endif 92 + 93 + #ifdef CONFIG_NFS_V4_SECURITY_LABEL 94 + static inline struct nfs4_label * 95 + nfs4_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 + } 116 + static inline void 117 + nfs4_label_release_security(struct nfs4_label *label) 118 + { 119 + if (label) 120 + security_release_secctx(label->label, label->len); 121 + } 122 + static 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 130 + static inline struct nfs4_label * 131 + nfs4_label_init_security(struct inode *dir, struct dentry *dentry, 132 + struct iattr *sattr, struct nfs4_label *l) 133 + { return NULL; } 134 + static inline void 135 + nfs4_label_release_security(struct nfs4_label *label) 136 + { return; } 137 + static inline u32 * 138 + nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label) 139 + { return server->attr_bitmask; } 140 + #endif 141 + 91 142 /* Prevent leaks of NFSv4 errors into userland */ 92 143 static int nfs4_map_errors(int err) 93 144 { ··· 187 136 | FATTR4_WORD1_SPACE_USED 188 137 | FATTR4_WORD1_TIME_ACCESS 189 138 | FATTR4_WORD1_TIME_METADATA 190 - | FATTR4_WORD1_TIME_MODIFY 139 + | FATTR4_WORD1_TIME_MODIFY, 140 + #ifdef CONFIG_NFS_V4_SECURITY_LABEL 141 + FATTR4_WORD2_SECURITY_LABEL 142 + #endif 191 143 }; 192 144 193 145 static const u32 nfs4_pnfs_open_bitmap[3] = { ··· 217 163 | FATTR4_WORD0_FILEID, 218 164 }; 219 165 220 - const u32 nfs4_statfs_bitmap[2] = { 166 + const u32 nfs4_statfs_bitmap[3] = { 221 167 FATTR4_WORD0_FILES_AVAIL 222 168 | FATTR4_WORD0_FILES_FREE 223 169 | FATTR4_WORD0_FILES_TOTAL, ··· 226 172 | FATTR4_WORD1_SPACE_TOTAL 227 173 }; 228 174 229 - const u32 nfs4_pathconf_bitmap[2] = { 175 + const u32 nfs4_pathconf_bitmap[3] = { 230 176 FATTR4_WORD0_MAXLINK 231 177 | FATTR4_WORD0_MAXNAME, 232 178 0 ··· 241 187 FATTR4_WORD2_LAYOUT_BLKSIZE 242 188 }; 243 189 244 - const u32 nfs4_fs_locations_bitmap[2] = { 190 + const u32 nfs4_fs_locations_bitmap[3] = { 245 191 FATTR4_WORD0_TYPE 246 192 | FATTR4_WORD0_CHANGE 247 193 | FATTR4_WORD0_SIZE ··· 257 203 | FATTR4_WORD1_TIME_ACCESS 258 204 | FATTR4_WORD1_TIME_METADATA 259 205 | FATTR4_WORD1_TIME_MODIFY 260 - | FATTR4_WORD1_MOUNTED_ON_FILEID 206 + | FATTR4_WORD1_MOUNTED_ON_FILEID, 261 207 }; 262 208 263 209 static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry, ··· 818 764 struct nfs4_string owner_name; 819 765 struct nfs4_string group_name; 820 766 struct nfs_fattr f_attr; 767 + struct nfs4_label *f_label; 821 768 struct dentry *dir; 822 769 struct dentry *dentry; 823 770 struct nfs4_state_owner *owner; ··· 864 809 static void nfs4_init_opendata_res(struct nfs4_opendata *p) 865 810 { 866 811 p->o_res.f_attr = &p->f_attr; 812 + p->o_res.f_label = p->f_label; 867 813 p->o_res.seqid = p->o_arg.seqid; 868 814 p->c_res.seqid = p->c_arg.seqid; 869 815 p->o_res.server = p->o_arg.server; ··· 876 820 static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, 877 821 struct nfs4_state_owner *sp, fmode_t fmode, int flags, 878 822 const struct iattr *attrs, 823 + struct nfs4_label *label, 879 824 enum open_claim_type4 claim, 880 825 gfp_t gfp_mask) 881 826 { ··· 888 831 p = kzalloc(sizeof(*p), gfp_mask); 889 832 if (p == NULL) 890 833 goto err; 834 + 835 + p->f_label = nfs4_label_alloc(server, gfp_mask); 836 + if (IS_ERR(p->f_label)) 837 + goto err_free_p; 838 + 891 839 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask); 892 840 if (p->o_arg.seqid == NULL) 893 - goto err_free; 841 + goto err_free_label; 894 842 nfs_sb_active(dentry->d_sb); 895 843 p->dentry = dget(dentry); 896 844 p->dir = parent; ··· 916 854 p->o_arg.id.uniquifier = sp->so_seqid.owner_id; 917 855 p->o_arg.name = &dentry->d_name; 918 856 p->o_arg.server = server; 919 - p->o_arg.bitmask = server->attr_bitmask; 857 + p->o_arg.bitmask = nfs4_bitmask(server, label); 920 858 p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; 859 + p->o_arg.label = label; 921 860 p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim); 922 861 switch (p->o_arg.claim) { 923 862 case NFS4_OPEN_CLAIM_NULL: ··· 949 886 nfs4_init_opendata_res(p); 950 887 kref_init(&p->kref); 951 888 return p; 952 - err_free: 889 + 890 + err_free_label: 891 + nfs4_label_free(p->f_label); 892 + err_free_p: 953 893 kfree(p); 954 894 err: 955 895 dput(parent); ··· 969 903 if (p->state != NULL) 970 904 nfs4_put_open_state(p->state); 971 905 nfs4_put_state_owner(p->owner); 906 + 907 + nfs4_label_free(p->f_label); 908 + 972 909 dput(p->dir); 973 910 dput(p->dentry); 974 911 nfs_sb_deactive(sb); ··· 1250 1181 if (ret) 1251 1182 goto err; 1252 1183 1184 + nfs_setsecurity(inode, &data->f_attr, data->f_label); 1185 + 1253 1186 if (data->o_res.delegation_type != 0) 1254 1187 nfs4_opendata_check_deleg(data, state); 1255 1188 update_open_stateid(state, &data->o_res.stateid, NULL, ··· 1278 1207 ret = -EAGAIN; 1279 1208 if (!(data->f_attr.valid & NFS_ATTR_FATTR)) 1280 1209 goto err; 1281 - inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr); 1210 + inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr, data->f_label); 1282 1211 ret = PTR_ERR(inode); 1283 1212 if (IS_ERR(inode)) 1284 1213 goto err; ··· 1331 1260 struct nfs4_opendata *opendata; 1332 1261 1333 1262 opendata = nfs4_opendata_alloc(ctx->dentry, state->owner, 0, 0, 1334 - NULL, claim, GFP_NOFS); 1263 + NULL, NULL, claim, GFP_NOFS); 1335 1264 if (opendata == NULL) 1336 1265 return ERR_PTR(-ENOMEM); 1337 1266 opendata->state = state; ··· 1857 1786 return status; 1858 1787 } 1859 1788 if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) 1860 - _nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr); 1789 + _nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr, o_res->f_label); 1861 1790 return 0; 1862 1791 } 1863 1792 ··· 2088 2017 static int _nfs4_do_open(struct inode *dir, 2089 2018 struct nfs_open_context *ctx, 2090 2019 int flags, 2091 - struct iattr *sattr) 2020 + struct iattr *sattr, 2021 + struct nfs4_label *label) 2092 2022 { 2093 2023 struct nfs4_state_owner *sp; 2094 2024 struct nfs4_state *state = NULL; ··· 2100 2028 struct nfs4_threshold **ctx_th = &ctx->mdsthreshold; 2101 2029 fmode_t fmode = ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC); 2102 2030 enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL; 2031 + struct nfs4_label *olabel = NULL; 2103 2032 int status; 2104 2033 2105 2034 /* Protect against reboot recovery conflicts */ ··· 2119 2046 if (dentry->d_inode) 2120 2047 claim = NFS4_OPEN_CLAIM_FH; 2121 2048 opendata = nfs4_opendata_alloc(dentry, sp, fmode, flags, sattr, 2122 - claim, GFP_KERNEL); 2049 + label, claim, GFP_KERNEL); 2123 2050 if (opendata == NULL) 2124 2051 goto err_put_state_owner; 2052 + 2053 + if (label) { 2054 + olabel = nfs4_label_alloc(server, GFP_KERNEL); 2055 + if (IS_ERR(olabel)) { 2056 + status = PTR_ERR(olabel); 2057 + goto err_opendata_put; 2058 + } 2059 + } 2125 2060 2126 2061 if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) { 2127 2062 opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc(); 2128 2063 if (!opendata->f_attr.mdsthreshold) 2129 - goto err_opendata_put; 2064 + goto err_free_label; 2130 2065 opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0]; 2131 2066 } 2132 2067 if (dentry->d_inode != NULL) ··· 2142 2061 2143 2062 status = _nfs4_open_and_get_state(opendata, fmode, flags, ctx); 2144 2063 if (status != 0) 2145 - goto err_opendata_put; 2064 + goto err_free_label; 2146 2065 state = ctx->state; 2147 2066 2148 2067 if ((opendata->o_arg.open_flags & O_EXCL) && ··· 2152 2071 nfs_fattr_init(opendata->o_res.f_attr); 2153 2072 status = nfs4_do_setattr(state->inode, cred, 2154 2073 opendata->o_res.f_attr, sattr, 2155 - state); 2156 - if (status == 0) 2074 + state, label, olabel); 2075 + if (status == 0) { 2157 2076 nfs_setattr_update_inode(state->inode, sattr); 2158 - nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); 2077 + nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); 2078 + nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel); 2079 + } 2159 2080 } 2160 2081 2161 2082 if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) ··· 2166 2083 kfree(opendata->f_attr.mdsthreshold); 2167 2084 opendata->f_attr.mdsthreshold = NULL; 2168 2085 2086 + nfs4_label_free(olabel); 2087 + 2169 2088 nfs4_opendata_put(opendata); 2170 2089 nfs4_put_state_owner(sp); 2171 2090 return 0; 2091 + err_free_label: 2092 + nfs4_label_free(olabel); 2172 2093 err_opendata_put: 2173 2094 kfree(opendata->f_attr.mdsthreshold); 2174 2095 nfs4_opendata_put(opendata); ··· 2186 2099 static struct nfs4_state *nfs4_do_open(struct inode *dir, 2187 2100 struct nfs_open_context *ctx, 2188 2101 int flags, 2189 - struct iattr *sattr) 2102 + struct iattr *sattr, 2103 + struct nfs4_label *label) 2190 2104 { 2191 2105 struct nfs_server *server = NFS_SERVER(dir); 2192 2106 struct nfs4_exception exception = { }; ··· 2195 2107 int status; 2196 2108 2197 2109 do { 2198 - status = _nfs4_do_open(dir, ctx, flags, sattr); 2110 + status = _nfs4_do_open(dir, ctx, flags, sattr, label); 2199 2111 res = ctx->state; 2200 2112 if (status == 0) 2201 2113 break; ··· 2242 2154 2243 2155 static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, 2244 2156 struct nfs_fattr *fattr, struct iattr *sattr, 2245 - struct nfs4_state *state) 2157 + struct nfs4_state *state, struct nfs4_label *ilabel, 2158 + struct nfs4_label *olabel) 2246 2159 { 2247 2160 struct nfs_server *server = NFS_SERVER(inode); 2248 2161 struct nfs_setattrargs arg = { ··· 2251 2162 .iap = sattr, 2252 2163 .server = server, 2253 2164 .bitmask = server->attr_bitmask, 2165 + .label = ilabel, 2254 2166 }; 2255 2167 struct nfs_setattrres res = { 2256 2168 .fattr = fattr, 2169 + .label = olabel, 2257 2170 .server = server, 2258 2171 }; 2259 2172 struct rpc_message msg = { ··· 2268 2177 fmode_t fmode; 2269 2178 bool truncate; 2270 2179 int status; 2180 + 2181 + arg.bitmask = nfs4_bitmask(server, ilabel); 2182 + if (ilabel) 2183 + arg.bitmask = nfs4_bitmask(server, olabel); 2271 2184 2272 2185 nfs_fattr_init(fattr); 2273 2186 ··· 2299 2204 2300 2205 static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, 2301 2206 struct nfs_fattr *fattr, struct iattr *sattr, 2302 - struct nfs4_state *state) 2207 + struct nfs4_state *state, struct nfs4_label *ilabel, 2208 + struct nfs4_label *olabel) 2303 2209 { 2304 2210 struct nfs_server *server = NFS_SERVER(inode); 2305 2211 struct nfs4_exception exception = { ··· 2309 2213 }; 2310 2214 int err; 2311 2215 do { 2312 - err = _nfs4_do_setattr(inode, cred, fattr, sattr, state); 2216 + err = _nfs4_do_setattr(inode, cred, fattr, sattr, state, ilabel, olabel); 2313 2217 switch (err) { 2314 2218 case -NFS4ERR_OPENMODE: 2315 2219 if (!(sattr->ia_valid & ATTR_SIZE)) { ··· 2554 2458 nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags, struct iattr *attr) 2555 2459 { 2556 2460 struct nfs4_state *state; 2461 + struct nfs4_label l = {0, 0, 0, NULL}, *label = NULL; 2462 + 2463 + label = nfs4_label_init_security(dir, ctx->dentry, attr, &l); 2557 2464 2558 2465 /* Protect against concurrent sillydeletes */ 2559 - state = nfs4_do_open(dir, ctx, open_flags, attr); 2466 + state = nfs4_do_open(dir, ctx, open_flags, attr, label); 2467 + 2468 + nfs4_label_release_security(label); 2469 + 2560 2470 if (IS_ERR(state)) 2561 2471 return ERR_CAST(state); 2562 2472 return state->inode; ··· 2621 2519 server->caps |= NFS_CAP_CTIME; 2622 2520 if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY) 2623 2521 server->caps |= NFS_CAP_MTIME; 2522 + #ifdef CONFIG_NFS_V4_SECURITY_LABEL 2523 + if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL) 2524 + server->caps |= NFS_CAP_SECURITY_LABEL; 2525 + #endif 2526 + memcpy(server->attr_bitmask_nl, res.attr_bitmask, 2527 + sizeof(server->attr_bitmask)); 2624 2528 2529 + if (server->caps & NFS_CAP_SECURITY_LABEL) { 2530 + server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL; 2531 + res.attr_bitmask[2] &= ~FATTR4_WORD2_SECURITY_LABEL; 2532 + } 2625 2533 memcpy(server->cache_consistency_bitmask, res.attr_bitmask, sizeof(server->cache_consistency_bitmask)); 2626 2534 server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE; 2627 2535 server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; ··· 2657 2545 static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, 2658 2546 struct nfs_fsinfo *info) 2659 2547 { 2548 + u32 bitmask[3]; 2660 2549 struct nfs4_lookup_root_arg args = { 2661 - .bitmask = nfs4_fattr_bitmap, 2550 + .bitmask = bitmask, 2662 2551 }; 2663 2552 struct nfs4_lookup_res res = { 2664 2553 .server = server, ··· 2671 2558 .rpc_argp = &args, 2672 2559 .rpc_resp = &res, 2673 2560 }; 2561 + 2562 + bitmask[0] = nfs4_fattr_bitmap[0]; 2563 + bitmask[1] = nfs4_fattr_bitmap[1]; 2564 + /* 2565 + * Process the label in the upcoming getfattr 2566 + */ 2567 + bitmask[2] = nfs4_fattr_bitmap[2] & ~FATTR4_WORD2_SECURITY_LABEL; 2674 2568 2675 2569 nfs_fattr_init(info->fattr); 2676 2570 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); ··· 2798 2678 { 2799 2679 int error; 2800 2680 struct nfs_fattr *fattr = info->fattr; 2681 + struct nfs4_label *label = NULL; 2801 2682 2802 2683 error = nfs4_server_capabilities(server, mntfh); 2803 2684 if (error < 0) { ··· 2806 2685 return error; 2807 2686 } 2808 2687 2809 - error = nfs4_proc_getattr(server, mntfh, fattr); 2688 + label = nfs4_label_alloc(server, GFP_KERNEL); 2689 + if (IS_ERR(label)) 2690 + return PTR_ERR(label); 2691 + 2692 + error = nfs4_proc_getattr(server, mntfh, fattr, label); 2810 2693 if (error < 0) { 2811 2694 dprintk("nfs4_get_root: getattr error = %d\n", -error); 2812 - return error; 2695 + goto err_free_label; 2813 2696 } 2814 2697 2815 2698 if (fattr->valid & NFS_ATTR_FATTR_FSID && 2816 2699 !nfs_fsid_equal(&server->fsid, &fattr->fsid)) 2817 2700 memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid)); 2701 + 2702 + err_free_label: 2703 + nfs4_label_free(label); 2818 2704 2819 2705 return error; 2820 2706 } ··· 2869 2741 return status; 2870 2742 } 2871 2743 2872 - static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2744 + static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, 2745 + struct nfs_fattr *fattr, struct nfs4_label *label) 2873 2746 { 2874 2747 struct nfs4_getattr_arg args = { 2875 2748 .fh = fhandle, ··· 2878 2749 }; 2879 2750 struct nfs4_getattr_res res = { 2880 2751 .fattr = fattr, 2752 + .label = label, 2881 2753 .server = server, 2882 2754 }; 2883 2755 struct rpc_message msg = { ··· 2886 2756 .rpc_argp = &args, 2887 2757 .rpc_resp = &res, 2888 2758 }; 2889 - 2759 + 2760 + args.bitmask = nfs4_bitmask(server, label); 2761 + 2890 2762 nfs_fattr_init(fattr); 2891 2763 return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); 2892 2764 } 2893 2765 2894 - static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2766 + static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, 2767 + struct nfs_fattr *fattr, struct nfs4_label *label) 2895 2768 { 2896 2769 struct nfs4_exception exception = { }; 2897 2770 int err; 2898 2771 do { 2899 2772 err = nfs4_handle_exception(server, 2900 - _nfs4_proc_getattr(server, fhandle, fattr), 2773 + _nfs4_proc_getattr(server, fhandle, fattr, label), 2901 2774 &exception); 2902 2775 } while (exception.retry); 2903 2776 return err; ··· 2930 2797 struct inode *inode = dentry->d_inode; 2931 2798 struct rpc_cred *cred = NULL; 2932 2799 struct nfs4_state *state = NULL; 2800 + struct nfs4_label *label = NULL; 2933 2801 int status; 2934 2802 2935 2803 if (pnfs_ld_layoutret_on_setattr(inode)) ··· 2957 2823 } 2958 2824 } 2959 2825 2960 - status = nfs4_do_setattr(inode, cred, fattr, sattr, state); 2961 - if (status == 0) 2826 + label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL); 2827 + if (IS_ERR(label)) 2828 + return PTR_ERR(label); 2829 + 2830 + status = nfs4_do_setattr(inode, cred, fattr, sattr, state, NULL, label); 2831 + if (status == 0) { 2962 2832 nfs_setattr_update_inode(inode, sattr); 2833 + nfs_setsecurity(inode, fattr, label); 2834 + } 2835 + nfs4_label_free(label); 2963 2836 return status; 2964 2837 } 2965 2838 2966 2839 static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, 2967 2840 const struct qstr *name, struct nfs_fh *fhandle, 2968 - struct nfs_fattr *fattr) 2841 + struct nfs_fattr *fattr, struct nfs4_label *label) 2969 2842 { 2970 2843 struct nfs_server *server = NFS_SERVER(dir); 2971 2844 int status; ··· 2984 2843 struct nfs4_lookup_res res = { 2985 2844 .server = server, 2986 2845 .fattr = fattr, 2846 + .label = label, 2987 2847 .fh = fhandle, 2988 2848 }; 2989 2849 struct rpc_message msg = { ··· 2992 2850 .rpc_argp = &args, 2993 2851 .rpc_resp = &res, 2994 2852 }; 2853 + 2854 + args.bitmask = nfs4_bitmask(server, label); 2995 2855 2996 2856 nfs_fattr_init(fattr); 2997 2857 ··· 3013 2869 3014 2870 static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir, 3015 2871 struct qstr *name, struct nfs_fh *fhandle, 3016 - struct nfs_fattr *fattr) 2872 + struct nfs_fattr *fattr, struct nfs4_label *label) 3017 2873 { 3018 2874 struct nfs4_exception exception = { }; 3019 2875 struct rpc_clnt *client = *clnt; 3020 2876 int err; 3021 2877 do { 3022 - err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr); 2878 + err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr, label); 3023 2879 switch (err) { 3024 2880 case -NFS4ERR_BADNAME: 3025 2881 err = -ENOENT; ··· 3053 2909 } 3054 2910 3055 2911 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, 3056 - struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2912 + struct nfs_fh *fhandle, struct nfs_fattr *fattr, 2913 + struct nfs4_label *label) 3057 2914 { 3058 2915 int status; 3059 2916 struct rpc_clnt *client = NFS_CLIENT(dir); 3060 2917 3061 - status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr); 2918 + status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, label); 3062 2919 if (client != NFS_CLIENT(dir)) { 3063 2920 rpc_shutdown_client(client); 3064 2921 nfs_fixup_secinfo_attributes(fattr); ··· 3074 2929 int status; 3075 2930 struct rpc_clnt *client = rpc_clone_client(NFS_CLIENT(dir)); 3076 2931 3077 - status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr); 2932 + status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, NULL); 3078 2933 if (status < 0) { 3079 2934 rpc_shutdown_client(client); 3080 2935 return ERR_PTR(status); ··· 3099 2954 .rpc_cred = entry->cred, 3100 2955 }; 3101 2956 int mode = entry->mask; 3102 - int status; 2957 + int status = 0; 3103 2958 3104 2959 /* 3105 2960 * Determine which access bits we want to ask for... ··· 3204 3059 nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, 3205 3060 int flags) 3206 3061 { 3062 + struct nfs4_label l, *ilabel = NULL; 3207 3063 struct nfs_open_context *ctx; 3208 3064 struct nfs4_state *state; 3209 3065 int status = 0; ··· 3213 3067 if (IS_ERR(ctx)) 3214 3068 return PTR_ERR(ctx); 3215 3069 3070 + ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); 3071 + 3216 3072 sattr->ia_mode &= ~current_umask(); 3217 - state = nfs4_do_open(dir, ctx, flags, sattr); 3073 + state = nfs4_do_open(dir, ctx, flags, sattr, ilabel); 3218 3074 if (IS_ERR(state)) { 3219 3075 status = PTR_ERR(state); 3220 3076 goto out; 3221 3077 } 3222 3078 out: 3079 + nfs4_label_release_security(ilabel); 3223 3080 put_nfs_open_context(ctx); 3224 3081 return status; 3225 3082 } ··· 3271 3122 res->server = server; 3272 3123 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE]; 3273 3124 nfs41_init_sequence(&args->seq_args, &res->seq_res, 1); 3125 + 3126 + nfs_fattr_init(res->dir_attr); 3274 3127 } 3275 3128 3276 3129 static void nfs4_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data) ··· 3348 3197 .rpc_resp = &res, 3349 3198 }; 3350 3199 int status = -ENOMEM; 3351 - 3200 + 3352 3201 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); 3353 3202 if (!status) { 3354 3203 update_changeattr(old_dir, &res.old_cinfo); ··· 3382 3231 }; 3383 3232 struct nfs4_link_res res = { 3384 3233 .server = server, 3234 + .label = NULL, 3385 3235 }; 3386 3236 struct rpc_message msg = { 3387 3237 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK], ··· 3395 3243 if (res.fattr == NULL) 3396 3244 goto out; 3397 3245 3246 + res.label = nfs4_label_alloc(server, GFP_KERNEL); 3247 + if (IS_ERR(res.label)) { 3248 + status = PTR_ERR(res.label); 3249 + goto out; 3250 + } 3251 + arg.bitmask = nfs4_bitmask(server, res.label); 3252 + 3398 3253 status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); 3399 3254 if (!status) { 3400 3255 update_changeattr(dir, &res.cinfo); 3401 - nfs_post_op_update_inode(inode, res.fattr); 3256 + status = nfs_post_op_update_inode(inode, res.fattr); 3257 + if (!status) 3258 + nfs_setsecurity(inode, res.fattr, res.label); 3402 3259 } 3260 + 3261 + 3262 + nfs4_label_free(res.label); 3263 + 3403 3264 out: 3404 3265 nfs_free_fattr(res.fattr); 3405 3266 return status; ··· 3436 3271 struct nfs4_create_res res; 3437 3272 struct nfs_fh fh; 3438 3273 struct nfs_fattr fattr; 3274 + struct nfs4_label *label; 3439 3275 }; 3440 3276 3441 3277 static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, ··· 3448 3282 if (data != NULL) { 3449 3283 struct nfs_server *server = NFS_SERVER(dir); 3450 3284 3285 + data->label = nfs4_label_alloc(server, GFP_KERNEL); 3286 + if (IS_ERR(data->label)) 3287 + goto out_free; 3288 + 3451 3289 data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE]; 3452 3290 data->msg.rpc_argp = &data->arg; 3453 3291 data->msg.rpc_resp = &data->res; ··· 3460 3290 data->arg.name = name; 3461 3291 data->arg.attrs = sattr; 3462 3292 data->arg.ftype = ftype; 3463 - data->arg.bitmask = server->attr_bitmask; 3293 + data->arg.bitmask = nfs4_bitmask(server, data->label); 3464 3294 data->res.server = server; 3465 3295 data->res.fh = &data->fh; 3466 3296 data->res.fattr = &data->fattr; 3297 + data->res.label = data->label; 3467 3298 nfs_fattr_init(data->res.fattr); 3468 3299 } 3469 3300 return data; 3301 + out_free: 3302 + kfree(data); 3303 + return NULL; 3470 3304 } 3471 3305 3472 3306 static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data) ··· 3479 3305 &data->arg.seq_args, &data->res.seq_res, 1); 3480 3306 if (status == 0) { 3481 3307 update_changeattr(dir, &data->res.dir_cinfo); 3482 - status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); 3308 + status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, data->res.label); 3483 3309 } 3484 3310 return status; 3485 3311 } 3486 3312 3487 3313 static void nfs4_free_createdata(struct nfs4_createdata *data) 3488 3314 { 3315 + nfs4_label_free(data->label); 3489 3316 kfree(data); 3490 3317 } 3491 3318 3492 3319 static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, 3493 - struct page *page, unsigned int len, struct iattr *sattr) 3320 + struct page *page, unsigned int len, struct iattr *sattr, 3321 + struct nfs4_label *label) 3494 3322 { 3495 3323 struct nfs4_createdata *data; 3496 3324 int status = -ENAMETOOLONG; ··· 3508 3332 data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK]; 3509 3333 data->arg.u.symlink.pages = &page; 3510 3334 data->arg.u.symlink.len = len; 3335 + data->arg.label = label; 3511 3336 3512 3337 status = nfs4_do_create(dir, dentry, data); 3513 3338 ··· 3521 3344 struct page *page, unsigned int len, struct iattr *sattr) 3522 3345 { 3523 3346 struct nfs4_exception exception = { }; 3347 + struct nfs4_label l, *label = NULL; 3524 3348 int err; 3349 + 3350 + label = nfs4_label_init_security(dir, dentry, sattr, &l); 3351 + 3525 3352 do { 3526 3353 err = nfs4_handle_exception(NFS_SERVER(dir), 3527 3354 _nfs4_proc_symlink(dir, dentry, page, 3528 - len, sattr), 3355 + len, sattr, label), 3529 3356 &exception); 3530 3357 } while (exception.retry); 3358 + 3359 + nfs4_label_release_security(label); 3531 3360 return err; 3532 3361 } 3533 3362 3534 3363 static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, 3535 - struct iattr *sattr) 3364 + struct iattr *sattr, struct nfs4_label *label) 3536 3365 { 3537 3366 struct nfs4_createdata *data; 3538 3367 int status = -ENOMEM; ··· 3547 3364 if (data == NULL) 3548 3365 goto out; 3549 3366 3367 + data->arg.label = label; 3550 3368 status = nfs4_do_create(dir, dentry, data); 3551 3369 3552 3370 nfs4_free_createdata(data); ··· 3559 3375 struct iattr *sattr) 3560 3376 { 3561 3377 struct nfs4_exception exception = { }; 3378 + struct nfs4_label l, *label = NULL; 3562 3379 int err; 3380 + 3381 + label = nfs4_label_init_security(dir, dentry, sattr, &l); 3563 3382 3564 3383 sattr->ia_mode &= ~current_umask(); 3565 3384 do { 3566 3385 err = nfs4_handle_exception(NFS_SERVER(dir), 3567 - _nfs4_proc_mkdir(dir, dentry, sattr), 3386 + _nfs4_proc_mkdir(dir, dentry, sattr, label), 3568 3387 &exception); 3569 3388 } while (exception.retry); 3389 + nfs4_label_release_security(label); 3390 + 3570 3391 return err; 3571 3392 } 3572 3393 ··· 3629 3440 } 3630 3441 3631 3442 static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, 3632 - struct iattr *sattr, dev_t rdev) 3443 + struct iattr *sattr, struct nfs4_label *label, dev_t rdev) 3633 3444 { 3634 3445 struct nfs4_createdata *data; 3635 3446 int mode = sattr->ia_mode; ··· 3654 3465 status = -EINVAL; 3655 3466 goto out_free; 3656 3467 } 3657 - 3468 + 3469 + data->arg.label = label; 3658 3470 status = nfs4_do_create(dir, dentry, data); 3659 3471 out_free: 3660 3472 nfs4_free_createdata(data); ··· 3667 3477 struct iattr *sattr, dev_t rdev) 3668 3478 { 3669 3479 struct nfs4_exception exception = { }; 3480 + struct nfs4_label l, *label = NULL; 3670 3481 int err; 3482 + 3483 + label = nfs4_label_init_security(dir, dentry, sattr, &l); 3671 3484 3672 3485 sattr->ia_mode &= ~current_umask(); 3673 3486 do { 3674 3487 err = nfs4_handle_exception(NFS_SERVER(dir), 3675 - _nfs4_proc_mknod(dir, dentry, sattr, rdev), 3488 + _nfs4_proc_mknod(dir, dentry, sattr, label, rdev), 3676 3489 &exception); 3677 3490 } while (exception.retry); 3491 + 3492 + nfs4_label_release_security(label); 3493 + 3678 3494 return err; 3679 3495 } 3680 3496 ··· 4406 4210 } while (exception.retry); 4407 4211 return err; 4408 4212 } 4213 + 4214 + #ifdef CONFIG_NFS_V4_SECURITY_LABEL 4215 + static int _nfs4_get_security_label(struct inode *inode, void *buf, 4216 + size_t buflen) 4217 + { 4218 + struct nfs_server *server = NFS_SERVER(inode); 4219 + struct nfs_fattr fattr; 4220 + struct nfs4_label label = {0, 0, buflen, buf}; 4221 + 4222 + u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL }; 4223 + struct nfs4_getattr_arg args = { 4224 + .fh = NFS_FH(inode), 4225 + .bitmask = bitmask, 4226 + }; 4227 + struct nfs4_getattr_res res = { 4228 + .fattr = &fattr, 4229 + .label = &label, 4230 + .server = server, 4231 + }; 4232 + struct rpc_message msg = { 4233 + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETATTR], 4234 + .rpc_argp = &args, 4235 + .rpc_resp = &res, 4236 + }; 4237 + int ret; 4238 + 4239 + nfs_fattr_init(&fattr); 4240 + 4241 + ret = rpc_call_sync(server->client, &msg, 0); 4242 + if (ret) 4243 + return ret; 4244 + if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL)) 4245 + return -ENOENT; 4246 + if (buflen < label.len) 4247 + return -ERANGE; 4248 + return 0; 4249 + } 4250 + 4251 + static int nfs4_get_security_label(struct inode *inode, void *buf, 4252 + size_t buflen) 4253 + { 4254 + struct nfs4_exception exception = { }; 4255 + int err; 4256 + 4257 + if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL)) 4258 + return -EOPNOTSUPP; 4259 + 4260 + do { 4261 + err = nfs4_handle_exception(NFS_SERVER(inode), 4262 + _nfs4_get_security_label(inode, buf, buflen), 4263 + &exception); 4264 + } while (exception.retry); 4265 + return err; 4266 + } 4267 + 4268 + static int _nfs4_do_set_security_label(struct inode *inode, 4269 + struct nfs4_label *ilabel, 4270 + struct nfs_fattr *fattr, 4271 + struct nfs4_label *olabel) 4272 + { 4273 + 4274 + struct iattr sattr = {0}; 4275 + struct nfs_server *server = NFS_SERVER(inode); 4276 + const u32 bitmask[3] = { 0, 0, FATTR4_WORD2_SECURITY_LABEL }; 4277 + struct nfs_setattrargs args = { 4278 + .fh = NFS_FH(inode), 4279 + .iap = &sattr, 4280 + .server = server, 4281 + .bitmask = bitmask, 4282 + .label = ilabel, 4283 + }; 4284 + struct nfs_setattrres res = { 4285 + .fattr = fattr, 4286 + .label = olabel, 4287 + .server = server, 4288 + }; 4289 + struct rpc_message msg = { 4290 + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETATTR], 4291 + .rpc_argp = &args, 4292 + .rpc_resp = &res, 4293 + }; 4294 + int status; 4295 + 4296 + nfs4_stateid_copy(&args.stateid, &zero_stateid); 4297 + 4298 + status = rpc_call_sync(server->client, &msg, 0); 4299 + if (status) 4300 + dprintk("%s failed: %d\n", __func__, status); 4301 + 4302 + return status; 4303 + } 4304 + 4305 + static int nfs4_do_set_security_label(struct inode *inode, 4306 + struct nfs4_label *ilabel, 4307 + struct nfs_fattr *fattr, 4308 + struct nfs4_label *olabel) 4309 + { 4310 + struct nfs4_exception exception = { }; 4311 + int err; 4312 + 4313 + do { 4314 + err = nfs4_handle_exception(NFS_SERVER(inode), 4315 + _nfs4_do_set_security_label(inode, ilabel, 4316 + fattr, olabel), 4317 + &exception); 4318 + } while (exception.retry); 4319 + return err; 4320 + } 4321 + 4322 + static int 4323 + nfs4_set_security_label(struct dentry *dentry, const void *buf, size_t buflen) 4324 + { 4325 + struct nfs4_label ilabel, *olabel = NULL; 4326 + struct nfs_fattr fattr; 4327 + struct rpc_cred *cred; 4328 + struct inode *inode = dentry->d_inode; 4329 + int status; 4330 + 4331 + if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL)) 4332 + return -EOPNOTSUPP; 4333 + 4334 + nfs_fattr_init(&fattr); 4335 + 4336 + ilabel.pi = 0; 4337 + ilabel.lfs = 0; 4338 + ilabel.label = (char *)buf; 4339 + ilabel.len = buflen; 4340 + 4341 + cred = rpc_lookup_cred(); 4342 + if (IS_ERR(cred)) 4343 + return PTR_ERR(cred); 4344 + 4345 + olabel = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL); 4346 + if (IS_ERR(olabel)) { 4347 + status = -PTR_ERR(olabel); 4348 + goto out; 4349 + } 4350 + 4351 + status = nfs4_do_set_security_label(inode, &ilabel, &fattr, olabel); 4352 + if (status == 0) 4353 + nfs_setsecurity(inode, &fattr, olabel); 4354 + 4355 + nfs4_label_free(olabel); 4356 + out: 4357 + put_rpccred(cred); 4358 + return status; 4359 + } 4360 + #endif /* CONFIG_NFS_V4_SECURITY_LABEL */ 4361 + 4409 4362 4410 4363 static int 4411 4364 nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state) ··· 5669 5324 return len; 5670 5325 } 5671 5326 5327 + #ifdef CONFIG_NFS_V4_SECURITY_LABEL 5328 + static inline int nfs4_server_supports_labels(struct nfs_server *server) 5329 + { 5330 + return server->caps & NFS_CAP_SECURITY_LABEL; 5331 + } 5332 + 5333 + static int nfs4_xattr_set_nfs4_label(struct dentry *dentry, const char *key, 5334 + const void *buf, size_t buflen, 5335 + int flags, int type) 5336 + { 5337 + if (security_ismaclabel(key)) 5338 + return nfs4_set_security_label(dentry, buf, buflen); 5339 + 5340 + return -EOPNOTSUPP; 5341 + } 5342 + 5343 + static int nfs4_xattr_get_nfs4_label(struct dentry *dentry, const char *key, 5344 + void *buf, size_t buflen, int type) 5345 + { 5346 + if (security_ismaclabel(key)) 5347 + return nfs4_get_security_label(dentry->d_inode, buf, buflen); 5348 + return -EOPNOTSUPP; 5349 + } 5350 + 5351 + static size_t nfs4_xattr_list_nfs4_label(struct dentry *dentry, char *list, 5352 + size_t list_len, const char *name, 5353 + size_t name_len, int type) 5354 + { 5355 + size_t len = 0; 5356 + 5357 + if (nfs_server_capable(dentry->d_inode, NFS_CAP_SECURITY_LABEL)) { 5358 + len = security_inode_listsecurity(dentry->d_inode, NULL, 0); 5359 + if (list && len <= list_len) 5360 + security_inode_listsecurity(dentry->d_inode, list, len); 5361 + } 5362 + return len; 5363 + } 5364 + 5365 + static const struct xattr_handler nfs4_xattr_nfs4_label_handler = { 5366 + .prefix = XATTR_SECURITY_PREFIX, 5367 + .list = nfs4_xattr_list_nfs4_label, 5368 + .get = nfs4_xattr_get_nfs4_label, 5369 + .set = nfs4_xattr_set_nfs4_label, 5370 + }; 5371 + #endif 5372 + 5373 + 5672 5374 /* 5673 5375 * nfs_fhget will use either the mounted_on_fileid or the fileid 5674 5376 */ ··· 5739 5347 struct page *page) 5740 5348 { 5741 5349 struct nfs_server *server = NFS_SERVER(dir); 5742 - u32 bitmask[2] = { 5350 + u32 bitmask[3] = { 5743 5351 [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, 5744 5352 }; 5745 5353 struct nfs4_fs_locations_arg args = { ··· 7444 7052 }; 7445 7053 #endif 7446 7054 7055 + #if defined(CONFIG_NFS_V4_2) 7056 + static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = { 7057 + .minor_version = 2, 7058 + .init_caps = NFS_CAP_READDIRPLUS 7059 + | NFS_CAP_ATOMIC_OPEN 7060 + | NFS_CAP_CHANGE_ATTR 7061 + | NFS_CAP_POSIX_LOCK 7062 + | NFS_CAP_STATEID_NFSV41 7063 + | NFS_CAP_ATOMIC_OPEN_V1, 7064 + .call_sync = nfs4_call_sync_sequence, 7065 + .match_stateid = nfs41_match_stateid, 7066 + .find_root_sec = nfs41_find_root_sec, 7067 + .free_lock_state = nfs41_free_lock_state, 7068 + .reboot_recovery_ops = &nfs41_reboot_recovery_ops, 7069 + .nograce_recovery_ops = &nfs41_nograce_recovery_ops, 7070 + .state_renewal_ops = &nfs41_state_renewal_ops, 7071 + }; 7072 + #endif 7073 + 7447 7074 const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = { 7448 7075 [0] = &nfs_v4_0_minor_ops, 7449 7076 #if defined(CONFIG_NFS_V4_1) 7450 7077 [1] = &nfs_v4_1_minor_ops, 7078 + #endif 7079 + #if defined(CONFIG_NFS_V4_2) 7080 + [2] = &nfs_v4_2_minor_ops, 7451 7081 #endif 7452 7082 }; 7453 7083 ··· 7570 7156 7571 7157 const struct xattr_handler *nfs4_xattr_handlers[] = { 7572 7158 &nfs4_xattr_nfs4_acl_handler, 7159 + #ifdef CONFIG_NFS_V4_SECURITY_LABEL 7160 + &nfs4_xattr_nfs4_label_handler, 7161 + #endif 7573 7162 NULL 7574 7163 }; 7575 7164
+137 -37
fs/nfs/nfs4xdr.c
··· 102 102 #define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) 103 103 #define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 104 104 #define nfs4_group_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 105 + #ifdef CONFIG_NFS_V4_SECURITY_LABEL 106 + /* PI(4 bytes) + LFS(4 bytes) + 1(for null terminator?) + MAXLABELLEN */ 107 + #define nfs4_label_maxsz (4 + 4 + 1 + XDR_QUADLEN(NFS4_MAXLABELLEN)) 108 + #define encode_readdir_space 24 109 + #define encode_readdir_bitmask_sz 3 110 + #else 111 + #define nfs4_label_maxsz 0 112 + #define encode_readdir_space 20 113 + #define encode_readdir_bitmask_sz 2 114 + #endif 105 115 /* We support only one layout type per file system */ 106 116 #define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8) 107 117 /* This is based on getfattr, which uses the most attributes: */ 108 118 #define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \ 109 119 3 + 3 + 3 + nfs4_owner_maxsz + \ 110 - nfs4_group_maxsz + decode_mdsthreshold_maxsz)) 120 + nfs4_group_maxsz + nfs4_label_maxsz + \ 121 + decode_mdsthreshold_maxsz)) 111 122 #define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \ 112 123 nfs4_fattr_value_maxsz) 113 124 #define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz) ··· 126 115 1 + 2 + 1 + \ 127 116 nfs4_owner_maxsz + \ 128 117 nfs4_group_maxsz + \ 118 + nfs4_label_maxsz + \ 129 119 4 + 4) 130 120 #define encode_savefh_maxsz (op_encode_hdr_maxsz) 131 121 #define decode_savefh_maxsz (op_decode_hdr_maxsz) ··· 204 192 encode_stateid_maxsz + 3) 205 193 #define decode_read_maxsz (op_decode_hdr_maxsz + 2) 206 194 #define encode_readdir_maxsz (op_encode_hdr_maxsz + \ 207 - 2 + encode_verifier_maxsz + 5) 195 + 2 + encode_verifier_maxsz + 5 + \ 196 + nfs4_label_maxsz) 208 197 #define decode_readdir_maxsz (op_decode_hdr_maxsz + \ 209 - decode_verifier_maxsz) 198 + decode_verifier_maxsz + \ 199 + nfs4_label_maxsz + nfs4_fattr_maxsz) 210 200 #define encode_readlink_maxsz (op_encode_hdr_maxsz) 211 201 #define decode_readlink_maxsz (op_decode_hdr_maxsz + 1) 212 202 #define encode_write_maxsz (op_encode_hdr_maxsz + \ ··· 988 974 encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE); 989 975 } 990 976 991 - static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs_server *server) 977 + static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, 978 + const struct nfs4_label *label, 979 + const struct nfs_server *server) 992 980 { 993 981 char owner_name[IDMAP_NAMESZ]; 994 982 char owner_group[IDMAP_NAMESZ]; ··· 1001 985 int len; 1002 986 uint32_t bmval0 = 0; 1003 987 uint32_t bmval1 = 0; 988 + uint32_t bmval2 = 0; 1004 989 1005 990 /* 1006 991 * We reserve enough space to write the entire attribute buffer at once. 1007 992 * In the worst-case, this would be 1008 - * 12(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime) 1009 - * = 36 bytes, plus any contribution from variable-length fields 993 + * 16(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime) 994 + * = 40 bytes, plus any contribution from variable-length fields 1010 995 * such as owner/group. 1011 996 */ 1012 - len = 16; 997 + len = 20; 1013 998 1014 999 /* Sigh */ 1015 1000 if (iap->ia_valid & ATTR_SIZE) ··· 1040 1023 } 1041 1024 len += 4 + (XDR_QUADLEN(owner_grouplen) << 2); 1042 1025 } 1026 + if (label) 1027 + len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2); 1043 1028 if (iap->ia_valid & ATTR_ATIME_SET) 1044 1029 len += 16; 1045 1030 else if (iap->ia_valid & ATTR_ATIME) ··· 1056 1037 * We write the bitmap length now, but leave the bitmap and the attribute 1057 1038 * buffer length to be backfilled at the end of this routine. 1058 1039 */ 1059 - *p++ = cpu_to_be32(2); 1040 + *p++ = cpu_to_be32(3); 1060 1041 q = p; 1061 - p += 3; 1042 + p += 4; 1062 1043 1063 1044 if (iap->ia_valid & ATTR_SIZE) { 1064 1045 bmval0 |= FATTR4_WORD0_SIZE; ··· 1096 1077 bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; 1097 1078 *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); 1098 1079 } 1080 + if (label) { 1081 + bmval2 |= FATTR4_WORD2_SECURITY_LABEL; 1082 + *p++ = cpu_to_be32(label->lfs); 1083 + *p++ = cpu_to_be32(label->pi); 1084 + *p++ = cpu_to_be32(label->len); 1085 + p = xdr_encode_opaque_fixed(p, label->label, label->len); 1086 + } 1099 1087 1100 1088 /* 1101 1089 * Now we backfill the bitmap and the attribute buffer length. ··· 1112 1086 len, ((char *)p - (char *)q) + 4); 1113 1087 BUG(); 1114 1088 } 1115 - len = (char *)p - (char *)q - 12; 1089 + len = (char *)p - (char *)q - 16; 1116 1090 *q++ = htonl(bmval0); 1117 1091 *q++ = htonl(bmval1); 1092 + *q++ = htonl(bmval2); 1118 1093 *q = htonl(len); 1119 1094 1120 1095 /* out: */ ··· 1169 1142 } 1170 1143 1171 1144 encode_string(xdr, create->name->len, create->name->name); 1172 - encode_attrs(xdr, create->attrs, create->server); 1145 + encode_attrs(xdr, create->attrs, create->label, create->server); 1173 1146 } 1174 1147 1175 1148 static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) ··· 1221 1194 1222 1195 static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1223 1196 { 1224 - encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0], 1225 - bitmask[1] & nfs4_fattr_bitmap[1], hdr); 1197 + encode_getattr_three(xdr, bitmask[0] & nfs4_fattr_bitmap[0], 1198 + bitmask[1] & nfs4_fattr_bitmap[1], 1199 + bitmask[2] & nfs4_fattr_bitmap[2], 1200 + hdr); 1226 1201 } 1227 1202 1228 1203 static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask, ··· 1402 1373 switch(arg->createmode) { 1403 1374 case NFS4_CREATE_UNCHECKED: 1404 1375 *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); 1405 - encode_attrs(xdr, arg->u.attrs, arg->server); 1376 + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server); 1406 1377 break; 1407 1378 case NFS4_CREATE_GUARDED: 1408 1379 *p = cpu_to_be32(NFS4_CREATE_GUARDED); 1409 - encode_attrs(xdr, arg->u.attrs, arg->server); 1380 + encode_attrs(xdr, arg->u.attrs, arg->label, arg->server); 1410 1381 break; 1411 1382 case NFS4_CREATE_EXCLUSIVE: 1412 1383 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); ··· 1416 1387 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); 1417 1388 encode_nfs4_verifier(xdr, &arg->u.verifier); 1418 1389 dummy.ia_valid = 0; 1419 - encode_attrs(xdr, &dummy, arg->server); 1390 + encode_attrs(xdr, &dummy, arg->label, arg->server); 1420 1391 } 1421 1392 } 1422 1393 ··· 1567 1538 1568 1539 static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) 1569 1540 { 1570 - uint32_t attrs[2] = { 1541 + uint32_t attrs[3] = { 1571 1542 FATTR4_WORD0_RDATTR_ERROR, 1572 1543 FATTR4_WORD1_MOUNTED_ON_FILEID, 1573 1544 }; ··· 1590 1561 encode_op_hdr(xdr, OP_READDIR, decode_readdir_maxsz, hdr); 1591 1562 encode_uint64(xdr, readdir->cookie); 1592 1563 encode_nfs4_verifier(xdr, &readdir->verifier); 1593 - p = reserve_space(xdr, 20); 1564 + p = reserve_space(xdr, encode_readdir_space); 1594 1565 *p++ = cpu_to_be32(dircount); 1595 1566 *p++ = cpu_to_be32(readdir->count); 1596 - *p++ = cpu_to_be32(2); 1597 - 1567 + *p++ = cpu_to_be32(encode_readdir_bitmask_sz); 1598 1568 *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]); 1599 - *p = cpu_to_be32(attrs[1] & readdir->bitmask[1]); 1569 + *p = cpu_to_be32(attrs[1] & readdir->bitmask[1]); 1570 + if (encode_readdir_bitmask_sz > 2) { 1571 + if (hdr->minorversion > 1) 1572 + attrs[2] |= FATTR4_WORD2_SECURITY_LABEL; 1573 + p++, *p++ = cpu_to_be32(attrs[2] & readdir->bitmask[2]); 1574 + } 1600 1575 memcpy(verf, readdir->verifier.data, sizeof(verf)); 1601 - dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n", 1576 + 1577 + dprintk("%s: cookie = %llu, verifier = %08x:%08x, bitmap = %08x:%08x:%08x\n", 1602 1578 __func__, 1603 1579 (unsigned long long)readdir->cookie, 1604 1580 verf[0], verf[1], 1605 1581 attrs[0] & readdir->bitmask[0], 1606 - attrs[1] & readdir->bitmask[1]); 1582 + attrs[1] & readdir->bitmask[1], 1583 + attrs[2] & readdir->bitmask[2]); 1607 1584 } 1608 1585 1609 1586 static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req, struct compound_hdr *hdr) ··· 1668 1633 { 1669 1634 encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); 1670 1635 encode_nfs4_stateid(xdr, &arg->stateid); 1671 - encode_attrs(xdr, arg->iap, server); 1636 + encode_attrs(xdr, arg->iap, arg->label, server); 1672 1637 } 1673 1638 1674 1639 static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) ··· 4079 4044 return status; 4080 4045 } 4081 4046 4047 + static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap, 4048 + struct nfs4_label *label) 4049 + { 4050 + uint32_t pi = 0; 4051 + uint32_t lfs = 0; 4052 + __u32 len; 4053 + __be32 *p; 4054 + int status = 0; 4055 + 4056 + if (unlikely(bitmap[2] & (FATTR4_WORD2_SECURITY_LABEL - 1U))) 4057 + return -EIO; 4058 + if (likely(bitmap[2] & FATTR4_WORD2_SECURITY_LABEL)) { 4059 + p = xdr_inline_decode(xdr, 4); 4060 + if (unlikely(!p)) 4061 + goto out_overflow; 4062 + lfs = be32_to_cpup(p++); 4063 + p = xdr_inline_decode(xdr, 4); 4064 + if (unlikely(!p)) 4065 + goto out_overflow; 4066 + pi = be32_to_cpup(p++); 4067 + p = xdr_inline_decode(xdr, 4); 4068 + if (unlikely(!p)) 4069 + goto out_overflow; 4070 + len = be32_to_cpup(p++); 4071 + p = xdr_inline_decode(xdr, len); 4072 + if (unlikely(!p)) 4073 + goto out_overflow; 4074 + if (len < NFS4_MAXLABELLEN) { 4075 + if (label) { 4076 + memcpy(label->label, p, len); 4077 + label->len = len; 4078 + label->pi = pi; 4079 + label->lfs = lfs; 4080 + status = NFS_ATTR_FATTR_V4_SECURITY_LABEL; 4081 + } 4082 + bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL; 4083 + } else 4084 + printk(KERN_WARNING "%s: label too long (%u)!\n", 4085 + __func__, len); 4086 + } 4087 + if (label && label->label) 4088 + dprintk("%s: label=%s, len=%d, PI=%d, LFS=%d\n", __func__, 4089 + (char *)label->label, label->len, label->pi, label->lfs); 4090 + return status; 4091 + 4092 + out_overflow: 4093 + print_overflow_msg(__func__, xdr); 4094 + return -EIO; 4095 + } 4096 + 4082 4097 static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) 4083 4098 { 4084 4099 int status = 0; ··· 4471 4386 4472 4387 static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, 4473 4388 struct nfs_fattr *fattr, struct nfs_fh *fh, 4474 - struct nfs4_fs_locations *fs_loc, 4389 + struct nfs4_fs_locations *fs_loc, struct nfs4_label *label, 4475 4390 const struct nfs_server *server) 4476 4391 { 4477 4392 int status; ··· 4579 4494 if (status < 0) 4580 4495 goto xdr_error; 4581 4496 4497 + if (label) { 4498 + status = decode_attr_security_label(xdr, bitmap, label); 4499 + if (status < 0) 4500 + goto xdr_error; 4501 + fattr->valid |= status; 4502 + } 4503 + 4582 4504 xdr_error: 4583 4505 dprintk("%s: xdr returned %d\n", __func__, -status); 4584 4506 return status; ··· 4593 4501 4594 4502 static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr, 4595 4503 struct nfs_fh *fh, struct nfs4_fs_locations *fs_loc, 4596 - const struct nfs_server *server) 4504 + struct nfs4_label *label, const struct nfs_server *server) 4597 4505 { 4598 4506 unsigned int savep; 4599 4507 uint32_t attrlen, ··· 4612 4520 if (status < 0) 4613 4521 goto xdr_error; 4614 4522 4615 - status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc, server); 4523 + status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc, 4524 + label, server); 4616 4525 if (status < 0) 4617 4526 goto xdr_error; 4618 4527 ··· 4623 4530 return status; 4624 4531 } 4625 4532 4533 + static int decode_getfattr_label(struct xdr_stream *xdr, struct nfs_fattr *fattr, 4534 + struct nfs4_label *label, const struct nfs_server *server) 4535 + { 4536 + return decode_getfattr_generic(xdr, fattr, NULL, NULL, label, server); 4537 + } 4538 + 4626 4539 static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, 4627 4540 const struct nfs_server *server) 4628 4541 { 4629 - return decode_getfattr_generic(xdr, fattr, NULL, NULL, server); 4542 + return decode_getfattr_generic(xdr, fattr, NULL, NULL, NULL, server); 4630 4543 } 4631 4544 4632 4545 /* ··· 6024 5925 status = decode_getfh(xdr, res->fh); 6025 5926 if (status) 6026 5927 goto out; 6027 - status = decode_getfattr(xdr, res->fattr, res->server); 5928 + status = decode_getfattr_label(xdr, res->fattr, res->label, res->server); 6028 5929 out: 6029 5930 return status; 6030 5931 } ··· 6050 5951 goto out; 6051 5952 status = decode_getfh(xdr, res->fh); 6052 5953 if (status == 0) 6053 - status = decode_getfattr(xdr, res->fattr, res->server); 5954 + status = decode_getfattr_label(xdr, res->fattr, 5955 + res->label, res->server); 6054 5956 out: 6055 5957 return status; 6056 5958 } ··· 6142 6042 status = decode_restorefh(xdr); 6143 6043 if (status) 6144 6044 goto out; 6145 - decode_getfattr(xdr, res->fattr, res->server); 6045 + decode_getfattr_label(xdr, res->fattr, res->label, res->server); 6146 6046 out: 6147 6047 return status; 6148 6048 } ··· 6171 6071 status = decode_getfh(xdr, res->fh); 6172 6072 if (status) 6173 6073 goto out; 6174 - decode_getfattr(xdr, res->fattr, res->server); 6074 + decode_getfattr_label(xdr, res->fattr, res->label, res->server); 6175 6075 out: 6176 6076 return status; 6177 6077 } ··· 6203 6103 status = decode_putfh(xdr); 6204 6104 if (status) 6205 6105 goto out; 6206 - status = decode_getfattr(xdr, res->fattr, res->server); 6106 + status = decode_getfattr_label(xdr, res->fattr, res->label, res->server); 6207 6107 out: 6208 6108 return status; 6209 6109 } ··· 6336 6236 goto out; 6337 6237 if (res->access_request) 6338 6238 decode_access(xdr, &res->access_supported, &res->access_result); 6339 - decode_getfattr(xdr, res->f_attr, res->server); 6239 + decode_getfattr_label(xdr, res->f_attr, res->f_label, res->server); 6340 6240 out: 6341 6241 return status; 6342 6242 } ··· 6413 6313 status = decode_setattr(xdr); 6414 6314 if (status) 6415 6315 goto out; 6416 - decode_getfattr(xdr, res->fattr, res->server); 6316 + decode_getfattr_label(xdr, res->fattr, res->label, res->server); 6417 6317 out: 6418 6318 return status; 6419 6319 } ··· 6802 6702 xdr_enter_page(xdr, PAGE_SIZE); 6803 6703 status = decode_getfattr_generic(xdr, &res->fs_locations->fattr, 6804 6704 NULL, res->fs_locations, 6805 - res->fs_locations->server); 6705 + NULL, res->fs_locations->server); 6806 6706 out: 6807 6707 return status; 6808 6708 } ··· 7215 7115 goto out_overflow; 7216 7116 7217 7117 if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, 7218 - NULL, entry->server) < 0) 7118 + NULL, entry->label, entry->server) < 0) 7219 7119 goto out_overflow; 7220 7120 if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) 7221 7121 entry->ino = entry->fattr->mounted_on_fileid;
+7 -6
fs/nfs/proc.c
··· 98 98 */ 99 99 static int 100 100 nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, 101 - struct nfs_fattr *fattr) 101 + struct nfs_fattr *fattr, struct nfs4_label *label) 102 102 { 103 103 struct rpc_message msg = { 104 104 .rpc_proc = &nfs_procedures[NFSPROC_GETATTR], ··· 146 146 147 147 static int 148 148 nfs_proc_lookup(struct inode *dir, struct qstr *name, 149 - struct nfs_fh *fhandle, struct nfs_fattr *fattr) 149 + struct nfs_fh *fhandle, struct nfs_fattr *fattr, 150 + struct nfs4_label *label) 150 151 { 151 152 struct nfs_diropargs arg = { 152 153 .fh = NFS_FH(dir), ··· 244 243 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 245 244 nfs_mark_for_revalidate(dir); 246 245 if (status == 0) 247 - status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); 246 + status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL); 248 247 nfs_free_createdata(data); 249 248 out: 250 249 dprintk("NFS reply create: %d\n", status); ··· 291 290 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 292 291 } 293 292 if (status == 0) 294 - status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); 293 + status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL); 295 294 nfs_free_createdata(data); 296 295 out: 297 296 dprintk("NFS reply mknod: %d\n", status); ··· 443 442 * should fill in the data with a LOOKUP call on the wire. 444 443 */ 445 444 if (status == 0) 446 - status = nfs_instantiate(dentry, fh, fattr); 445 + status = nfs_instantiate(dentry, fh, fattr, NULL); 447 446 448 447 out_free: 449 448 nfs_free_fattr(fattr); ··· 472 471 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 473 472 nfs_mark_for_revalidate(dir); 474 473 if (status == 0) 475 - status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); 474 + status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL); 476 475 nfs_free_createdata(data); 477 476 out: 478 477 dprintk("NFS reply mkdir: %d\n", status);
+22 -2
fs/nfs/super.c
··· 269 269 270 270 enum { 271 271 Opt_vers_2, Opt_vers_3, Opt_vers_4, Opt_vers_4_0, 272 - Opt_vers_4_1, 272 + Opt_vers_4_1, Opt_vers_4_2, 273 273 274 274 Opt_vers_err 275 275 }; ··· 280 280 { Opt_vers_4, "4" }, 281 281 { Opt_vers_4_0, "4.0" }, 282 282 { Opt_vers_4_1, "4.1" }, 283 + { Opt_vers_4_2, "4.2" }, 283 284 284 285 { Opt_vers_err, NULL } 285 286 }; ··· 833 832 seq_printf(m, "\n\tnfsv4:\t"); 834 833 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]); 835 834 seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]); 835 + seq_printf(m, ",bm2=0x%x", nfss->attr_bitmask[2]); 836 836 seq_printf(m, ",acl=0x%x", nfss->acl_bitmask); 837 837 show_sessions(m, nfss); 838 838 show_pnfs(m, nfss); ··· 1098 1096 case Opt_vers_4_1: 1099 1097 mnt->version = 4; 1100 1098 mnt->minorversion = 1; 1099 + break; 1100 + case Opt_vers_4_2: 1101 + mnt->version = 4; 1102 + mnt->minorversion = 2; 1101 1103 break; 1102 1104 default: 1103 1105 return 0; ··· 2429 2423 int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot, 2430 2424 struct nfs_mount_info *mount_info) 2431 2425 { 2432 - return security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts); 2426 + int error; 2427 + unsigned long kflags = 0, kflags_out = 0; 2428 + if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL) 2429 + kflags |= SECURITY_LSM_NATIVE_LABELS; 2430 + 2431 + error = security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts, 2432 + kflags, &kflags_out); 2433 + if (error) 2434 + goto err; 2435 + 2436 + if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL && 2437 + !(kflags_out & SECURITY_LSM_NATIVE_LABELS)) 2438 + NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL; 2439 + err: 2440 + return error; 2433 2441 } 2434 2442 EXPORT_SYMBOL_GPL(nfs_set_sb_security); 2435 2443
+6
fs/nfsd/nfsd.h
··· 243 243 #define nfserr_reject_deleg cpu_to_be32(NFS4ERR_REJECT_DELEG) 244 244 #define nfserr_returnconflict cpu_to_be32(NFS4ERR_RETURNCONFLICT) 245 245 #define nfserr_deleg_revoked cpu_to_be32(NFS4ERR_DELEG_REVOKED) 246 + #define nfserr_partner_notsupp cpu_to_be32(NFS4ERR_PARTNER_NOTSUPP) 247 + #define nfserr_partner_no_auth cpu_to_be32(NFS4ERR_PARTNER_NO_AUTH) 248 + #define nfserr_metadata_notsupp cpu_to_be32(NFS4ERR_METADATA_NOTSUPP) 249 + #define nfserr_offload_denied cpu_to_be32(NFS4ERR_OFFLOAD_DENIED) 250 + #define nfserr_wrong_lfs cpu_to_be32(NFS4ERR_WRONG_LFS) 251 + #define nfserr_badlabel cpu_to_be32(NFS4ERR_BADLABEL) 246 252 247 253 /* error codes for internal use */ 248 254 /* if a request fails due to kmalloc failure, it gets dropped.
+22
include/linux/nfs4.h
··· 32 32 struct nfs4_ace aces[0]; 33 33 }; 34 34 35 + #define NFS4_MAXLABELLEN 2048 36 + 37 + struct nfs4_label { 38 + uint32_t lfs; 39 + uint32_t pi; 40 + u32 len; 41 + char *label; 42 + }; 43 + 35 44 typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier; 36 45 37 46 struct nfs_stateid4 { ··· 228 219 NFS4ERR_REJECT_DELEG = 10085, /* on callback */ 229 220 NFS4ERR_RETURNCONFLICT = 10086, /* outstanding layoutreturn */ 230 221 NFS4ERR_DELEG_REVOKED = 10087, /* deleg./layout revoked */ 222 + 223 + /* nfs42 */ 224 + NFS4ERR_PARTNER_NOTSUPP = 10088, 225 + NFS4ERR_PARTNER_NO_AUTH = 10089, 226 + NFS4ERR_METADATA_NOTSUPP = 10090, 227 + NFS4ERR_OFFLOAD_DENIED = 10091, 228 + NFS4ERR_WRONG_LFS = 10092, 229 + NFS4ERR_BADLABEL = 10093, 231 230 }; 232 231 233 232 static inline bool seqid_mutating_err(u32 err) ··· 395 378 #define FATTR4_WORD1_FS_LAYOUT_TYPES (1UL << 30) 396 379 #define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) 397 380 #define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4) 381 + #define FATTR4_WORD2_SECURITY_LABEL (1UL << 17) 398 382 399 383 /* MDS threshold bitmap bits */ 400 384 #define THRESHOLD_RD (1UL << 0) ··· 408 390 #define NFS4_VERSION 4 409 391 #define NFS4_MINOR_VERSION 0 410 392 393 + #if defined(CONFIG_NFS_V4_2) 394 + #define NFS4_MAX_MINOR_VERSION 2 395 + #else 411 396 #if defined(CONFIG_NFS_V4_1) 412 397 #define NFS4_MAX_MINOR_VERSION 1 413 398 #else 414 399 #define NFS4_MAX_MINOR_VERSION 0 415 400 #endif /* CONFIG_NFS_V4_1 */ 401 + #endif /* CONFIG_NFS_V4_2 */ 416 402 417 403 #define NFS4_DEBUG 1 418 404
+24 -2
include/linux/nfs_fs.h
··· 207 207 #define NFS_INO_INVALID_ACL 0x0010 /* cached acls are invalid */ 208 208 #define NFS_INO_REVAL_PAGECACHE 0x0020 /* must revalidate pagecache */ 209 209 #define NFS_INO_REVAL_FORCED 0x0040 /* force revalidation ignoring a delegation */ 210 + #define NFS_INO_INVALID_LABEL 0x0080 /* cached label is invalid */ 210 211 211 212 /* 212 213 * Bit offsets in flags field ··· 337 336 extern void nfs_zap_caches(struct inode *); 338 337 extern void nfs_invalidate_atime(struct inode *); 339 338 extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *, 340 - struct nfs_fattr *); 339 + struct nfs_fattr *, struct nfs4_label *); 341 340 extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); 342 341 extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); 343 342 extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr); ··· 353 352 extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); 354 353 extern int nfs_setattr(struct dentry *, struct iattr *); 355 354 extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr); 355 + extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, 356 + struct nfs4_label *label); 356 357 extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx); 357 358 extern void put_nfs_open_context(struct nfs_open_context *ctx); 358 359 extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode); ··· 472 469 extern const struct dentry_operations nfs_dentry_operations; 473 470 474 471 extern void nfs_force_lookup_revalidate(struct inode *dir); 475 - extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr); 472 + extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, 473 + struct nfs_fattr *fattr, struct nfs4_label *label); 476 474 extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags); 477 475 extern void nfs_access_zap_cache(struct inode *inode); 478 476 ··· 500 496 extern const struct inode_operations nfs_referral_inode_operations; 501 497 extern int nfs_mountpoint_expiry_timeout; 502 498 extern void nfs_release_automount_timer(void); 499 + 500 + /* 501 + * linux/fs/nfs/nfs4proc.c 502 + */ 503 + #ifdef CONFIG_NFS_V4_SECURITY_LABEL 504 + extern struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags); 505 + static inline void nfs4_label_free(struct nfs4_label *label) 506 + { 507 + if (label) { 508 + kfree(label->label); 509 + kfree(label); 510 + } 511 + return; 512 + } 513 + #else 514 + static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; } 515 + static inline void nfs4_label_free(void *label) {} 516 + #endif 503 517 504 518 /* 505 519 * linux/fs/nfs/unlink.c
+7 -1
include/linux/nfs_fs_sb.h
··· 146 146 u32 attr_bitmask[3];/* V4 bitmask representing the set 147 147 of attributes supported on this 148 148 filesystem */ 149 - u32 cache_consistency_bitmask[2]; 149 + u32 attr_bitmask_nl[3]; 150 + /* V4 bitmask representing the 151 + set of attributes supported 152 + on this filesystem excluding 153 + the label support bit. */ 154 + u32 cache_consistency_bitmask[3]; 150 155 /* V4 bitmask representing the subset 151 156 of change attribute, size, ctime 152 157 and mtime attributes supported by ··· 205 200 #define NFS_CAP_UIDGID_NOMAP (1U << 15) 206 201 #define NFS_CAP_STATEID_NFSV41 (1U << 16) 207 202 #define NFS_CAP_ATOMIC_OPEN_V1 (1U << 17) 203 + #define NFS_CAP_SECURITY_LABEL (1U << 18) 208 204 209 205 #endif
+16 -3
include/linux/nfs_xdr.h
··· 101 101 #define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 22) 102 102 #define NFS_ATTR_FATTR_OWNER_NAME (1U << 23) 103 103 #define NFS_ATTR_FATTR_GROUP_NAME (1U << 24) 104 + #define NFS_ATTR_FATTR_V4_SECURITY_LABEL (1U << 25) 104 105 105 106 #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ 106 107 | NFS_ATTR_FATTR_MODE \ ··· 121 120 #define NFS_ATTR_FATTR_V3 (NFS_ATTR_FATTR \ 122 121 | NFS_ATTR_FATTR_SPACE_USED) 123 122 #define NFS_ATTR_FATTR_V4 (NFS_ATTR_FATTR \ 124 - | NFS_ATTR_FATTR_SPACE_USED) 123 + | NFS_ATTR_FATTR_SPACE_USED \ 124 + | NFS_ATTR_FATTR_V4_SECURITY_LABEL) 125 125 126 126 /* 127 127 * Info on the file system ··· 350 348 const u32 * open_bitmap; 351 349 __u32 claim; 352 350 enum createmode4 createmode; 351 + const struct nfs4_label *label; 353 352 }; 354 353 355 354 struct nfs_openres { ··· 360 357 struct nfs4_change_info cinfo; 361 358 __u32 rflags; 362 359 struct nfs_fattr * f_attr; 360 + struct nfs4_label *f_label; 363 361 struct nfs_seqid * seqid; 364 362 const struct nfs_server *server; 365 363 fmode_t delegation_type; ··· 603 599 int eof; 604 600 struct nfs_fh * fh; 605 601 struct nfs_fattr * fattr; 602 + struct nfs4_label *label; 606 603 unsigned char d_type; 607 604 struct nfs_server * server; 608 605 }; ··· 636 631 struct iattr * iap; 637 632 const struct nfs_server * server; /* Needed for name mapping */ 638 633 const u32 * bitmask; 634 + const struct nfs4_label *label; 639 635 }; 640 636 641 637 struct nfs_setaclargs { ··· 672 666 struct nfs_setattrres { 673 667 struct nfs4_sequence_res seq_res; 674 668 struct nfs_fattr * fattr; 669 + struct nfs4_label *label; 675 670 const struct nfs_server * server; 676 671 }; 677 672 ··· 870 863 const struct iattr * attrs; 871 864 const struct nfs_fh * dir_fh; 872 865 const u32 * bitmask; 866 + const struct nfs4_label *label; 873 867 }; 874 868 875 869 struct nfs4_create_res { ··· 878 870 const struct nfs_server * server; 879 871 struct nfs_fh * fh; 880 872 struct nfs_fattr * fattr; 873 + struct nfs4_label *label; 881 874 struct nfs4_change_info dir_cinfo; 882 875 }; 883 876 ··· 903 894 struct nfs4_sequence_res seq_res; 904 895 const struct nfs_server * server; 905 896 struct nfs_fattr * fattr; 897 + struct nfs4_label *label; 906 898 }; 907 899 908 900 struct nfs4_link_arg { ··· 918 908 struct nfs4_sequence_res seq_res; 919 909 const struct nfs_server * server; 920 910 struct nfs_fattr * fattr; 911 + struct nfs4_label *label; 921 912 struct nfs4_change_info cinfo; 922 913 struct nfs_fattr * dir_attr; 923 914 }; ··· 936 925 const struct nfs_server * server; 937 926 struct nfs_fattr * fattr; 938 927 struct nfs_fh * fh; 928 + struct nfs4_label *label; 939 929 }; 940 930 941 931 struct nfs4_lookup_root_arg { ··· 1379 1367 struct dentry *(*try_mount) (int, const char *, struct nfs_mount_info *, 1380 1368 struct nfs_subversion *); 1381 1369 int (*getattr) (struct nfs_server *, struct nfs_fh *, 1382 - struct nfs_fattr *); 1370 + struct nfs_fattr *, struct nfs4_label *); 1383 1371 int (*setattr) (struct dentry *, struct nfs_fattr *, 1384 1372 struct iattr *); 1385 1373 int (*lookup) (struct inode *, struct qstr *, 1386 - struct nfs_fh *, struct nfs_fattr *); 1374 + struct nfs_fh *, struct nfs_fattr *, 1375 + struct nfs4_label *); 1387 1376 int (*access) (struct inode *, struct nfs_access_entry *); 1388 1377 int (*readlink)(struct inode *, struct page *, unsigned int, 1389 1378 unsigned int);
+54 -3
include/linux/security.h
··· 26 26 #include <linux/capability.h> 27 27 #include <linux/slab.h> 28 28 #include <linux/err.h> 29 + #include <linux/string.h> 29 30 30 31 struct linux_binprm; 31 32 struct cred; ··· 60 59 /* If capable should audit the security request */ 61 60 #define SECURITY_CAP_NOAUDIT 0 62 61 #define SECURITY_CAP_AUDIT 1 62 + 63 + /* LSM Agnostic defines for sb_set_mnt_opts */ 64 + #define SECURITY_LSM_NATIVE_LABELS 1 63 65 64 66 struct ctl_table; 65 67 struct audit_krule; ··· 310 306 * Parse a string of security data filling in the opts structure 311 307 * @options string containing all mount options known by the LSM 312 308 * @opts binary data structure usable by the LSM 309 + * @dentry_init_security: 310 + * Compute a context for a dentry as the inode is not yet available 311 + * since NFSv4 has no label backed by an EA anyway. 312 + * @dentry dentry to use in calculating the context. 313 + * @mode mode used to determine resource type. 314 + * @name name of the last path component used to create file 315 + * @ctx pointer to place the pointer to the resulting context in. 316 + * @ctxlen point to place the length of the resulting context. 317 + * 313 318 * 314 319 * Security hooks for inode operations. 315 320 * ··· 1326 1313 * @pages contains the number of pages. 1327 1314 * Return 0 if permission is granted. 1328 1315 * 1316 + * @ismaclabel: 1317 + * Check if the extended attribute specified by @name 1318 + * represents a MAC label. Returns 1 if name is a MAC 1319 + * attribute otherwise returns 0. 1320 + * @name full extended attribute name to check against 1321 + * LSM as a MAC label. 1322 + * 1329 1323 * @secid_to_secctx: 1330 1324 * Convert secid to security context. If secdata is NULL the length of 1331 1325 * the result will be returned in seclen, but no secdata will be returned. ··· 1459 1439 int (*sb_pivotroot) (struct path *old_path, 1460 1440 struct path *new_path); 1461 1441 int (*sb_set_mnt_opts) (struct super_block *sb, 1462 - struct security_mnt_opts *opts); 1442 + struct security_mnt_opts *opts, 1443 + unsigned long kern_flags, 1444 + unsigned long *set_kern_flags); 1463 1445 int (*sb_clone_mnt_opts) (const struct super_block *oldsb, 1464 1446 struct super_block *newsb); 1465 1447 int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts); 1448 + int (*dentry_init_security) (struct dentry *dentry, int mode, 1449 + struct qstr *name, void **ctx, 1450 + u32 *ctxlen); 1451 + 1466 1452 1467 1453 #ifdef CONFIG_SECURITY_PATH 1468 1454 int (*path_unlink) (struct path *dir, struct dentry *dentry); ··· 1616 1590 1617 1591 int (*getprocattr) (struct task_struct *p, char *name, char **value); 1618 1592 int (*setprocattr) (struct task_struct *p, char *name, void *value, size_t size); 1593 + int (*ismaclabel) (const char *name); 1619 1594 int (*secid_to_secctx) (u32 secid, char **secdata, u32 *seclen); 1620 1595 int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid); 1621 1596 void (*release_secctx) (char *secdata, u32 seclen); ··· 1752 1725 const char *type, unsigned long flags, void *data); 1753 1726 int security_sb_umount(struct vfsmount *mnt, int flags); 1754 1727 int security_sb_pivotroot(struct path *old_path, struct path *new_path); 1755 - int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts); 1728 + int security_sb_set_mnt_opts(struct super_block *sb, 1729 + struct security_mnt_opts *opts, 1730 + unsigned long kern_flags, 1731 + unsigned long *set_kern_flags); 1756 1732 int security_sb_clone_mnt_opts(const struct super_block *oldsb, 1757 1733 struct super_block *newsb); 1758 1734 int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts); 1735 + int security_dentry_init_security(struct dentry *dentry, int mode, 1736 + struct qstr *name, void **ctx, 1737 + u32 *ctxlen); 1759 1738 1760 1739 int security_inode_alloc(struct inode *inode); 1761 1740 void security_inode_free(struct inode *inode); ··· 1873 1840 int security_getprocattr(struct task_struct *p, char *name, char **value); 1874 1841 int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size); 1875 1842 int security_netlink_send(struct sock *sk, struct sk_buff *skb); 1843 + int security_ismaclabel(const char *name); 1876 1844 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); 1877 1845 int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); 1878 1846 void security_release_secctx(char *secdata, u32 seclen); ··· 2045 2011 } 2046 2012 2047 2013 static inline int security_sb_set_mnt_opts(struct super_block *sb, 2048 - struct security_mnt_opts *opts) 2014 + struct security_mnt_opts *opts, 2015 + unsigned long kern_flags, 2016 + unsigned long *set_kern_flags) 2049 2017 { 2050 2018 return 0; 2051 2019 } ··· 2070 2034 2071 2035 static inline void security_inode_free(struct inode *inode) 2072 2036 { } 2037 + 2038 + static inline int security_dentry_init_security(struct dentry *dentry, 2039 + int mode, 2040 + struct qstr *name, 2041 + void **ctx, 2042 + u32 *ctxlen) 2043 + { 2044 + return -EOPNOTSUPP; 2045 + } 2046 + 2073 2047 2074 2048 static inline int security_inode_init_security(struct inode *inode, 2075 2049 struct inode *dir, ··· 2564 2518 static inline int security_netlink_send(struct sock *sk, struct sk_buff *skb) 2565 2519 { 2566 2520 return cap_netlink_send(sk, skb); 2521 + } 2522 + 2523 + static inline int security_ismaclabel(const char *name) 2524 + { 2525 + return 0; 2567 2526 } 2568 2527 2569 2528 static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+18 -1
security/capability.c
··· 91 91 } 92 92 93 93 static int cap_sb_set_mnt_opts(struct super_block *sb, 94 - struct security_mnt_opts *opts) 94 + struct security_mnt_opts *opts, 95 + unsigned long kern_flags, 96 + unsigned long *set_kern_flags) 97 + 95 98 { 96 99 if (unlikely(opts->num_mnt_opts)) 97 100 return -EOPNOTSUPP; ··· 108 105 } 109 106 110 107 static int cap_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) 108 + { 109 + return 0; 110 + } 111 + 112 + static int cap_dentry_init_security(struct dentry *dentry, int mode, 113 + struct qstr *name, void **ctx, 114 + u32 *ctxlen) 111 115 { 112 116 return 0; 113 117 } ··· 826 816 return -EINVAL; 827 817 } 828 818 819 + static int cap_ismaclabel(const char *name) 820 + { 821 + return 0; 822 + } 823 + 829 824 static int cap_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 830 825 { 831 826 return -EOPNOTSUPP; ··· 946 931 set_to_cap_if_null(ops, sb_set_mnt_opts); 947 932 set_to_cap_if_null(ops, sb_clone_mnt_opts); 948 933 set_to_cap_if_null(ops, sb_parse_opts_str); 934 + set_to_cap_if_null(ops, dentry_init_security); 949 935 set_to_cap_if_null(ops, inode_alloc_security); 950 936 set_to_cap_if_null(ops, inode_free_security); 951 937 set_to_cap_if_null(ops, inode_init_security); ··· 1050 1034 set_to_cap_if_null(ops, d_instantiate); 1051 1035 set_to_cap_if_null(ops, getprocattr); 1052 1036 set_to_cap_if_null(ops, setprocattr); 1037 + set_to_cap_if_null(ops, ismaclabel); 1053 1038 set_to_cap_if_null(ops, secid_to_secctx); 1054 1039 set_to_cap_if_null(ops, secctx_to_secid); 1055 1040 set_to_cap_if_null(ops, release_secctx);
+22 -2
security/security.c
··· 12 12 */ 13 13 14 14 #include <linux/capability.h> 15 + #include <linux/dcache.h> 15 16 #include <linux/module.h> 16 17 #include <linux/init.h> 17 18 #include <linux/kernel.h> ··· 294 293 } 295 294 296 295 int security_sb_set_mnt_opts(struct super_block *sb, 297 - struct security_mnt_opts *opts) 296 + struct security_mnt_opts *opts, 297 + unsigned long kern_flags, 298 + unsigned long *set_kern_flags) 298 299 { 299 - return security_ops->sb_set_mnt_opts(sb, opts); 300 + return security_ops->sb_set_mnt_opts(sb, opts, kern_flags, 301 + set_kern_flags); 300 302 } 301 303 EXPORT_SYMBOL(security_sb_set_mnt_opts); 302 304 ··· 327 323 integrity_inode_free(inode); 328 324 security_ops->inode_free_security(inode); 329 325 } 326 + 327 + int security_dentry_init_security(struct dentry *dentry, int mode, 328 + struct qstr *name, void **ctx, 329 + u32 *ctxlen) 330 + { 331 + return security_ops->dentry_init_security(dentry, mode, name, 332 + ctx, ctxlen); 333 + } 334 + EXPORT_SYMBOL(security_dentry_init_security); 330 335 331 336 int security_inode_init_security(struct inode *inode, struct inode *dir, 332 337 const struct qstr *qstr, ··· 660 647 return 0; 661 648 return security_ops->inode_listsecurity(inode, buffer, buffer_size); 662 649 } 650 + EXPORT_SYMBOL(security_inode_listsecurity); 663 651 664 652 void security_inode_getsecid(const struct inode *inode, u32 *secid) 665 653 { ··· 1060 1046 { 1061 1047 return security_ops->netlink_send(sk, skb); 1062 1048 } 1049 + 1050 + int security_ismaclabel(const char *name) 1051 + { 1052 + return security_ops->ismaclabel(name); 1053 + } 1054 + EXPORT_SYMBOL(security_ismaclabel); 1063 1055 1064 1056 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 1065 1057 {
+81 -11
security/selinux/hooks.c
··· 81 81 #include <linux/syslog.h> 82 82 #include <linux/user_namespace.h> 83 83 #include <linux/export.h> 84 + #include <linux/security.h> 84 85 #include <linux/msg.h> 85 86 #include <linux/shm.h> 86 87 ··· 285 284 286 285 /* The file system's label must be initialized prior to use. */ 287 286 288 - static const char *labeling_behaviors[6] = { 287 + static const char *labeling_behaviors[7] = { 289 288 "uses xattr", 290 289 "uses transition SIDs", 291 290 "uses task SIDs", 292 291 "uses genfs_contexts", 293 292 "not configured for labeling", 294 293 "uses mountpoint labeling", 294 + "uses native labeling", 295 295 }; 296 296 297 297 static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry); ··· 554 552 * labeling information. 555 553 */ 556 554 static int selinux_set_mnt_opts(struct super_block *sb, 557 - struct security_mnt_opts *opts) 555 + struct security_mnt_opts *opts, 556 + unsigned long kern_flags, 557 + unsigned long *set_kern_flags) 558 558 { 559 559 const struct cred *cred = current_cred(); 560 560 int rc = 0, i; ··· 582 578 rc = -EINVAL; 583 579 printk(KERN_WARNING "SELinux: Unable to set superblock options " 584 580 "before the security server is initialized\n"); 581 + goto out; 582 + } 583 + if (kern_flags && !set_kern_flags) { 584 + /* Specifying internal flags without providing a place to 585 + * place the results is not allowed */ 586 + rc = -EINVAL; 585 587 goto out; 586 588 } 587 589 ··· 680 670 if (strcmp(sb->s_type->name, "proc") == 0) 681 671 sbsec->flags |= SE_SBPROC; 682 672 683 - /* Determine the labeling behavior to use for this filesystem type. */ 684 - rc = security_fs_use((sbsec->flags & SE_SBPROC) ? "proc" : sb->s_type->name, &sbsec->behavior, &sbsec->sid); 685 - if (rc) { 686 - printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", 687 - __func__, sb->s_type->name, rc); 688 - goto out; 673 + if (!sbsec->behavior) { 674 + /* 675 + * Determine the labeling behavior to use for this 676 + * filesystem type. 677 + */ 678 + rc = security_fs_use((sbsec->flags & SE_SBPROC) ? 679 + "proc" : sb->s_type->name, 680 + &sbsec->behavior, &sbsec->sid); 681 + if (rc) { 682 + printk(KERN_WARNING 683 + "%s: security_fs_use(%s) returned %d\n", 684 + __func__, sb->s_type->name, rc); 685 + goto out; 686 + } 689 687 } 690 - 691 688 /* sets the context of the superblock for the fs being mounted. */ 692 689 if (fscontext_sid) { 693 690 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred); ··· 709 692 * sets the label used on all file below the mountpoint, and will set 710 693 * the superblock context if not already set. 711 694 */ 695 + if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) { 696 + sbsec->behavior = SECURITY_FS_USE_NATIVE; 697 + *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS; 698 + } 699 + 712 700 if (context_sid) { 713 701 if (!fscontext_sid) { 714 702 rc = may_context_mount_sb_relabel(context_sid, sbsec, ··· 745 723 } 746 724 747 725 if (defcontext_sid) { 748 - if (sbsec->behavior != SECURITY_FS_USE_XATTR) { 726 + if (sbsec->behavior != SECURITY_FS_USE_XATTR && 727 + sbsec->behavior != SECURITY_FS_USE_NATIVE) { 749 728 rc = -EINVAL; 750 729 printk(KERN_WARNING "SELinux: defcontext option is " 751 730 "invalid for this filesystem type\n"); ··· 1003 980 goto out_err; 1004 981 1005 982 out: 1006 - rc = selinux_set_mnt_opts(sb, &opts); 983 + rc = selinux_set_mnt_opts(sb, &opts, 0, NULL); 1007 984 1008 985 out_err: 1009 986 security_free_mnt_opts(&opts); ··· 1245 1222 } 1246 1223 1247 1224 switch (sbsec->behavior) { 1225 + case SECURITY_FS_USE_NATIVE: 1226 + break; 1248 1227 case SECURITY_FS_USE_XATTR: 1249 1228 if (!inode->i_op->getxattr) { 1250 1229 isec->sid = sbsec->def_sid; ··· 2540 2515 inode_free_security(inode); 2541 2516 } 2542 2517 2518 + static int selinux_dentry_init_security(struct dentry *dentry, int mode, 2519 + struct qstr *name, void **ctx, 2520 + u32 *ctxlen) 2521 + { 2522 + const struct cred *cred = current_cred(); 2523 + struct task_security_struct *tsec; 2524 + struct inode_security_struct *dsec; 2525 + struct superblock_security_struct *sbsec; 2526 + struct inode *dir = dentry->d_parent->d_inode; 2527 + u32 newsid; 2528 + int rc; 2529 + 2530 + tsec = cred->security; 2531 + dsec = dir->i_security; 2532 + sbsec = dir->i_sb->s_security; 2533 + 2534 + if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) { 2535 + newsid = tsec->create_sid; 2536 + } else { 2537 + rc = security_transition_sid(tsec->sid, dsec->sid, 2538 + inode_mode_to_security_class(mode), 2539 + name, 2540 + &newsid); 2541 + if (rc) { 2542 + printk(KERN_WARNING 2543 + "%s: security_transition_sid failed, rc=%d\n", 2544 + __func__, -rc); 2545 + return rc; 2546 + } 2547 + } 2548 + 2549 + return security_sid_to_context(newsid, (char **)ctx, ctxlen); 2550 + } 2551 + 2543 2552 static int selinux_inode_init_security(struct inode *inode, struct inode *dir, 2544 2553 const struct qstr *qstr, char **name, 2545 2554 void **value, size_t *len) ··· 2908 2849 return; 2909 2850 } 2910 2851 2852 + isec->sclass = inode_mode_to_security_class(inode->i_mode); 2911 2853 isec->sid = newsid; 2854 + isec->initialized = 1; 2855 + 2912 2856 return; 2913 2857 } 2914 2858 ··· 2999 2937 if (rc) 3000 2938 return rc; 3001 2939 2940 + isec->sclass = inode_mode_to_security_class(inode->i_mode); 3002 2941 isec->sid = newsid; 3003 2942 isec->initialized = 1; 3004 2943 return 0; ··· 5483 5420 return error; 5484 5421 } 5485 5422 5423 + static int selinux_ismaclabel(const char *name) 5424 + { 5425 + return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0); 5426 + } 5427 + 5486 5428 static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 5487 5429 { 5488 5430 return security_sid_to_context(secid, secdata, seclen); ··· 5630 5562 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, 5631 5563 .sb_parse_opts_str = selinux_parse_opts_str, 5632 5564 5565 + .dentry_init_security = selinux_dentry_init_security, 5633 5566 5634 5567 .inode_alloc_security = selinux_inode_alloc_security, 5635 5568 .inode_free_security = selinux_inode_free_security, ··· 5726 5657 .getprocattr = selinux_getprocattr, 5727 5658 .setprocattr = selinux_setprocattr, 5728 5659 5660 + .ismaclabel = selinux_ismaclabel, 5729 5661 .secid_to_secctx = selinux_secid_to_secctx, 5730 5662 .secctx_to_secid = selinux_secctx_to_secid, 5731 5663 .release_secctx = selinux_release_secctx,
+2
security/selinux/include/security.h
··· 169 169 #define SECURITY_FS_USE_GENFS 4 /* use the genfs support */ 170 170 #define SECURITY_FS_USE_NONE 5 /* no labeling support */ 171 171 #define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */ 172 + #define SECURITY_FS_USE_NATIVE 7 /* use native label support */ 173 + #define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */ 172 174 173 175 int security_fs_use(const char *fstype, unsigned int *behavior, 174 176 u32 *sid);
+4 -1
security/selinux/ss/policydb.c
··· 2168 2168 2169 2169 rc = -EINVAL; 2170 2170 c->v.behavior = le32_to_cpu(buf[0]); 2171 - if (c->v.behavior > SECURITY_FS_USE_NONE) 2171 + /* Determined at runtime, not in policy DB. */ 2172 + if (c->v.behavior == SECURITY_FS_USE_MNTPOINT) 2173 + goto out; 2174 + if (c->v.behavior > SECURITY_FS_USE_MAX) 2172 2175 goto out; 2173 2176 2174 2177 rc = -ENOMEM;
+11
security/smack/smack_lsm.c
··· 3329 3329 #endif /* CONFIG_AUDIT */ 3330 3330 3331 3331 /** 3332 + * smack_ismaclabel - check if xattr @name references a smack MAC label 3333 + * @name: Full xattr name to check. 3334 + */ 3335 + static int smack_ismaclabel(const char *name) 3336 + { 3337 + return (strcmp(name, XATTR_SMACK_SUFFIX) == 0); 3338 + } 3339 + 3340 + 3341 + /** 3332 3342 * smack_secid_to_secctx - return the smack label for a secid 3333 3343 * @secid: incoming integer 3334 3344 * @secdata: destination ··· 3534 3524 .audit_rule_free = smack_audit_rule_free, 3535 3525 #endif /* CONFIG_AUDIT */ 3536 3526 3527 + .ismaclabel = smack_ismaclabel, 3537 3528 .secid_to_secctx = smack_secid_to_secctx, 3538 3529 .secctx_to_secid = smack_secctx_to_secid, 3539 3530 .release_secctx = smack_release_secctx,