Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/fs.h>
0003 #include <linux/gfp.h>
0004 #include <linux/nfs.h>
0005 #include <linux/nfs3.h>
0006 #include <linux/nfs_fs.h>
0007 #include <linux/posix_acl_xattr.h>
0008 #include <linux/nfsacl.h>
0009 
0010 #include "internal.h"
0011 #include "nfs3_fs.h"
0012 
0013 #define NFSDBG_FACILITY NFSDBG_PROC
0014 
0015 /*
0016  * nfs3_prepare_get_acl, nfs3_complete_get_acl, nfs3_abort_get_acl: Helpers for
0017  * caching get_acl results in a race-free way.  See fs/posix_acl.c:get_acl()
0018  * for explanations.
0019  */
0020 static void nfs3_prepare_get_acl(struct posix_acl **p)
0021 {
0022     struct posix_acl *sentinel = uncached_acl_sentinel(current);
0023 
0024     if (cmpxchg(p, ACL_NOT_CACHED, sentinel) != ACL_NOT_CACHED) {
0025         /* Not the first reader or sentinel already in place. */
0026     }
0027 }
0028 
0029 static void nfs3_complete_get_acl(struct posix_acl **p, struct posix_acl *acl)
0030 {
0031     struct posix_acl *sentinel = uncached_acl_sentinel(current);
0032 
0033     /* Only cache the ACL if our sentinel is still in place. */
0034     posix_acl_dup(acl);
0035     if (cmpxchg(p, sentinel, acl) != sentinel)
0036         posix_acl_release(acl);
0037 }
0038 
0039 static void nfs3_abort_get_acl(struct posix_acl **p)
0040 {
0041     struct posix_acl *sentinel = uncached_acl_sentinel(current);
0042 
0043     /* Remove our sentinel upon failure. */
0044     cmpxchg(p, sentinel, ACL_NOT_CACHED);
0045 }
0046 
0047 struct posix_acl *nfs3_get_acl(struct inode *inode, int type, bool rcu)
0048 {
0049     struct nfs_server *server = NFS_SERVER(inode);
0050     struct page *pages[NFSACL_MAXPAGES] = { };
0051     struct nfs3_getaclargs args = {
0052         .fh = NFS_FH(inode),
0053         /* The xdr layer may allocate pages here. */
0054         .pages = pages,
0055     };
0056     struct nfs3_getaclres res = {
0057         NULL,
0058     };
0059     struct rpc_message msg = {
0060         .rpc_argp   = &args,
0061         .rpc_resp   = &res,
0062     };
0063     int status, count;
0064 
0065     if (rcu)
0066         return ERR_PTR(-ECHILD);
0067 
0068     if (!nfs_server_capable(inode, NFS_CAP_ACLS))
0069         return ERR_PTR(-EOPNOTSUPP);
0070 
0071     status = nfs_revalidate_inode(inode, NFS_INO_INVALID_CHANGE);
0072     if (status < 0)
0073         return ERR_PTR(status);
0074 
0075     /*
0076      * Only get the access acl when explicitly requested: We don't
0077      * need it for access decisions, and only some applications use
0078      * it. Applications which request the access acl first are not
0079      * penalized from this optimization.
0080      */
0081     if (type == ACL_TYPE_ACCESS)
0082         args.mask |= NFS_ACLCNT|NFS_ACL;
0083     if (S_ISDIR(inode->i_mode))
0084         args.mask |= NFS_DFACLCNT|NFS_DFACL;
0085     if (args.mask == 0)
0086         return NULL;
0087 
0088     dprintk("NFS call getacl\n");
0089     msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_GETACL];
0090     res.fattr = nfs_alloc_fattr();
0091     if (res.fattr == NULL)
0092         return ERR_PTR(-ENOMEM);
0093 
0094     if (args.mask & NFS_ACL)
0095         nfs3_prepare_get_acl(&inode->i_acl);
0096     if (args.mask & NFS_DFACL)
0097         nfs3_prepare_get_acl(&inode->i_default_acl);
0098 
0099     status = rpc_call_sync(server->client_acl, &msg, 0);
0100     dprintk("NFS reply getacl: %d\n", status);
0101 
0102     /* pages may have been allocated at the xdr layer. */
0103     for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++)
0104         __free_page(args.pages[count]);
0105 
0106     switch (status) {
0107         case 0:
0108             status = nfs_refresh_inode(inode, res.fattr);
0109             break;
0110         case -EPFNOSUPPORT:
0111         case -EPROTONOSUPPORT:
0112             dprintk("NFS_V3_ACL extension not supported; disabling\n");
0113             server->caps &= ~NFS_CAP_ACLS;
0114             fallthrough;
0115         case -ENOTSUPP:
0116             status = -EOPNOTSUPP;
0117             goto getout;
0118         default:
0119             goto getout;
0120     }
0121     if ((args.mask & res.mask) != args.mask) {
0122         status = -EIO;
0123         goto getout;
0124     }
0125 
0126     if (res.acl_access != NULL) {
0127         if ((posix_acl_equiv_mode(res.acl_access, NULL) == 0) ||
0128             res.acl_access->a_count == 0) {
0129             posix_acl_release(res.acl_access);
0130             res.acl_access = NULL;
0131         }
0132     }
0133 
0134     if (res.mask & NFS_ACL)
0135         nfs3_complete_get_acl(&inode->i_acl, res.acl_access);
0136     else
0137         forget_cached_acl(inode, ACL_TYPE_ACCESS);
0138 
0139     if (res.mask & NFS_DFACL)
0140         nfs3_complete_get_acl(&inode->i_default_acl, res.acl_default);
0141     else
0142         forget_cached_acl(inode, ACL_TYPE_DEFAULT);
0143 
0144     nfs_free_fattr(res.fattr);
0145     if (type == ACL_TYPE_ACCESS) {
0146         posix_acl_release(res.acl_default);
0147         return res.acl_access;
0148     } else {
0149         posix_acl_release(res.acl_access);
0150         return res.acl_default;
0151     }
0152 
0153 getout:
0154     nfs3_abort_get_acl(&inode->i_acl);
0155     nfs3_abort_get_acl(&inode->i_default_acl);
0156     posix_acl_release(res.acl_access);
0157     posix_acl_release(res.acl_default);
0158     nfs_free_fattr(res.fattr);
0159     return ERR_PTR(status);
0160 }
0161 
0162 static int __nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
0163         struct posix_acl *dfacl)
0164 {
0165     struct nfs_server *server = NFS_SERVER(inode);
0166     struct nfs_fattr *fattr;
0167     struct page *pages[NFSACL_MAXPAGES];
0168     struct nfs3_setaclargs args = {
0169         .inode = inode,
0170         .mask = NFS_ACL,
0171         .acl_access = acl,
0172         .pages = pages,
0173     };
0174     struct rpc_message msg = {
0175         .rpc_argp   = &args,
0176         .rpc_resp   = &fattr,
0177     };
0178     int status = 0;
0179 
0180     if (acl == NULL && (!S_ISDIR(inode->i_mode) || dfacl == NULL))
0181         goto out;
0182 
0183     status = -EOPNOTSUPP;
0184     if (!nfs_server_capable(inode, NFS_CAP_ACLS))
0185         goto out;
0186 
0187     /* We are doing this here because XDR marshalling does not
0188      * return any results, it BUGs. */
0189     status = -ENOSPC;
0190     if (acl != NULL && acl->a_count > NFS_ACL_MAX_ENTRIES)
0191         goto out;
0192     if (dfacl != NULL && dfacl->a_count > NFS_ACL_MAX_ENTRIES)
0193         goto out;
0194     if (S_ISDIR(inode->i_mode)) {
0195         args.mask |= NFS_DFACL;
0196         args.acl_default = dfacl;
0197         args.len = nfsacl_size(acl, dfacl);
0198     } else
0199         args.len = nfsacl_size(acl, NULL);
0200 
0201     if (args.len > NFS_ACL_INLINE_BUFSIZE) {
0202         unsigned int npages = 1 + ((args.len - 1) >> PAGE_SHIFT);
0203 
0204         status = -ENOMEM;
0205         do {
0206             args.pages[args.npages] = alloc_page(GFP_KERNEL);
0207             if (args.pages[args.npages] == NULL)
0208                 goto out_freepages;
0209             args.npages++;
0210         } while (args.npages < npages);
0211     }
0212 
0213     dprintk("NFS call setacl\n");
0214     status = -ENOMEM;
0215     fattr = nfs_alloc_fattr();
0216     if (fattr == NULL)
0217         goto out_freepages;
0218 
0219     msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL];
0220     msg.rpc_resp = fattr;
0221     status = rpc_call_sync(server->client_acl, &msg, 0);
0222     nfs_access_zap_cache(inode);
0223     nfs_zap_acl_cache(inode);
0224     dprintk("NFS reply setacl: %d\n", status);
0225 
0226     switch (status) {
0227         case 0:
0228             status = nfs_refresh_inode(inode, fattr);
0229             break;
0230         case -EPFNOSUPPORT:
0231         case -EPROTONOSUPPORT:
0232             dprintk("NFS_V3_ACL SETACL RPC not supported"
0233                     "(will not retry)\n");
0234             server->caps &= ~NFS_CAP_ACLS;
0235             fallthrough;
0236         case -ENOTSUPP:
0237             status = -EOPNOTSUPP;
0238     }
0239     nfs_free_fattr(fattr);
0240 out_freepages:
0241     while (args.npages != 0) {
0242         args.npages--;
0243         __free_page(args.pages[args.npages]);
0244     }
0245 out:
0246     return status;
0247 }
0248 
0249 int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
0250         struct posix_acl *dfacl)
0251 {
0252     int ret;
0253     ret = __nfs3_proc_setacls(inode, acl, dfacl);
0254     return (ret == -EOPNOTSUPP) ? 0 : ret;
0255 
0256 }
0257 
0258 int nfs3_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
0259          struct posix_acl *acl, int type)
0260 {
0261     struct posix_acl *orig = acl, *dfacl = NULL, *alloc;
0262     int status;
0263 
0264     if (S_ISDIR(inode->i_mode)) {
0265         switch(type) {
0266         case ACL_TYPE_ACCESS:
0267             alloc = get_acl(inode, ACL_TYPE_DEFAULT);
0268             if (IS_ERR(alloc))
0269                 goto fail;
0270             dfacl = alloc;
0271             break;
0272 
0273         case ACL_TYPE_DEFAULT:
0274             alloc = get_acl(inode, ACL_TYPE_ACCESS);
0275             if (IS_ERR(alloc))
0276                 goto fail;
0277             dfacl = acl;
0278             acl = alloc;
0279             break;
0280         }
0281     }
0282 
0283     if (acl == NULL) {
0284         alloc = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
0285         if (IS_ERR(alloc))
0286             goto fail;
0287         acl = alloc;
0288     }
0289     status = __nfs3_proc_setacls(inode, acl, dfacl);
0290 out:
0291     if (acl != orig)
0292         posix_acl_release(acl);
0293     if (dfacl != orig)
0294         posix_acl_release(dfacl);
0295     return status;
0296 
0297 fail:
0298     status = PTR_ERR(alloc);
0299     goto out;
0300 }
0301 
0302 const struct xattr_handler *nfs3_xattr_handlers[] = {
0303     &posix_acl_access_xattr_handler,
0304     &posix_acl_default_xattr_handler,
0305     NULL,
0306 };
0307 
0308 static int
0309 nfs3_list_one_acl(struct inode *inode, int type, const char *name, void *data,
0310         size_t size, ssize_t *result)
0311 {
0312     struct posix_acl *acl;
0313     char *p = data + *result;
0314 
0315     acl = get_acl(inode, type);
0316     if (IS_ERR_OR_NULL(acl))
0317         return 0;
0318 
0319     posix_acl_release(acl);
0320 
0321     *result += strlen(name);
0322     *result += 1;
0323     if (!size)
0324         return 0;
0325     if (*result > size)
0326         return -ERANGE;
0327 
0328     strcpy(p, name);
0329     return 0;
0330 }
0331 
0332 ssize_t
0333 nfs3_listxattr(struct dentry *dentry, char *data, size_t size)
0334 {
0335     struct inode *inode = d_inode(dentry);
0336     ssize_t result = 0;
0337     int error;
0338 
0339     error = nfs3_list_one_acl(inode, ACL_TYPE_ACCESS,
0340             XATTR_NAME_POSIX_ACL_ACCESS, data, size, &result);
0341     if (error)
0342         return error;
0343 
0344     error = nfs3_list_one_acl(inode, ACL_TYPE_DEFAULT,
0345             XATTR_NAME_POSIX_ACL_DEFAULT, data, size, &result);
0346     if (error)
0347         return error;
0348     return result;
0349 }