1 /* 2 * linux/fs/nfs/callback_xdr.c 3 * 4 * Copyright (C) 2004 Trond Myklebust 5 * 6 * NFSv4 callback encode/decode procedures 7 */ 8 #include <linux/kernel.h> 9 #include <linux/sunrpc/svc.h> 10 #include <linux/nfs4.h> 11 #include <linux/nfs_fs.h> 12 #include <linux/ratelimit.h> 13 #include <linux/printk.h> 14 #include <linux/slab.h> 15 #include <linux/sunrpc/bc_xprt.h> 16 #include "nfs4_fs.h" 17 #include "callback.h" 18 #include "internal.h" 19 #include "nfs4session.h" 20 21 #define CB_OP_TAGLEN_MAXSZ (512) 22 #define CB_OP_HDR_RES_MAXSZ (2 * 4) // opcode, status 23 #define CB_OP_GETATTR_BITMAP_MAXSZ (4 * 4) // bitmap length, 3 bitmaps 24 #define CB_OP_GETATTR_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ 25 CB_OP_GETATTR_BITMAP_MAXSZ + \ 26 /* change, size, ctime, mtime */\ 27 (2 + 2 + 3 + 3) * 4) 28 #define CB_OP_RECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) 29 30 #if defined(CONFIG_NFS_V4_1) 31 #define CB_OP_LAYOUTRECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) 32 #define CB_OP_DEVICENOTIFY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) 33 #define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ 34 NFS4_MAX_SESSIONID_LEN + \ 35 (1 + 3) * 4) // seqid, 3 slotids 36 #define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) 37 #define CB_OP_RECALLSLOT_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) 38 #define CB_OP_NOTIFY_LOCK_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) 39 #endif /* CONFIG_NFS_V4_1 */ 40 41 #define NFSDBG_FACILITY NFSDBG_CALLBACK 42 43 /* Internal error code */ 44 #define NFS4ERR_RESOURCE_HDR 11050 45 46 struct callback_op { 47 __be32 (*process_op)(void *, void *, struct cb_process_state *); 48 __be32 (*decode_args)(struct svc_rqst *, struct xdr_stream *, void *); 49 __be32 (*encode_res)(struct svc_rqst *, struct xdr_stream *, 50 const void *); 51 long res_maxsize; 52 }; 53 54 static struct callback_op callback_ops[]; 55 56 static __be32 nfs4_callback_null(struct svc_rqst *rqstp) 57 { 58 return htonl(NFS4_OK); 59 } 60 61 static int nfs4_decode_void(struct svc_rqst *rqstp, __be32 *p) 62 { 63 return xdr_argsize_check(rqstp, p); 64 } 65 66 static int nfs4_encode_void(struct svc_rqst *rqstp, __be32 *p) 67 { 68 return xdr_ressize_check(rqstp, p); 69 } 70 71 static __be32 *read_buf(struct xdr_stream *xdr, size_t nbytes) 72 { 73 __be32 *p; 74 75 p = xdr_inline_decode(xdr, nbytes); 76 if (unlikely(p == NULL)) 77 printk(KERN_WARNING "NFS: NFSv4 callback reply buffer overflowed!\n"); 78 return p; 79 } 80 81 static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, 82 const char **str, size_t maxlen) 83 { 84 ssize_t err; 85 86 err = xdr_stream_decode_opaque_inline(xdr, (void **)str, maxlen); 87 if (err < 0) 88 return cpu_to_be32(NFS4ERR_RESOURCE); 89 *len = err; 90 return 0; 91 } 92 93 static __be32 decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh) 94 { 95 __be32 *p; 96 97 p = read_buf(xdr, 4); 98 if (unlikely(p == NULL)) 99 return htonl(NFS4ERR_RESOURCE); 100 fh->size = ntohl(*p); 101 if (fh->size > NFS4_FHSIZE) 102 return htonl(NFS4ERR_BADHANDLE); 103 p = read_buf(xdr, fh->size); 104 if (unlikely(p == NULL)) 105 return htonl(NFS4ERR_RESOURCE); 106 memcpy(&fh->data[0], p, fh->size); 107 memset(&fh->data[fh->size], 0, sizeof(fh->data) - fh->size); 108 return 0; 109 } 110 111 static __be32 decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) 112 { 113 __be32 *p; 114 unsigned int attrlen; 115 116 p = read_buf(xdr, 4); 117 if (unlikely(p == NULL)) 118 return htonl(NFS4ERR_RESOURCE); 119 attrlen = ntohl(*p); 120 p = read_buf(xdr, attrlen << 2); 121 if (unlikely(p == NULL)) 122 return htonl(NFS4ERR_RESOURCE); 123 if (likely(attrlen > 0)) 124 bitmap[0] = ntohl(*p++); 125 if (attrlen > 1) 126 bitmap[1] = ntohl(*p); 127 return 0; 128 } 129 130 static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 131 { 132 __be32 *p; 133 134 p = read_buf(xdr, NFS4_STATEID_SIZE); 135 if (unlikely(p == NULL)) 136 return htonl(NFS4ERR_RESOURCE); 137 memcpy(stateid->data, p, NFS4_STATEID_SIZE); 138 return 0; 139 } 140 141 static __be32 decode_delegation_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 142 { 143 stateid->type = NFS4_DELEGATION_STATEID_TYPE; 144 return decode_stateid(xdr, stateid); 145 } 146 147 static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr) 148 { 149 __be32 *p; 150 __be32 status; 151 152 status = decode_string(xdr, &hdr->taglen, &hdr->tag, CB_OP_TAGLEN_MAXSZ); 153 if (unlikely(status != 0)) 154 return status; 155 p = read_buf(xdr, 12); 156 if (unlikely(p == NULL)) 157 return htonl(NFS4ERR_RESOURCE); 158 hdr->minorversion = ntohl(*p++); 159 /* Check for minor version support */ 160 if (hdr->minorversion <= NFS4_MAX_MINOR_VERSION) { 161 hdr->cb_ident = ntohl(*p++); /* ignored by v4.1 and v4.2 */ 162 } else { 163 pr_warn_ratelimited("NFS: %s: NFSv4 server callback with " 164 "illegal minor version %u!\n", 165 __func__, hdr->minorversion); 166 return htonl(NFS4ERR_MINOR_VERS_MISMATCH); 167 } 168 hdr->nops = ntohl(*p); 169 return 0; 170 } 171 172 static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op) 173 { 174 __be32 *p; 175 p = read_buf(xdr, 4); 176 if (unlikely(p == NULL)) 177 return htonl(NFS4ERR_RESOURCE_HDR); 178 *op = ntohl(*p); 179 return 0; 180 } 181 182 static __be32 decode_getattr_args(struct svc_rqst *rqstp, 183 struct xdr_stream *xdr, void *argp) 184 { 185 struct cb_getattrargs *args = argp; 186 __be32 status; 187 188 status = decode_fh(xdr, &args->fh); 189 if (unlikely(status != 0)) 190 return status; 191 return decode_bitmap(xdr, args->bitmap); 192 } 193 194 static __be32 decode_recall_args(struct svc_rqst *rqstp, 195 struct xdr_stream *xdr, void *argp) 196 { 197 struct cb_recallargs *args = argp; 198 __be32 *p; 199 __be32 status; 200 201 status = decode_delegation_stateid(xdr, &args->stateid); 202 if (unlikely(status != 0)) 203 return status; 204 p = read_buf(xdr, 4); 205 if (unlikely(p == NULL)) 206 return htonl(NFS4ERR_RESOURCE); 207 args->truncate = ntohl(*p); 208 return decode_fh(xdr, &args->fh); 209 } 210 211 #if defined(CONFIG_NFS_V4_1) 212 static __be32 decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 213 { 214 stateid->type = NFS4_LAYOUT_STATEID_TYPE; 215 return decode_stateid(xdr, stateid); 216 } 217 218 static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp, 219 struct xdr_stream *xdr, void *argp) 220 { 221 struct cb_layoutrecallargs *args = argp; 222 __be32 *p; 223 __be32 status = 0; 224 uint32_t iomode; 225 226 p = read_buf(xdr, 4 * sizeof(uint32_t)); 227 if (unlikely(p == NULL)) 228 return htonl(NFS4ERR_BADXDR); 229 230 args->cbl_layout_type = ntohl(*p++); 231 /* Depite the spec's xdr, iomode really belongs in the FILE switch, 232 * as it is unusable and ignored with the other types. 233 */ 234 iomode = ntohl(*p++); 235 args->cbl_layoutchanged = ntohl(*p++); 236 args->cbl_recall_type = ntohl(*p++); 237 238 if (args->cbl_recall_type == RETURN_FILE) { 239 args->cbl_range.iomode = iomode; 240 status = decode_fh(xdr, &args->cbl_fh); 241 if (unlikely(status != 0)) 242 return status; 243 244 p = read_buf(xdr, 2 * sizeof(uint64_t)); 245 if (unlikely(p == NULL)) 246 return htonl(NFS4ERR_BADXDR); 247 p = xdr_decode_hyper(p, &args->cbl_range.offset); 248 p = xdr_decode_hyper(p, &args->cbl_range.length); 249 return decode_layout_stateid(xdr, &args->cbl_stateid); 250 } else if (args->cbl_recall_type == RETURN_FSID) { 251 p = read_buf(xdr, 2 * sizeof(uint64_t)); 252 if (unlikely(p == NULL)) 253 return htonl(NFS4ERR_BADXDR); 254 p = xdr_decode_hyper(p, &args->cbl_fsid.major); 255 p = xdr_decode_hyper(p, &args->cbl_fsid.minor); 256 } else if (args->cbl_recall_type != RETURN_ALL) 257 return htonl(NFS4ERR_BADXDR); 258 return 0; 259 } 260 261 static 262 __be32 decode_devicenotify_args(struct svc_rqst *rqstp, 263 struct xdr_stream *xdr, 264 void *argp) 265 { 266 struct cb_devicenotifyargs *args = argp; 267 __be32 *p; 268 __be32 status = 0; 269 u32 tmp; 270 int n, i; 271 args->ndevs = 0; 272 273 /* Num of device notifications */ 274 p = read_buf(xdr, sizeof(uint32_t)); 275 if (unlikely(p == NULL)) { 276 status = htonl(NFS4ERR_BADXDR); 277 goto out; 278 } 279 n = ntohl(*p++); 280 if (n <= 0) 281 goto out; 282 if (n > ULONG_MAX / sizeof(*args->devs)) { 283 status = htonl(NFS4ERR_BADXDR); 284 goto out; 285 } 286 287 args->devs = kmalloc_array(n, sizeof(*args->devs), GFP_KERNEL); 288 if (!args->devs) { 289 status = htonl(NFS4ERR_DELAY); 290 goto out; 291 } 292 293 /* Decode each dev notification */ 294 for (i = 0; i < n; i++) { 295 struct cb_devicenotifyitem *dev = &args->devs[i]; 296 297 p = read_buf(xdr, (4 * sizeof(uint32_t)) + NFS4_DEVICEID4_SIZE); 298 if (unlikely(p == NULL)) { 299 status = htonl(NFS4ERR_BADXDR); 300 goto err; 301 } 302 303 tmp = ntohl(*p++); /* bitmap size */ 304 if (tmp != 1) { 305 status = htonl(NFS4ERR_INVAL); 306 goto err; 307 } 308 dev->cbd_notify_type = ntohl(*p++); 309 if (dev->cbd_notify_type != NOTIFY_DEVICEID4_CHANGE && 310 dev->cbd_notify_type != NOTIFY_DEVICEID4_DELETE) { 311 status = htonl(NFS4ERR_INVAL); 312 goto err; 313 } 314 315 tmp = ntohl(*p++); /* opaque size */ 316 if (((dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE) && 317 (tmp != NFS4_DEVICEID4_SIZE + 8)) || 318 ((dev->cbd_notify_type == NOTIFY_DEVICEID4_DELETE) && 319 (tmp != NFS4_DEVICEID4_SIZE + 4))) { 320 status = htonl(NFS4ERR_INVAL); 321 goto err; 322 } 323 dev->cbd_layout_type = ntohl(*p++); 324 memcpy(dev->cbd_dev_id.data, p, NFS4_DEVICEID4_SIZE); 325 p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); 326 327 if (dev->cbd_layout_type == NOTIFY_DEVICEID4_CHANGE) { 328 p = read_buf(xdr, sizeof(uint32_t)); 329 if (unlikely(p == NULL)) { 330 status = htonl(NFS4ERR_BADXDR); 331 goto err; 332 } 333 dev->cbd_immediate = ntohl(*p++); 334 } else { 335 dev->cbd_immediate = 0; 336 } 337 338 args->ndevs++; 339 340 dprintk("%s: type %d layout 0x%x immediate %d\n", 341 __func__, dev->cbd_notify_type, dev->cbd_layout_type, 342 dev->cbd_immediate); 343 } 344 out: 345 dprintk("%s: status %d ndevs %d\n", 346 __func__, ntohl(status), args->ndevs); 347 return status; 348 err: 349 kfree(args->devs); 350 goto out; 351 } 352 353 static __be32 decode_sessionid(struct xdr_stream *xdr, 354 struct nfs4_sessionid *sid) 355 { 356 __be32 *p; 357 358 p = read_buf(xdr, NFS4_MAX_SESSIONID_LEN); 359 if (unlikely(p == NULL)) 360 return htonl(NFS4ERR_RESOURCE); 361 362 memcpy(sid->data, p, NFS4_MAX_SESSIONID_LEN); 363 return 0; 364 } 365 366 static __be32 decode_rc_list(struct xdr_stream *xdr, 367 struct referring_call_list *rc_list) 368 { 369 __be32 *p; 370 int i; 371 __be32 status; 372 373 status = decode_sessionid(xdr, &rc_list->rcl_sessionid); 374 if (status) 375 goto out; 376 377 status = htonl(NFS4ERR_RESOURCE); 378 p = read_buf(xdr, sizeof(uint32_t)); 379 if (unlikely(p == NULL)) 380 goto out; 381 382 rc_list->rcl_nrefcalls = ntohl(*p++); 383 if (rc_list->rcl_nrefcalls) { 384 p = read_buf(xdr, 385 rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)); 386 if (unlikely(p == NULL)) 387 goto out; 388 rc_list->rcl_refcalls = kmalloc_array(rc_list->rcl_nrefcalls, 389 sizeof(*rc_list->rcl_refcalls), 390 GFP_KERNEL); 391 if (unlikely(rc_list->rcl_refcalls == NULL)) 392 goto out; 393 for (i = 0; i < rc_list->rcl_nrefcalls; i++) { 394 rc_list->rcl_refcalls[i].rc_sequenceid = ntohl(*p++); 395 rc_list->rcl_refcalls[i].rc_slotid = ntohl(*p++); 396 } 397 } 398 status = 0; 399 400 out: 401 return status; 402 } 403 404 static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp, 405 struct xdr_stream *xdr, 406 void *argp) 407 { 408 struct cb_sequenceargs *args = argp; 409 __be32 *p; 410 int i; 411 __be32 status; 412 413 status = decode_sessionid(xdr, &args->csa_sessionid); 414 if (status) 415 return status; 416 417 p = read_buf(xdr, 5 * sizeof(uint32_t)); 418 if (unlikely(p == NULL)) 419 return htonl(NFS4ERR_RESOURCE); 420 421 args->csa_addr = svc_addr(rqstp); 422 args->csa_sequenceid = ntohl(*p++); 423 args->csa_slotid = ntohl(*p++); 424 args->csa_highestslotid = ntohl(*p++); 425 args->csa_cachethis = ntohl(*p++); 426 args->csa_nrclists = ntohl(*p++); 427 args->csa_rclists = NULL; 428 if (args->csa_nrclists) { 429 args->csa_rclists = kmalloc_array(args->csa_nrclists, 430 sizeof(*args->csa_rclists), 431 GFP_KERNEL); 432 if (unlikely(args->csa_rclists == NULL)) 433 return htonl(NFS4ERR_RESOURCE); 434 435 for (i = 0; i < args->csa_nrclists; i++) { 436 status = decode_rc_list(xdr, &args->csa_rclists[i]); 437 if (status) { 438 args->csa_nrclists = i; 439 goto out_free; 440 } 441 } 442 } 443 return 0; 444 445 out_free: 446 for (i = 0; i < args->csa_nrclists; i++) 447 kfree(args->csa_rclists[i].rcl_refcalls); 448 kfree(args->csa_rclists); 449 return status; 450 } 451 452 static __be32 decode_recallany_args(struct svc_rqst *rqstp, 453 struct xdr_stream *xdr, 454 void *argp) 455 { 456 struct cb_recallanyargs *args = argp; 457 uint32_t bitmap[2]; 458 __be32 *p, status; 459 460 p = read_buf(xdr, 4); 461 if (unlikely(p == NULL)) 462 return htonl(NFS4ERR_BADXDR); 463 args->craa_objs_to_keep = ntohl(*p++); 464 status = decode_bitmap(xdr, bitmap); 465 if (unlikely(status)) 466 return status; 467 args->craa_type_mask = bitmap[0]; 468 469 return 0; 470 } 471 472 static __be32 decode_recallslot_args(struct svc_rqst *rqstp, 473 struct xdr_stream *xdr, 474 void *argp) 475 { 476 struct cb_recallslotargs *args = argp; 477 __be32 *p; 478 479 p = read_buf(xdr, 4); 480 if (unlikely(p == NULL)) 481 return htonl(NFS4ERR_BADXDR); 482 args->crsa_target_highest_slotid = ntohl(*p++); 483 return 0; 484 } 485 486 static __be32 decode_lockowner(struct xdr_stream *xdr, struct cb_notify_lock_args *args) 487 { 488 __be32 *p; 489 unsigned int len; 490 491 p = read_buf(xdr, 12); 492 if (unlikely(p == NULL)) 493 return htonl(NFS4ERR_BADXDR); 494 495 p = xdr_decode_hyper(p, &args->cbnl_owner.clientid); 496 len = be32_to_cpu(*p); 497 498 p = read_buf(xdr, len); 499 if (unlikely(p == NULL)) 500 return htonl(NFS4ERR_BADXDR); 501 502 /* Only try to decode if the length is right */ 503 if (len == 20) { 504 p += 2; /* skip "lock id:" */ 505 args->cbnl_owner.s_dev = be32_to_cpu(*p++); 506 xdr_decode_hyper(p, &args->cbnl_owner.id); 507 args->cbnl_valid = true; 508 } else { 509 args->cbnl_owner.s_dev = 0; 510 args->cbnl_owner.id = 0; 511 args->cbnl_valid = false; 512 } 513 return 0; 514 } 515 516 static __be32 decode_notify_lock_args(struct svc_rqst *rqstp, 517 struct xdr_stream *xdr, void *argp) 518 { 519 struct cb_notify_lock_args *args = argp; 520 __be32 status; 521 522 status = decode_fh(xdr, &args->cbnl_fh); 523 if (unlikely(status != 0)) 524 return status; 525 return decode_lockowner(xdr, args); 526 } 527 528 #endif /* CONFIG_NFS_V4_1 */ 529 530 static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) 531 { 532 if (unlikely(xdr_stream_encode_opaque(xdr, str, len) < 0)) 533 return cpu_to_be32(NFS4ERR_RESOURCE); 534 return 0; 535 } 536 537 #define CB_SUPPORTED_ATTR0 (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) 538 #define CB_SUPPORTED_ATTR1 (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) 539 static __be32 encode_attr_bitmap(struct xdr_stream *xdr, const uint32_t *bitmap, __be32 **savep) 540 { 541 __be32 bm[2]; 542 __be32 *p; 543 544 bm[0] = htonl(bitmap[0] & CB_SUPPORTED_ATTR0); 545 bm[1] = htonl(bitmap[1] & CB_SUPPORTED_ATTR1); 546 if (bm[1] != 0) { 547 p = xdr_reserve_space(xdr, 16); 548 if (unlikely(p == NULL)) 549 return htonl(NFS4ERR_RESOURCE); 550 *p++ = htonl(2); 551 *p++ = bm[0]; 552 *p++ = bm[1]; 553 } else if (bm[0] != 0) { 554 p = xdr_reserve_space(xdr, 12); 555 if (unlikely(p == NULL)) 556 return htonl(NFS4ERR_RESOURCE); 557 *p++ = htonl(1); 558 *p++ = bm[0]; 559 } else { 560 p = xdr_reserve_space(xdr, 8); 561 if (unlikely(p == NULL)) 562 return htonl(NFS4ERR_RESOURCE); 563 *p++ = htonl(0); 564 } 565 *savep = p; 566 return 0; 567 } 568 569 static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t change) 570 { 571 __be32 *p; 572 573 if (!(bitmap[0] & FATTR4_WORD0_CHANGE)) 574 return 0; 575 p = xdr_reserve_space(xdr, 8); 576 if (unlikely(!p)) 577 return htonl(NFS4ERR_RESOURCE); 578 p = xdr_encode_hyper(p, change); 579 return 0; 580 } 581 582 static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t size) 583 { 584 __be32 *p; 585 586 if (!(bitmap[0] & FATTR4_WORD0_SIZE)) 587 return 0; 588 p = xdr_reserve_space(xdr, 8); 589 if (unlikely(!p)) 590 return htonl(NFS4ERR_RESOURCE); 591 p = xdr_encode_hyper(p, size); 592 return 0; 593 } 594 595 static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *time) 596 { 597 __be32 *p; 598 599 p = xdr_reserve_space(xdr, 12); 600 if (unlikely(!p)) 601 return htonl(NFS4ERR_RESOURCE); 602 p = xdr_encode_hyper(p, time->tv_sec); 603 *p = htonl(time->tv_nsec); 604 return 0; 605 } 606 607 static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time) 608 { 609 if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA)) 610 return 0; 611 return encode_attr_time(xdr,time); 612 } 613 614 static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time) 615 { 616 if (!(bitmap[1] & FATTR4_WORD1_TIME_MODIFY)) 617 return 0; 618 return encode_attr_time(xdr,time); 619 } 620 621 static __be32 encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound_hdr_res *hdr) 622 { 623 __be32 status; 624 625 hdr->status = xdr_reserve_space(xdr, 4); 626 if (unlikely(hdr->status == NULL)) 627 return htonl(NFS4ERR_RESOURCE); 628 status = encode_string(xdr, hdr->taglen, hdr->tag); 629 if (unlikely(status != 0)) 630 return status; 631 hdr->nops = xdr_reserve_space(xdr, 4); 632 if (unlikely(hdr->nops == NULL)) 633 return htonl(NFS4ERR_RESOURCE); 634 return 0; 635 } 636 637 static __be32 encode_op_hdr(struct xdr_stream *xdr, uint32_t op, __be32 res) 638 { 639 __be32 *p; 640 641 p = xdr_reserve_space(xdr, 8); 642 if (unlikely(p == NULL)) 643 return htonl(NFS4ERR_RESOURCE_HDR); 644 *p++ = htonl(op); 645 *p = res; 646 return 0; 647 } 648 649 static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, 650 const void *resp) 651 { 652 const struct cb_getattrres *res = resp; 653 __be32 *savep = NULL; 654 __be32 status = res->status; 655 656 if (unlikely(status != 0)) 657 goto out; 658 status = encode_attr_bitmap(xdr, res->bitmap, &savep); 659 if (unlikely(status != 0)) 660 goto out; 661 status = encode_attr_change(xdr, res->bitmap, res->change_attr); 662 if (unlikely(status != 0)) 663 goto out; 664 status = encode_attr_size(xdr, res->bitmap, res->size); 665 if (unlikely(status != 0)) 666 goto out; 667 status = encode_attr_ctime(xdr, res->bitmap, &res->ctime); 668 if (unlikely(status != 0)) 669 goto out; 670 status = encode_attr_mtime(xdr, res->bitmap, &res->mtime); 671 *savep = htonl((unsigned int)((char *)xdr->p - (char *)(savep+1))); 672 out: 673 return status; 674 } 675 676 #if defined(CONFIG_NFS_V4_1) 677 678 static __be32 encode_sessionid(struct xdr_stream *xdr, 679 const struct nfs4_sessionid *sid) 680 { 681 __be32 *p; 682 683 p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN); 684 if (unlikely(p == NULL)) 685 return htonl(NFS4ERR_RESOURCE); 686 687 memcpy(p, sid, NFS4_MAX_SESSIONID_LEN); 688 return 0; 689 } 690 691 static __be32 encode_cb_sequence_res(struct svc_rqst *rqstp, 692 struct xdr_stream *xdr, 693 const void *resp) 694 { 695 const struct cb_sequenceres *res = resp; 696 __be32 *p; 697 __be32 status = res->csr_status; 698 699 if (unlikely(status != 0)) 700 return status; 701 702 status = encode_sessionid(xdr, &res->csr_sessionid); 703 if (status) 704 return status; 705 706 p = xdr_reserve_space(xdr, 4 * sizeof(uint32_t)); 707 if (unlikely(p == NULL)) 708 return htonl(NFS4ERR_RESOURCE); 709 710 *p++ = htonl(res->csr_sequenceid); 711 *p++ = htonl(res->csr_slotid); 712 *p++ = htonl(res->csr_highestslotid); 713 *p++ = htonl(res->csr_target_highestslotid); 714 return 0; 715 } 716 717 static __be32 718 preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) 719 { 720 if (op_nr == OP_CB_SEQUENCE) { 721 if (nop != 0) 722 return htonl(NFS4ERR_SEQUENCE_POS); 723 } else { 724 if (nop == 0) 725 return htonl(NFS4ERR_OP_NOT_IN_SESSION); 726 } 727 728 switch (op_nr) { 729 case OP_CB_GETATTR: 730 case OP_CB_RECALL: 731 case OP_CB_SEQUENCE: 732 case OP_CB_RECALL_ANY: 733 case OP_CB_RECALL_SLOT: 734 case OP_CB_LAYOUTRECALL: 735 case OP_CB_NOTIFY_DEVICEID: 736 case OP_CB_NOTIFY_LOCK: 737 *op = &callback_ops[op_nr]; 738 break; 739 740 case OP_CB_NOTIFY: 741 case OP_CB_PUSH_DELEG: 742 case OP_CB_RECALLABLE_OBJ_AVAIL: 743 case OP_CB_WANTS_CANCELLED: 744 return htonl(NFS4ERR_NOTSUPP); 745 746 default: 747 return htonl(NFS4ERR_OP_ILLEGAL); 748 } 749 750 return htonl(NFS_OK); 751 } 752 753 static void nfs4_callback_free_slot(struct nfs4_session *session, 754 struct nfs4_slot *slot) 755 { 756 struct nfs4_slot_table *tbl = &session->bc_slot_table; 757 758 spin_lock(&tbl->slot_tbl_lock); 759 /* 760 * Let the state manager know callback processing done. 761 * A single slot, so highest used slotid is either 0 or -1 762 */ 763 nfs4_free_slot(tbl, slot); 764 spin_unlock(&tbl->slot_tbl_lock); 765 } 766 767 static void nfs4_cb_free_slot(struct cb_process_state *cps) 768 { 769 if (cps->slot) { 770 nfs4_callback_free_slot(cps->clp->cl_session, cps->slot); 771 cps->slot = NULL; 772 } 773 } 774 775 #else /* CONFIG_NFS_V4_1 */ 776 777 static __be32 778 preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) 779 { 780 return htonl(NFS4ERR_MINOR_VERS_MISMATCH); 781 } 782 783 static void nfs4_cb_free_slot(struct cb_process_state *cps) 784 { 785 } 786 #endif /* CONFIG_NFS_V4_1 */ 787 788 #ifdef CONFIG_NFS_V4_2 789 static __be32 790 preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op) 791 { 792 __be32 status = preprocess_nfs41_op(nop, op_nr, op); 793 if (status != htonl(NFS4ERR_OP_ILLEGAL)) 794 return status; 795 796 if (op_nr == OP_CB_OFFLOAD) 797 return htonl(NFS4ERR_NOTSUPP); 798 return htonl(NFS4ERR_OP_ILLEGAL); 799 } 800 #else /* CONFIG_NFS_V4_2 */ 801 static __be32 802 preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op) 803 { 804 return htonl(NFS4ERR_MINOR_VERS_MISMATCH); 805 } 806 #endif /* CONFIG_NFS_V4_2 */ 807 808 static __be32 809 preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op) 810 { 811 switch (op_nr) { 812 case OP_CB_GETATTR: 813 case OP_CB_RECALL: 814 *op = &callback_ops[op_nr]; 815 break; 816 default: 817 return htonl(NFS4ERR_OP_ILLEGAL); 818 } 819 820 return htonl(NFS_OK); 821 } 822 823 static __be32 process_op(int nop, struct svc_rqst *rqstp, 824 struct xdr_stream *xdr_in, void *argp, 825 struct xdr_stream *xdr_out, void *resp, 826 struct cb_process_state *cps) 827 { 828 struct callback_op *op = &callback_ops[0]; 829 unsigned int op_nr; 830 __be32 status; 831 long maxlen; 832 __be32 res; 833 834 status = decode_op_hdr(xdr_in, &op_nr); 835 if (unlikely(status)) 836 return status; 837 838 switch (cps->minorversion) { 839 case 0: 840 status = preprocess_nfs4_op(op_nr, &op); 841 break; 842 case 1: 843 status = preprocess_nfs41_op(nop, op_nr, &op); 844 break; 845 case 2: 846 status = preprocess_nfs42_op(nop, op_nr, &op); 847 break; 848 default: 849 status = htonl(NFS4ERR_MINOR_VERS_MISMATCH); 850 } 851 852 if (status == htonl(NFS4ERR_OP_ILLEGAL)) 853 op_nr = OP_CB_ILLEGAL; 854 if (status) 855 goto encode_hdr; 856 857 if (cps->drc_status) { 858 status = cps->drc_status; 859 goto encode_hdr; 860 } 861 862 maxlen = xdr_out->end - xdr_out->p; 863 if (maxlen > 0 && maxlen < PAGE_SIZE) { 864 status = op->decode_args(rqstp, xdr_in, argp); 865 if (likely(status == 0)) 866 status = op->process_op(argp, resp, cps); 867 } else 868 status = htonl(NFS4ERR_RESOURCE); 869 870 encode_hdr: 871 res = encode_op_hdr(xdr_out, op_nr, status); 872 if (unlikely(res)) 873 return res; 874 if (op->encode_res != NULL && status == 0) 875 status = op->encode_res(rqstp, xdr_out, resp); 876 return status; 877 } 878 879 /* 880 * Decode, process and encode a COMPOUND 881 */ 882 static __be32 nfs4_callback_compound(struct svc_rqst *rqstp) 883 { 884 struct cb_compound_hdr_arg hdr_arg = { 0 }; 885 struct cb_compound_hdr_res hdr_res = { NULL }; 886 struct xdr_stream xdr_in, xdr_out; 887 __be32 *p, status; 888 struct cb_process_state cps = { 889 .drc_status = 0, 890 .clp = NULL, 891 .net = SVC_NET(rqstp), 892 }; 893 unsigned int nops = 0; 894 895 xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base); 896 897 p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len); 898 xdr_init_encode(&xdr_out, &rqstp->rq_res, p); 899 900 status = decode_compound_hdr_arg(&xdr_in, &hdr_arg); 901 if (status == htonl(NFS4ERR_RESOURCE)) 902 return rpc_garbage_args; 903 904 if (hdr_arg.minorversion == 0) { 905 cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident); 906 if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp)) 907 goto out_invalidcred; 908 } 909 910 cps.minorversion = hdr_arg.minorversion; 911 hdr_res.taglen = hdr_arg.taglen; 912 hdr_res.tag = hdr_arg.tag; 913 if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0) 914 return rpc_system_err; 915 916 while (status == 0 && nops != hdr_arg.nops) { 917 status = process_op(nops, rqstp, &xdr_in, 918 rqstp->rq_argp, &xdr_out, rqstp->rq_resp, 919 &cps); 920 nops++; 921 } 922 923 /* Buffer overflow in decode_ops_hdr or encode_ops_hdr. Return 924 * resource error in cb_compound status without returning op */ 925 if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) { 926 status = htonl(NFS4ERR_RESOURCE); 927 nops--; 928 } 929 930 *hdr_res.status = status; 931 *hdr_res.nops = htonl(nops); 932 nfs4_cb_free_slot(&cps); 933 nfs_put_client(cps.clp); 934 return rpc_success; 935 936 out_invalidcred: 937 pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n"); 938 return rpc_autherr_badcred; 939 } 940 941 /* 942 * Define NFS4 callback COMPOUND ops. 943 */ 944 static struct callback_op callback_ops[] = { 945 [0] = { 946 .res_maxsize = CB_OP_HDR_RES_MAXSZ, 947 }, 948 [OP_CB_GETATTR] = { 949 .process_op = nfs4_callback_getattr, 950 .decode_args = decode_getattr_args, 951 .encode_res = encode_getattr_res, 952 .res_maxsize = CB_OP_GETATTR_RES_MAXSZ, 953 }, 954 [OP_CB_RECALL] = { 955 .process_op = nfs4_callback_recall, 956 .decode_args = decode_recall_args, 957 .res_maxsize = CB_OP_RECALL_RES_MAXSZ, 958 }, 959 #if defined(CONFIG_NFS_V4_1) 960 [OP_CB_LAYOUTRECALL] = { 961 .process_op = nfs4_callback_layoutrecall, 962 .decode_args = decode_layoutrecall_args, 963 .res_maxsize = CB_OP_LAYOUTRECALL_RES_MAXSZ, 964 }, 965 [OP_CB_NOTIFY_DEVICEID] = { 966 .process_op = nfs4_callback_devicenotify, 967 .decode_args = decode_devicenotify_args, 968 .res_maxsize = CB_OP_DEVICENOTIFY_RES_MAXSZ, 969 }, 970 [OP_CB_SEQUENCE] = { 971 .process_op = nfs4_callback_sequence, 972 .decode_args = decode_cb_sequence_args, 973 .encode_res = encode_cb_sequence_res, 974 .res_maxsize = CB_OP_SEQUENCE_RES_MAXSZ, 975 }, 976 [OP_CB_RECALL_ANY] = { 977 .process_op = nfs4_callback_recallany, 978 .decode_args = decode_recallany_args, 979 .res_maxsize = CB_OP_RECALLANY_RES_MAXSZ, 980 }, 981 [OP_CB_RECALL_SLOT] = { 982 .process_op = nfs4_callback_recallslot, 983 .decode_args = decode_recallslot_args, 984 .res_maxsize = CB_OP_RECALLSLOT_RES_MAXSZ, 985 }, 986 [OP_CB_NOTIFY_LOCK] = { 987 .process_op = nfs4_callback_notify_lock, 988 .decode_args = decode_notify_lock_args, 989 .res_maxsize = CB_OP_NOTIFY_LOCK_RES_MAXSZ, 990 }, 991 #endif /* CONFIG_NFS_V4_1 */ 992 }; 993 994 /* 995 * Define NFS4 callback procedures 996 */ 997 static const struct svc_procedure nfs4_callback_procedures1[] = { 998 [CB_NULL] = { 999 .pc_func = nfs4_callback_null, 1000 .pc_decode = nfs4_decode_void, 1001 .pc_encode = nfs4_encode_void, 1002 .pc_xdrressize = 1, 1003 }, 1004 [CB_COMPOUND] = { 1005 .pc_func = nfs4_callback_compound, 1006 .pc_encode = nfs4_encode_void, 1007 .pc_argsize = 256, 1008 .pc_ressize = 256, 1009 .pc_xdrressize = NFS4_CALLBACK_BUFSIZE, 1010 } 1011 }; 1012 1013 static unsigned int nfs4_callback_count1[ARRAY_SIZE(nfs4_callback_procedures1)]; 1014 const struct svc_version nfs4_callback_version1 = { 1015 .vs_vers = 1, 1016 .vs_nproc = ARRAY_SIZE(nfs4_callback_procedures1), 1017 .vs_proc = nfs4_callback_procedures1, 1018 .vs_count = nfs4_callback_count1, 1019 .vs_xdrsize = NFS4_CALLBACK_XDRSIZE, 1020 .vs_dispatch = NULL, 1021 .vs_hidden = true, 1022 .vs_need_cong_ctrl = true, 1023 }; 1024 1025 static unsigned int nfs4_callback_count4[ARRAY_SIZE(nfs4_callback_procedures1)]; 1026 const struct svc_version nfs4_callback_version4 = { 1027 .vs_vers = 4, 1028 .vs_nproc = ARRAY_SIZE(nfs4_callback_procedures1), 1029 .vs_proc = nfs4_callback_procedures1, 1030 .vs_count = nfs4_callback_count4, 1031 .vs_xdrsize = NFS4_CALLBACK_XDRSIZE, 1032 .vs_dispatch = NULL, 1033 .vs_hidden = true, 1034 .vs_need_cong_ctrl = true, 1035 }; 1036