0001
0002
0003
0004
0005
0006
0007
0008 #include "vfs.h"
0009 #include "xdr.h"
0010 #include "auth.h"
0011
0012
0013
0014
0015 static const u32 nfs_ftypes[] = {
0016 NFNON, NFCHR, NFCHR, NFBAD,
0017 NFDIR, NFBAD, NFBLK, NFBAD,
0018 NFREG, NFBAD, NFLNK, NFBAD,
0019 NFSOCK, NFBAD, NFLNK, NFBAD,
0020 };
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 bool
0037 svcxdr_encode_stat(struct xdr_stream *xdr, __be32 status)
0038 {
0039 __be32 *p;
0040
0041 p = xdr_reserve_space(xdr, sizeof(status));
0042 if (!p)
0043 return false;
0044 *p = status;
0045
0046 return true;
0047 }
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 bool
0059 svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp)
0060 {
0061 __be32 *p;
0062
0063 p = xdr_inline_decode(xdr, NFS_FHSIZE);
0064 if (!p)
0065 return false;
0066 fh_init(fhp, NFS_FHSIZE);
0067 memcpy(&fhp->fh_handle.fh_raw, p, NFS_FHSIZE);
0068 fhp->fh_handle.fh_size = NFS_FHSIZE;
0069
0070 return true;
0071 }
0072
0073 static bool
0074 svcxdr_encode_fhandle(struct xdr_stream *xdr, const struct svc_fh *fhp)
0075 {
0076 __be32 *p;
0077
0078 p = xdr_reserve_space(xdr, NFS_FHSIZE);
0079 if (!p)
0080 return false;
0081 memcpy(p, &fhp->fh_handle.fh_raw, NFS_FHSIZE);
0082
0083 return true;
0084 }
0085
0086 static __be32 *
0087 encode_timeval(__be32 *p, const struct timespec64 *time)
0088 {
0089 *p++ = cpu_to_be32((u32)time->tv_sec);
0090 if (time->tv_nsec)
0091 *p++ = cpu_to_be32(time->tv_nsec / NSEC_PER_USEC);
0092 else
0093 *p++ = xdr_zero;
0094 return p;
0095 }
0096
0097 static bool
0098 svcxdr_decode_filename(struct xdr_stream *xdr, char **name, unsigned int *len)
0099 {
0100 u32 size, i;
0101 __be32 *p;
0102 char *c;
0103
0104 if (xdr_stream_decode_u32(xdr, &size) < 0)
0105 return false;
0106 if (size == 0 || size > NFS_MAXNAMLEN)
0107 return false;
0108 p = xdr_inline_decode(xdr, size);
0109 if (!p)
0110 return false;
0111
0112 *len = size;
0113 *name = (char *)p;
0114 for (i = 0, c = *name; i < size; i++, c++)
0115 if (*c == '\0' || *c == '/')
0116 return false;
0117
0118 return true;
0119 }
0120
0121 static bool
0122 svcxdr_decode_diropargs(struct xdr_stream *xdr, struct svc_fh *fhp,
0123 char **name, unsigned int *len)
0124 {
0125 return svcxdr_decode_fhandle(xdr, fhp) &&
0126 svcxdr_decode_filename(xdr, name, len);
0127 }
0128
0129 static bool
0130 svcxdr_decode_sattr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
0131 struct iattr *iap)
0132 {
0133 u32 tmp1, tmp2;
0134 __be32 *p;
0135
0136 p = xdr_inline_decode(xdr, XDR_UNIT * 8);
0137 if (!p)
0138 return false;
0139
0140 iap->ia_valid = 0;
0141
0142
0143
0144
0145
0146 tmp1 = be32_to_cpup(p++);
0147 if (tmp1 != (u32)-1 && tmp1 != 0xffff) {
0148 iap->ia_valid |= ATTR_MODE;
0149 iap->ia_mode = tmp1;
0150 }
0151
0152 tmp1 = be32_to_cpup(p++);
0153 if (tmp1 != (u32)-1) {
0154 iap->ia_uid = make_kuid(nfsd_user_namespace(rqstp), tmp1);
0155 if (uid_valid(iap->ia_uid))
0156 iap->ia_valid |= ATTR_UID;
0157 }
0158
0159 tmp1 = be32_to_cpup(p++);
0160 if (tmp1 != (u32)-1) {
0161 iap->ia_gid = make_kgid(nfsd_user_namespace(rqstp), tmp1);
0162 if (gid_valid(iap->ia_gid))
0163 iap->ia_valid |= ATTR_GID;
0164 }
0165
0166 tmp1 = be32_to_cpup(p++);
0167 if (tmp1 != (u32)-1) {
0168 iap->ia_valid |= ATTR_SIZE;
0169 iap->ia_size = tmp1;
0170 }
0171
0172 tmp1 = be32_to_cpup(p++);
0173 tmp2 = be32_to_cpup(p++);
0174 if (tmp1 != (u32)-1 && tmp2 != (u32)-1) {
0175 iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
0176 iap->ia_atime.tv_sec = tmp1;
0177 iap->ia_atime.tv_nsec = tmp2 * NSEC_PER_USEC;
0178 }
0179
0180 tmp1 = be32_to_cpup(p++);
0181 tmp2 = be32_to_cpup(p++);
0182 if (tmp1 != (u32)-1 && tmp2 != (u32)-1) {
0183 iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
0184 iap->ia_mtime.tv_sec = tmp1;
0185 iap->ia_mtime.tv_nsec = tmp2 * NSEC_PER_USEC;
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 if (tmp2 == 1000000)
0196 iap->ia_valid &= ~(ATTR_ATIME_SET|ATTR_MTIME_SET);
0197 }
0198
0199 return true;
0200 }
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 bool
0214 svcxdr_encode_fattr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
0215 const struct svc_fh *fhp, const struct kstat *stat)
0216 {
0217 struct user_namespace *userns = nfsd_user_namespace(rqstp);
0218 struct dentry *dentry = fhp->fh_dentry;
0219 int type = stat->mode & S_IFMT;
0220 struct timespec64 time;
0221 __be32 *p;
0222 u32 fsid;
0223
0224 p = xdr_reserve_space(xdr, XDR_UNIT * 17);
0225 if (!p)
0226 return false;
0227
0228 *p++ = cpu_to_be32(nfs_ftypes[type >> 12]);
0229 *p++ = cpu_to_be32((u32)stat->mode);
0230 *p++ = cpu_to_be32((u32)stat->nlink);
0231 *p++ = cpu_to_be32((u32)from_kuid_munged(userns, stat->uid));
0232 *p++ = cpu_to_be32((u32)from_kgid_munged(userns, stat->gid));
0233
0234 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN)
0235 *p++ = cpu_to_be32(NFS_MAXPATHLEN);
0236 else
0237 *p++ = cpu_to_be32((u32) stat->size);
0238 *p++ = cpu_to_be32((u32) stat->blksize);
0239 if (S_ISCHR(type) || S_ISBLK(type))
0240 *p++ = cpu_to_be32(new_encode_dev(stat->rdev));
0241 else
0242 *p++ = cpu_to_be32(0xffffffff);
0243 *p++ = cpu_to_be32((u32)stat->blocks);
0244
0245 switch (fsid_source(fhp)) {
0246 case FSIDSOURCE_FSID:
0247 fsid = (u32)fhp->fh_export->ex_fsid;
0248 break;
0249 case FSIDSOURCE_UUID:
0250 fsid = ((u32 *)fhp->fh_export->ex_uuid)[0];
0251 fsid ^= ((u32 *)fhp->fh_export->ex_uuid)[1];
0252 fsid ^= ((u32 *)fhp->fh_export->ex_uuid)[2];
0253 fsid ^= ((u32 *)fhp->fh_export->ex_uuid)[3];
0254 break;
0255 default:
0256 fsid = new_encode_dev(stat->dev);
0257 break;
0258 }
0259 *p++ = cpu_to_be32(fsid);
0260
0261 *p++ = cpu_to_be32((u32)stat->ino);
0262 p = encode_timeval(p, &stat->atime);
0263 time = stat->mtime;
0264 lease_get_mtime(d_inode(dentry), &time);
0265 p = encode_timeval(p, &time);
0266 encode_timeval(p, &stat->ctime);
0267
0268 return true;
0269 }
0270
0271
0272
0273
0274
0275 bool
0276 nfssvc_decode_fhandleargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0277 {
0278 struct nfsd_fhandle *args = rqstp->rq_argp;
0279
0280 return svcxdr_decode_fhandle(xdr, &args->fh);
0281 }
0282
0283 bool
0284 nfssvc_decode_sattrargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0285 {
0286 struct nfsd_sattrargs *args = rqstp->rq_argp;
0287
0288 return svcxdr_decode_fhandle(xdr, &args->fh) &&
0289 svcxdr_decode_sattr(rqstp, xdr, &args->attrs);
0290 }
0291
0292 bool
0293 nfssvc_decode_diropargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0294 {
0295 struct nfsd_diropargs *args = rqstp->rq_argp;
0296
0297 return svcxdr_decode_diropargs(xdr, &args->fh, &args->name, &args->len);
0298 }
0299
0300 bool
0301 nfssvc_decode_readargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0302 {
0303 struct nfsd_readargs *args = rqstp->rq_argp;
0304 u32 totalcount;
0305
0306 if (!svcxdr_decode_fhandle(xdr, &args->fh))
0307 return false;
0308 if (xdr_stream_decode_u32(xdr, &args->offset) < 0)
0309 return false;
0310 if (xdr_stream_decode_u32(xdr, &args->count) < 0)
0311 return false;
0312
0313 if (xdr_stream_decode_u32(xdr, &totalcount) < 0)
0314 return false;
0315
0316 return true;
0317 }
0318
0319 bool
0320 nfssvc_decode_writeargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0321 {
0322 struct nfsd_writeargs *args = rqstp->rq_argp;
0323 u32 beginoffset, totalcount;
0324
0325 if (!svcxdr_decode_fhandle(xdr, &args->fh))
0326 return false;
0327
0328 if (xdr_stream_decode_u32(xdr, &beginoffset) < 0)
0329 return false;
0330 if (xdr_stream_decode_u32(xdr, &args->offset) < 0)
0331 return false;
0332
0333 if (xdr_stream_decode_u32(xdr, &totalcount) < 0)
0334 return false;
0335
0336
0337 if (xdr_stream_decode_u32(xdr, &args->len) < 0)
0338 return false;
0339 if (args->len > NFSSVC_MAXBLKSIZE_V2)
0340 return false;
0341 if (!xdr_stream_subsegment(xdr, &args->payload, args->len))
0342 return false;
0343
0344 return true;
0345 }
0346
0347 bool
0348 nfssvc_decode_createargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0349 {
0350 struct nfsd_createargs *args = rqstp->rq_argp;
0351
0352 return svcxdr_decode_diropargs(xdr, &args->fh,
0353 &args->name, &args->len) &&
0354 svcxdr_decode_sattr(rqstp, xdr, &args->attrs);
0355 }
0356
0357 bool
0358 nfssvc_decode_renameargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0359 {
0360 struct nfsd_renameargs *args = rqstp->rq_argp;
0361
0362 return svcxdr_decode_diropargs(xdr, &args->ffh,
0363 &args->fname, &args->flen) &&
0364 svcxdr_decode_diropargs(xdr, &args->tfh,
0365 &args->tname, &args->tlen);
0366 }
0367
0368 bool
0369 nfssvc_decode_linkargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0370 {
0371 struct nfsd_linkargs *args = rqstp->rq_argp;
0372
0373 return svcxdr_decode_fhandle(xdr, &args->ffh) &&
0374 svcxdr_decode_diropargs(xdr, &args->tfh,
0375 &args->tname, &args->tlen);
0376 }
0377
0378 bool
0379 nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0380 {
0381 struct nfsd_symlinkargs *args = rqstp->rq_argp;
0382 struct kvec *head = rqstp->rq_arg.head;
0383
0384 if (!svcxdr_decode_diropargs(xdr, &args->ffh, &args->fname, &args->flen))
0385 return false;
0386 if (xdr_stream_decode_u32(xdr, &args->tlen) < 0)
0387 return false;
0388 if (args->tlen == 0)
0389 return false;
0390
0391 args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
0392 args->first.iov_base = xdr_inline_decode(xdr, args->tlen);
0393 if (!args->first.iov_base)
0394 return false;
0395 return svcxdr_decode_sattr(rqstp, xdr, &args->attrs);
0396 }
0397
0398 bool
0399 nfssvc_decode_readdirargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0400 {
0401 struct nfsd_readdirargs *args = rqstp->rq_argp;
0402
0403 if (!svcxdr_decode_fhandle(xdr, &args->fh))
0404 return false;
0405 if (xdr_stream_decode_u32(xdr, &args->cookie) < 0)
0406 return false;
0407 if (xdr_stream_decode_u32(xdr, &args->count) < 0)
0408 return false;
0409
0410 return true;
0411 }
0412
0413
0414
0415
0416
0417 bool
0418 nfssvc_encode_statres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0419 {
0420 struct nfsd_stat *resp = rqstp->rq_resp;
0421
0422 return svcxdr_encode_stat(xdr, resp->status);
0423 }
0424
0425 bool
0426 nfssvc_encode_attrstatres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0427 {
0428 struct nfsd_attrstat *resp = rqstp->rq_resp;
0429
0430 if (!svcxdr_encode_stat(xdr, resp->status))
0431 return false;
0432 switch (resp->status) {
0433 case nfs_ok:
0434 if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat))
0435 return false;
0436 break;
0437 }
0438
0439 return true;
0440 }
0441
0442 bool
0443 nfssvc_encode_diropres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0444 {
0445 struct nfsd_diropres *resp = rqstp->rq_resp;
0446
0447 if (!svcxdr_encode_stat(xdr, resp->status))
0448 return false;
0449 switch (resp->status) {
0450 case nfs_ok:
0451 if (!svcxdr_encode_fhandle(xdr, &resp->fh))
0452 return false;
0453 if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat))
0454 return false;
0455 break;
0456 }
0457
0458 return true;
0459 }
0460
0461 bool
0462 nfssvc_encode_readlinkres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0463 {
0464 struct nfsd_readlinkres *resp = rqstp->rq_resp;
0465 struct kvec *head = rqstp->rq_res.head;
0466
0467 if (!svcxdr_encode_stat(xdr, resp->status))
0468 return false;
0469 switch (resp->status) {
0470 case nfs_ok:
0471 if (xdr_stream_encode_u32(xdr, resp->len) < 0)
0472 return false;
0473 xdr_write_pages(xdr, &resp->page, 0, resp->len);
0474 if (svc_encode_result_payload(rqstp, head->iov_len, resp->len) < 0)
0475 return false;
0476 break;
0477 }
0478
0479 return true;
0480 }
0481
0482 bool
0483 nfssvc_encode_readres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0484 {
0485 struct nfsd_readres *resp = rqstp->rq_resp;
0486 struct kvec *head = rqstp->rq_res.head;
0487
0488 if (!svcxdr_encode_stat(xdr, resp->status))
0489 return false;
0490 switch (resp->status) {
0491 case nfs_ok:
0492 if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat))
0493 return false;
0494 if (xdr_stream_encode_u32(xdr, resp->count) < 0)
0495 return false;
0496 xdr_write_pages(xdr, resp->pages, rqstp->rq_res.page_base,
0497 resp->count);
0498 if (svc_encode_result_payload(rqstp, head->iov_len, resp->count) < 0)
0499 return false;
0500 break;
0501 }
0502
0503 return true;
0504 }
0505
0506 bool
0507 nfssvc_encode_readdirres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0508 {
0509 struct nfsd_readdirres *resp = rqstp->rq_resp;
0510 struct xdr_buf *dirlist = &resp->dirlist;
0511
0512 if (!svcxdr_encode_stat(xdr, resp->status))
0513 return false;
0514 switch (resp->status) {
0515 case nfs_ok:
0516 xdr_write_pages(xdr, dirlist->pages, 0, dirlist->len);
0517
0518 if (xdr_stream_encode_item_absent(xdr) < 0)
0519 return false;
0520 if (xdr_stream_encode_bool(xdr, resp->common.err == nfserr_eof) < 0)
0521 return false;
0522 break;
0523 }
0524
0525 return true;
0526 }
0527
0528 bool
0529 nfssvc_encode_statfsres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
0530 {
0531 struct nfsd_statfsres *resp = rqstp->rq_resp;
0532 struct kstatfs *stat = &resp->stats;
0533 __be32 *p;
0534
0535 if (!svcxdr_encode_stat(xdr, resp->status))
0536 return false;
0537 switch (resp->status) {
0538 case nfs_ok:
0539 p = xdr_reserve_space(xdr, XDR_UNIT * 5);
0540 if (!p)
0541 return false;
0542 *p++ = cpu_to_be32(NFSSVC_MAXBLKSIZE_V2);
0543 *p++ = cpu_to_be32(stat->f_bsize);
0544 *p++ = cpu_to_be32(stat->f_blocks);
0545 *p++ = cpu_to_be32(stat->f_bfree);
0546 *p = cpu_to_be32(stat->f_bavail);
0547 break;
0548 }
0549
0550 return true;
0551 }
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561 void nfssvc_encode_nfscookie(struct nfsd_readdirres *resp, u32 offset)
0562 {
0563 __be32 cookie = cpu_to_be32(offset);
0564
0565 if (!resp->cookie_offset)
0566 return;
0567
0568 write_bytes_to_xdr_buf(&resp->dirlist, resp->cookie_offset, &cookie,
0569 sizeof(cookie));
0570 resp->cookie_offset = 0;
0571 }
0572
0573 static bool
0574 svcxdr_encode_entry_common(struct nfsd_readdirres *resp, const char *name,
0575 int namlen, loff_t offset, u64 ino)
0576 {
0577 struct xdr_buf *dirlist = &resp->dirlist;
0578 struct xdr_stream *xdr = &resp->xdr;
0579
0580 if (xdr_stream_encode_item_present(xdr) < 0)
0581 return false;
0582
0583 if (xdr_stream_encode_u32(xdr, (u32)ino) < 0)
0584 return false;
0585
0586 if (xdr_stream_encode_opaque(xdr, name, min(namlen, NFS2_MAXNAMLEN)) < 0)
0587 return false;
0588
0589 resp->cookie_offset = dirlist->len;
0590 if (xdr_stream_encode_u32(xdr, ~0U) < 0)
0591 return false;
0592
0593 return true;
0594 }
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614 int nfssvc_encode_entry(void *data, const char *name, int namlen,
0615 loff_t offset, u64 ino, unsigned int d_type)
0616 {
0617 struct readdir_cd *ccd = data;
0618 struct nfsd_readdirres *resp = container_of(ccd,
0619 struct nfsd_readdirres,
0620 common);
0621 unsigned int starting_length = resp->dirlist.len;
0622
0623
0624 nfssvc_encode_nfscookie(resp, offset);
0625
0626 if (!svcxdr_encode_entry_common(resp, name, namlen, offset, ino))
0627 goto out_toosmall;
0628
0629 xdr_commit_encode(&resp->xdr);
0630 resp->common.err = nfs_ok;
0631 return 0;
0632
0633 out_toosmall:
0634 resp->cookie_offset = 0;
0635 resp->common.err = nfserr_toosmall;
0636 resp->dirlist.len = starting_length;
0637 return -EINVAL;
0638 }
0639
0640
0641
0642
0643 void nfssvc_release_attrstat(struct svc_rqst *rqstp)
0644 {
0645 struct nfsd_attrstat *resp = rqstp->rq_resp;
0646
0647 fh_put(&resp->fh);
0648 }
0649
0650 void nfssvc_release_diropres(struct svc_rqst *rqstp)
0651 {
0652 struct nfsd_diropres *resp = rqstp->rq_resp;
0653
0654 fh_put(&resp->fh);
0655 }
0656
0657 void nfssvc_release_readres(struct svc_rqst *rqstp)
0658 {
0659 struct nfsd_readres *resp = rqstp->rq_resp;
0660
0661 fh_put(&resp->fh);
0662 }