1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * XDR support for nfsd 4 * 5 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> 6 */ 7 8 #include "vfs.h" 9 #include "xdr.h" 10 #include "auth.h" 11 12 #define NFSDDBG_FACILITY NFSDDBG_XDR 13 14 /* 15 * Mapping of S_IF* types to NFS file types 16 */ 17 static u32 nfs_ftypes[] = { 18 NFNON, NFCHR, NFCHR, NFBAD, 19 NFDIR, NFBAD, NFBLK, NFBAD, 20 NFREG, NFBAD, NFLNK, NFBAD, 21 NFSOCK, NFBAD, NFLNK, NFBAD, 22 }; 23 24 25 /* 26 * Basic NFSv2 data types (RFC 1094 Section 2.3) 27 */ 28 29 /** 30 * svcxdr_decode_fhandle - Decode an NFSv2 file handle 31 * @xdr: XDR stream positioned at an encoded NFSv2 FH 32 * @fhp: OUT: filled-in server file handle 33 * 34 * Return values: 35 * %false: The encoded file handle was not valid 36 * %true: @fhp has been initialized 37 */ 38 bool 39 svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp) 40 { 41 __be32 *p; 42 43 p = xdr_inline_decode(xdr, NFS_FHSIZE); 44 if (!p) 45 return false; 46 fh_init(fhp, NFS_FHSIZE); 47 memcpy(&fhp->fh_handle.fh_base, p, NFS_FHSIZE); 48 fhp->fh_handle.fh_size = NFS_FHSIZE; 49 50 return true; 51 } 52 53 static __be32 * 54 encode_fh(__be32 *p, struct svc_fh *fhp) 55 { 56 memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE); 57 return p + (NFS_FHSIZE>> 2); 58 } 59 60 static bool 61 svcxdr_decode_filename(struct xdr_stream *xdr, char **name, unsigned int *len) 62 { 63 u32 size, i; 64 __be32 *p; 65 char *c; 66 67 if (xdr_stream_decode_u32(xdr, &size) < 0) 68 return false; 69 if (size == 0 || size > NFS_MAXNAMLEN) 70 return false; 71 p = xdr_inline_decode(xdr, size); 72 if (!p) 73 return false; 74 75 *len = size; 76 *name = (char *)p; 77 for (i = 0, c = *name; i < size; i++, c++) 78 if (*c == '\0' || *c == '/') 79 return false; 80 81 return true; 82 } 83 84 static bool 85 svcxdr_decode_diropargs(struct xdr_stream *xdr, struct svc_fh *fhp, 86 char **name, unsigned int *len) 87 { 88 return svcxdr_decode_fhandle(xdr, fhp) && 89 svcxdr_decode_filename(xdr, name, len); 90 } 91 92 static bool 93 svcxdr_decode_sattr(struct svc_rqst *rqstp, struct xdr_stream *xdr, 94 struct iattr *iap) 95 { 96 u32 tmp1, tmp2; 97 __be32 *p; 98 99 p = xdr_inline_decode(xdr, XDR_UNIT * 8); 100 if (!p) 101 return false; 102 103 iap->ia_valid = 0; 104 105 /* 106 * Some Sun clients put 0xffff in the mode field when they 107 * mean 0xffffffff. 108 */ 109 tmp1 = be32_to_cpup(p++); 110 if (tmp1 != (u32)-1 && tmp1 != 0xffff) { 111 iap->ia_valid |= ATTR_MODE; 112 iap->ia_mode = tmp1; 113 } 114 115 tmp1 = be32_to_cpup(p++); 116 if (tmp1 != (u32)-1) { 117 iap->ia_uid = make_kuid(nfsd_user_namespace(rqstp), tmp1); 118 if (uid_valid(iap->ia_uid)) 119 iap->ia_valid |= ATTR_UID; 120 } 121 122 tmp1 = be32_to_cpup(p++); 123 if (tmp1 != (u32)-1) { 124 iap->ia_gid = make_kgid(nfsd_user_namespace(rqstp), tmp1); 125 if (gid_valid(iap->ia_gid)) 126 iap->ia_valid |= ATTR_GID; 127 } 128 129 tmp1 = be32_to_cpup(p++); 130 if (tmp1 != (u32)-1) { 131 iap->ia_valid |= ATTR_SIZE; 132 iap->ia_size = tmp1; 133 } 134 135 tmp1 = be32_to_cpup(p++); 136 tmp2 = be32_to_cpup(p++); 137 if (tmp1 != (u32)-1 && tmp2 != (u32)-1) { 138 iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET; 139 iap->ia_atime.tv_sec = tmp1; 140 iap->ia_atime.tv_nsec = tmp2 * NSEC_PER_USEC; 141 } 142 143 tmp1 = be32_to_cpup(p++); 144 tmp2 = be32_to_cpup(p++); 145 if (tmp1 != (u32)-1 && tmp2 != (u32)-1) { 146 iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET; 147 iap->ia_mtime.tv_sec = tmp1; 148 iap->ia_mtime.tv_nsec = tmp2 * NSEC_PER_USEC; 149 /* 150 * Passing the invalid value useconds=1000000 for mtime 151 * is a Sun convention for "set both mtime and atime to 152 * current server time". It's needed to make permissions 153 * checks for the "touch" program across v2 mounts to 154 * Solaris and Irix boxes work correctly. See description of 155 * sattr in section 6.1 of "NFS Illustrated" by 156 * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5 157 */ 158 if (tmp2 == 1000000) 159 iap->ia_valid &= ~(ATTR_ATIME_SET|ATTR_MTIME_SET); 160 } 161 162 return true; 163 } 164 165 static __be32 * 166 encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, 167 struct kstat *stat) 168 { 169 struct user_namespace *userns = nfsd_user_namespace(rqstp); 170 struct dentry *dentry = fhp->fh_dentry; 171 int type; 172 struct timespec64 time; 173 u32 f; 174 175 type = (stat->mode & S_IFMT); 176 177 *p++ = htonl(nfs_ftypes[type >> 12]); 178 *p++ = htonl((u32) stat->mode); 179 *p++ = htonl((u32) stat->nlink); 180 *p++ = htonl((u32) from_kuid_munged(userns, stat->uid)); 181 *p++ = htonl((u32) from_kgid_munged(userns, stat->gid)); 182 183 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { 184 *p++ = htonl(NFS_MAXPATHLEN); 185 } else { 186 *p++ = htonl((u32) stat->size); 187 } 188 *p++ = htonl((u32) stat->blksize); 189 if (S_ISCHR(type) || S_ISBLK(type)) 190 *p++ = htonl(new_encode_dev(stat->rdev)); 191 else 192 *p++ = htonl(0xffffffff); 193 *p++ = htonl((u32) stat->blocks); 194 switch (fsid_source(fhp)) { 195 default: 196 case FSIDSOURCE_DEV: 197 *p++ = htonl(new_encode_dev(stat->dev)); 198 break; 199 case FSIDSOURCE_FSID: 200 *p++ = htonl((u32) fhp->fh_export->ex_fsid); 201 break; 202 case FSIDSOURCE_UUID: 203 f = ((u32*)fhp->fh_export->ex_uuid)[0]; 204 f ^= ((u32*)fhp->fh_export->ex_uuid)[1]; 205 f ^= ((u32*)fhp->fh_export->ex_uuid)[2]; 206 f ^= ((u32*)fhp->fh_export->ex_uuid)[3]; 207 *p++ = htonl(f); 208 break; 209 } 210 *p++ = htonl((u32) stat->ino); 211 *p++ = htonl((u32) stat->atime.tv_sec); 212 *p++ = htonl(stat->atime.tv_nsec ? stat->atime.tv_nsec / 1000 : 0); 213 time = stat->mtime; 214 lease_get_mtime(d_inode(dentry), &time); 215 *p++ = htonl((u32) time.tv_sec); 216 *p++ = htonl(time.tv_nsec ? time.tv_nsec / 1000 : 0); 217 *p++ = htonl((u32) stat->ctime.tv_sec); 218 *p++ = htonl(stat->ctime.tv_nsec ? stat->ctime.tv_nsec / 1000 : 0); 219 220 return p; 221 } 222 223 /* Helper function for NFSv2 ACL code */ 224 __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat) 225 { 226 return encode_fattr(rqstp, p, fhp, stat); 227 } 228 229 /* 230 * XDR decode functions 231 */ 232 233 int 234 nfssvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p) 235 { 236 struct xdr_stream *xdr = &rqstp->rq_arg_stream; 237 struct nfsd_fhandle *args = rqstp->rq_argp; 238 239 return svcxdr_decode_fhandle(xdr, &args->fh); 240 } 241 242 int 243 nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p) 244 { 245 struct xdr_stream *xdr = &rqstp->rq_arg_stream; 246 struct nfsd_sattrargs *args = rqstp->rq_argp; 247 248 return svcxdr_decode_fhandle(xdr, &args->fh) && 249 svcxdr_decode_sattr(rqstp, xdr, &args->attrs); 250 } 251 252 int 253 nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p) 254 { 255 struct xdr_stream *xdr = &rqstp->rq_arg_stream; 256 struct nfsd_diropargs *args = rqstp->rq_argp; 257 258 return svcxdr_decode_diropargs(xdr, &args->fh, &args->name, &args->len); 259 } 260 261 int 262 nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p) 263 { 264 struct xdr_stream *xdr = &rqstp->rq_arg_stream; 265 struct nfsd_readargs *args = rqstp->rq_argp; 266 u32 totalcount; 267 268 if (!svcxdr_decode_fhandle(xdr, &args->fh)) 269 return 0; 270 if (xdr_stream_decode_u32(xdr, &args->offset) < 0) 271 return 0; 272 if (xdr_stream_decode_u32(xdr, &args->count) < 0) 273 return 0; 274 /* totalcount is ignored */ 275 if (xdr_stream_decode_u32(xdr, &totalcount) < 0) 276 return 0; 277 278 return 1; 279 } 280 281 int 282 nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p) 283 { 284 struct xdr_stream *xdr = &rqstp->rq_arg_stream; 285 struct nfsd_writeargs *args = rqstp->rq_argp; 286 struct kvec *head = rqstp->rq_arg.head; 287 struct kvec *tail = rqstp->rq_arg.tail; 288 u32 beginoffset, totalcount; 289 size_t remaining; 290 291 if (!svcxdr_decode_fhandle(xdr, &args->fh)) 292 return 0; 293 /* beginoffset is ignored */ 294 if (xdr_stream_decode_u32(xdr, &beginoffset) < 0) 295 return 0; 296 if (xdr_stream_decode_u32(xdr, &args->offset) < 0) 297 return 0; 298 /* totalcount is ignored */ 299 if (xdr_stream_decode_u32(xdr, &totalcount) < 0) 300 return 0; 301 302 /* opaque data */ 303 if (xdr_stream_decode_u32(xdr, &args->len) < 0) 304 return 0; 305 if (args->len > NFSSVC_MAXBLKSIZE_V2) 306 return 0; 307 remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len; 308 remaining -= xdr_stream_pos(xdr); 309 if (remaining < xdr_align_size(args->len)) 310 return 0; 311 args->first.iov_base = xdr->p; 312 args->first.iov_len = head->iov_len - xdr_stream_pos(xdr); 313 314 return 1; 315 } 316 317 int 318 nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p) 319 { 320 struct xdr_stream *xdr = &rqstp->rq_arg_stream; 321 struct nfsd_createargs *args = rqstp->rq_argp; 322 323 return svcxdr_decode_diropargs(xdr, &args->fh, 324 &args->name, &args->len) && 325 svcxdr_decode_sattr(rqstp, xdr, &args->attrs); 326 } 327 328 int 329 nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p) 330 { 331 struct xdr_stream *xdr = &rqstp->rq_arg_stream; 332 struct nfsd_renameargs *args = rqstp->rq_argp; 333 334 return svcxdr_decode_diropargs(xdr, &args->ffh, 335 &args->fname, &args->flen) && 336 svcxdr_decode_diropargs(xdr, &args->tfh, 337 &args->tname, &args->tlen); 338 } 339 340 int 341 nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p) 342 { 343 struct xdr_stream *xdr = &rqstp->rq_arg_stream; 344 struct nfsd_linkargs *args = rqstp->rq_argp; 345 346 return svcxdr_decode_fhandle(xdr, &args->ffh) && 347 svcxdr_decode_diropargs(xdr, &args->tfh, 348 &args->tname, &args->tlen); 349 } 350 351 int 352 nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p) 353 { 354 struct xdr_stream *xdr = &rqstp->rq_arg_stream; 355 struct nfsd_symlinkargs *args = rqstp->rq_argp; 356 struct kvec *head = rqstp->rq_arg.head; 357 358 if (!svcxdr_decode_diropargs(xdr, &args->ffh, &args->fname, &args->flen)) 359 return 0; 360 if (xdr_stream_decode_u32(xdr, &args->tlen) < 0) 361 return 0; 362 if (args->tlen == 0) 363 return 0; 364 365 args->first.iov_len = head->iov_len - xdr_stream_pos(xdr); 366 args->first.iov_base = xdr_inline_decode(xdr, args->tlen); 367 if (!args->first.iov_base) 368 return 0; 369 return svcxdr_decode_sattr(rqstp, xdr, &args->attrs); 370 } 371 372 int 373 nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p) 374 { 375 struct xdr_stream *xdr = &rqstp->rq_arg_stream; 376 struct nfsd_readdirargs *args = rqstp->rq_argp; 377 378 if (!svcxdr_decode_fhandle(xdr, &args->fh)) 379 return 0; 380 if (xdr_stream_decode_u32(xdr, &args->cookie) < 0) 381 return 0; 382 if (xdr_stream_decode_u32(xdr, &args->count) < 0) 383 return 0; 384 385 return 1; 386 } 387 388 /* 389 * XDR encode functions 390 */ 391 392 int 393 nfssvc_encode_stat(struct svc_rqst *rqstp, __be32 *p) 394 { 395 struct nfsd_stat *resp = rqstp->rq_resp; 396 397 *p++ = resp->status; 398 return xdr_ressize_check(rqstp, p); 399 } 400 401 int 402 nfssvc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p) 403 { 404 struct nfsd_attrstat *resp = rqstp->rq_resp; 405 406 *p++ = resp->status; 407 if (resp->status != nfs_ok) 408 goto out; 409 p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); 410 out: 411 return xdr_ressize_check(rqstp, p); 412 } 413 414 int 415 nfssvc_encode_diropres(struct svc_rqst *rqstp, __be32 *p) 416 { 417 struct nfsd_diropres *resp = rqstp->rq_resp; 418 419 *p++ = resp->status; 420 if (resp->status != nfs_ok) 421 goto out; 422 p = encode_fh(p, &resp->fh); 423 p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); 424 out: 425 return xdr_ressize_check(rqstp, p); 426 } 427 428 int 429 nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p) 430 { 431 struct nfsd_readlinkres *resp = rqstp->rq_resp; 432 struct kvec *head = rqstp->rq_res.head; 433 434 *p++ = resp->status; 435 if (resp->status != nfs_ok) 436 return xdr_ressize_check(rqstp, p); 437 438 *p++ = htonl(resp->len); 439 xdr_ressize_check(rqstp, p); 440 rqstp->rq_res.page_len = resp->len; 441 if (resp->len & 3) { 442 /* need to pad the tail */ 443 rqstp->rq_res.tail[0].iov_base = p; 444 *p = 0; 445 rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3); 446 } 447 if (svc_encode_result_payload(rqstp, head->iov_len, resp->len)) 448 return 0; 449 return 1; 450 } 451 452 int 453 nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p) 454 { 455 struct nfsd_readres *resp = rqstp->rq_resp; 456 struct kvec *head = rqstp->rq_res.head; 457 458 *p++ = resp->status; 459 if (resp->status != nfs_ok) 460 return xdr_ressize_check(rqstp, p); 461 462 p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); 463 *p++ = htonl(resp->count); 464 xdr_ressize_check(rqstp, p); 465 466 /* now update rqstp->rq_res to reflect data as well */ 467 rqstp->rq_res.page_len = resp->count; 468 if (resp->count & 3) { 469 /* need to pad the tail */ 470 rqstp->rq_res.tail[0].iov_base = p; 471 *p = 0; 472 rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3); 473 } 474 if (svc_encode_result_payload(rqstp, head->iov_len, resp->count)) 475 return 0; 476 return 1; 477 } 478 479 int 480 nfssvc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p) 481 { 482 struct nfsd_readdirres *resp = rqstp->rq_resp; 483 484 *p++ = resp->status; 485 if (resp->status != nfs_ok) 486 return xdr_ressize_check(rqstp, p); 487 488 xdr_ressize_check(rqstp, p); 489 p = resp->buffer; 490 *p++ = 0; /* no more entries */ 491 *p++ = htonl((resp->common.err == nfserr_eof)); 492 rqstp->rq_res.page_len = (((unsigned long)p-1) & ~PAGE_MASK)+1; 493 494 return 1; 495 } 496 497 int 498 nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p) 499 { 500 struct nfsd_statfsres *resp = rqstp->rq_resp; 501 struct kstatfs *stat = &resp->stats; 502 503 *p++ = resp->status; 504 if (resp->status != nfs_ok) 505 return xdr_ressize_check(rqstp, p); 506 507 *p++ = htonl(NFSSVC_MAXBLKSIZE_V2); /* max transfer size */ 508 *p++ = htonl(stat->f_bsize); 509 *p++ = htonl(stat->f_blocks); 510 *p++ = htonl(stat->f_bfree); 511 *p++ = htonl(stat->f_bavail); 512 return xdr_ressize_check(rqstp, p); 513 } 514 515 int 516 nfssvc_encode_entry(void *ccdv, const char *name, 517 int namlen, loff_t offset, u64 ino, unsigned int d_type) 518 { 519 struct readdir_cd *ccd = ccdv; 520 struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common); 521 __be32 *p = cd->buffer; 522 int buflen, slen; 523 524 /* 525 dprintk("nfsd: entry(%.*s off %ld ino %ld)\n", 526 namlen, name, offset, ino); 527 */ 528 529 if (offset > ~((u32) 0)) { 530 cd->common.err = nfserr_fbig; 531 return -EINVAL; 532 } 533 if (cd->offset) 534 *cd->offset = htonl(offset); 535 536 /* truncate filename */ 537 namlen = min(namlen, NFS2_MAXNAMLEN); 538 slen = XDR_QUADLEN(namlen); 539 540 if ((buflen = cd->buflen - slen - 4) < 0) { 541 cd->common.err = nfserr_toosmall; 542 return -EINVAL; 543 } 544 if (ino > ~((u32) 0)) { 545 cd->common.err = nfserr_fbig; 546 return -EINVAL; 547 } 548 *p++ = xdr_one; /* mark entry present */ 549 *p++ = htonl((u32) ino); /* file id */ 550 p = xdr_encode_array(p, name, namlen);/* name length & name */ 551 cd->offset = p; /* remember pointer */ 552 *p++ = htonl(~0U); /* offset of next entry */ 553 554 cd->buflen = buflen; 555 cd->buffer = p; 556 cd->common.err = nfs_ok; 557 return 0; 558 } 559 560 /* 561 * XDR release functions 562 */ 563 void nfssvc_release_attrstat(struct svc_rqst *rqstp) 564 { 565 struct nfsd_attrstat *resp = rqstp->rq_resp; 566 567 fh_put(&resp->fh); 568 } 569 570 void nfssvc_release_diropres(struct svc_rqst *rqstp) 571 { 572 struct nfsd_diropres *resp = rqstp->rq_resp; 573 574 fh_put(&resp->fh); 575 } 576 577 void nfssvc_release_readres(struct svc_rqst *rqstp) 578 { 579 struct nfsd_readres *resp = rqstp->rq_resp; 580 581 fh_put(&resp->fh); 582 } 583