1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * linux/fs/lockd/clnt4xdr.c 4 * 5 * XDR functions to encode/decode NLM version 4 RPC arguments and results. 6 * 7 * NLM client-side only. 8 * 9 * Copyright (C) 2010, Oracle. All rights reserved. 10 */ 11 12 #include <linux/types.h> 13 #include <linux/sunrpc/xdr.h> 14 #include <linux/sunrpc/clnt.h> 15 #include <linux/sunrpc/stats.h> 16 #include <linux/lockd/lockd.h> 17 18 #include <uapi/linux/nfs3.h> 19 20 #define NLMDBG_FACILITY NLMDBG_XDR 21 22 #if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ) 23 # error "NLM host name cannot be larger than XDR_MAX_NETOBJ!" 24 #endif 25 26 #if (NLMCLNT_OHSIZE > NLM_MAXSTRLEN) 27 # error "NLM host name cannot be larger than NLM's maximum string length!" 28 #endif 29 30 /* 31 * Declare the space requirements for NLM arguments and replies as 32 * number of 32bit-words 33 */ 34 #define NLM4_void_sz (0) 35 #define NLM4_cookie_sz (1+(NLM_MAXCOOKIELEN>>2)) 36 #define NLM4_caller_sz (1+(NLMCLNT_OHSIZE>>2)) 37 #define NLM4_owner_sz (1+(NLMCLNT_OHSIZE>>2)) 38 #define NLM4_fhandle_sz (1+(NFS3_FHSIZE>>2)) 39 #define NLM4_lock_sz (5+NLM4_caller_sz+NLM4_owner_sz+NLM4_fhandle_sz) 40 #define NLM4_holder_sz (6+NLM4_owner_sz) 41 42 #define NLM4_testargs_sz (NLM4_cookie_sz+1+NLM4_lock_sz) 43 #define NLM4_lockargs_sz (NLM4_cookie_sz+4+NLM4_lock_sz) 44 #define NLM4_cancargs_sz (NLM4_cookie_sz+2+NLM4_lock_sz) 45 #define NLM4_unlockargs_sz (NLM4_cookie_sz+NLM4_lock_sz) 46 47 #define NLM4_testres_sz (NLM4_cookie_sz+1+NLM4_holder_sz) 48 #define NLM4_res_sz (NLM4_cookie_sz+1) 49 #define NLM4_norep_sz (0) 50 51 52 static s64 loff_t_to_s64(loff_t offset) 53 { 54 s64 res; 55 56 if (offset >= NLM4_OFFSET_MAX) 57 res = NLM4_OFFSET_MAX; 58 else if (offset <= -NLM4_OFFSET_MAX) 59 res = -NLM4_OFFSET_MAX; 60 else 61 res = offset; 62 return res; 63 } 64 65 static void nlm4_compute_offsets(const struct nlm_lock *lock, 66 u64 *l_offset, u64 *l_len) 67 { 68 const struct file_lock *fl = &lock->fl; 69 70 *l_offset = loff_t_to_s64(fl->fl_start); 71 if (fl->fl_end == OFFSET_MAX) 72 *l_len = 0; 73 else 74 *l_len = loff_t_to_s64(fl->fl_end - fl->fl_start + 1); 75 } 76 77 /* 78 * Handle decode buffer overflows out-of-line. 79 */ 80 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) 81 { 82 dprintk("lockd: %s prematurely hit the end of our receive buffer. " 83 "Remaining buffer length is %tu words.\n", 84 func, xdr->end - xdr->p); 85 } 86 87 88 /* 89 * Encode/decode NLMv4 basic data types 90 * 91 * Basic NLMv4 data types are defined in Appendix II, section 6.1.4 92 * of RFC 1813: "NFS Version 3 Protocol Specification" and in Chapter 93 * 10 of X/Open's "Protocols for Interworking: XNFS, Version 3W". 94 * 95 * Not all basic data types have their own encoding and decoding 96 * functions. For run-time efficiency, some data types are encoded 97 * or decoded inline. 98 */ 99 100 static void encode_bool(struct xdr_stream *xdr, const int value) 101 { 102 __be32 *p; 103 104 p = xdr_reserve_space(xdr, 4); 105 *p = value ? xdr_one : xdr_zero; 106 } 107 108 static void encode_int32(struct xdr_stream *xdr, const s32 value) 109 { 110 __be32 *p; 111 112 p = xdr_reserve_space(xdr, 4); 113 *p = cpu_to_be32(value); 114 } 115 116 /* 117 * typedef opaque netobj<MAXNETOBJ_SZ> 118 */ 119 static void encode_netobj(struct xdr_stream *xdr, 120 const u8 *data, const unsigned int length) 121 { 122 __be32 *p; 123 124 p = xdr_reserve_space(xdr, 4 + length); 125 xdr_encode_opaque(p, data, length); 126 } 127 128 static int decode_netobj(struct xdr_stream *xdr, 129 struct xdr_netobj *obj) 130 { 131 u32 length; 132 __be32 *p; 133 134 p = xdr_inline_decode(xdr, 4); 135 if (unlikely(p == NULL)) 136 goto out_overflow; 137 length = be32_to_cpup(p++); 138 if (unlikely(length > XDR_MAX_NETOBJ)) 139 goto out_size; 140 obj->len = length; 141 obj->data = (u8 *)p; 142 return 0; 143 out_size: 144 dprintk("NFS: returned netobj was too long: %u\n", length); 145 return -EIO; 146 out_overflow: 147 print_overflow_msg(__func__, xdr); 148 return -EIO; 149 } 150 151 /* 152 * netobj cookie; 153 */ 154 static void encode_cookie(struct xdr_stream *xdr, 155 const struct nlm_cookie *cookie) 156 { 157 encode_netobj(xdr, (u8 *)&cookie->data, cookie->len); 158 } 159 160 static int decode_cookie(struct xdr_stream *xdr, 161 struct nlm_cookie *cookie) 162 { 163 u32 length; 164 __be32 *p; 165 166 p = xdr_inline_decode(xdr, 4); 167 if (unlikely(p == NULL)) 168 goto out_overflow; 169 length = be32_to_cpup(p++); 170 /* apparently HPUX can return empty cookies */ 171 if (length == 0) 172 goto out_hpux; 173 if (length > NLM_MAXCOOKIELEN) 174 goto out_size; 175 p = xdr_inline_decode(xdr, length); 176 if (unlikely(p == NULL)) 177 goto out_overflow; 178 cookie->len = length; 179 memcpy(cookie->data, p, length); 180 return 0; 181 out_hpux: 182 cookie->len = 4; 183 memset(cookie->data, 0, 4); 184 return 0; 185 out_size: 186 dprintk("NFS: returned cookie was too long: %u\n", length); 187 return -EIO; 188 out_overflow: 189 print_overflow_msg(__func__, xdr); 190 return -EIO; 191 } 192 193 /* 194 * netobj fh; 195 */ 196 static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh) 197 { 198 encode_netobj(xdr, (u8 *)&fh->data, fh->size); 199 } 200 201 /* 202 * enum nlm4_stats { 203 * NLM4_GRANTED = 0, 204 * NLM4_DENIED = 1, 205 * NLM4_DENIED_NOLOCKS = 2, 206 * NLM4_BLOCKED = 3, 207 * NLM4_DENIED_GRACE_PERIOD = 4, 208 * NLM4_DEADLCK = 5, 209 * NLM4_ROFS = 6, 210 * NLM4_STALE_FH = 7, 211 * NLM4_FBIG = 8, 212 * NLM4_FAILED = 9 213 * }; 214 * 215 * struct nlm4_stat { 216 * nlm4_stats stat; 217 * }; 218 * 219 * NB: we don't swap bytes for the NLM status values. The upper 220 * layers deal directly with the status value in network byte 221 * order. 222 */ 223 static void encode_nlm4_stat(struct xdr_stream *xdr, 224 const __be32 stat) 225 { 226 __be32 *p; 227 228 BUG_ON(be32_to_cpu(stat) > NLM_FAILED); 229 p = xdr_reserve_space(xdr, 4); 230 *p = stat; 231 } 232 233 static int decode_nlm4_stat(struct xdr_stream *xdr, __be32 *stat) 234 { 235 __be32 *p; 236 237 p = xdr_inline_decode(xdr, 4); 238 if (unlikely(p == NULL)) 239 goto out_overflow; 240 if (unlikely(ntohl(*p) > ntohl(nlm4_failed))) 241 goto out_bad_xdr; 242 *stat = *p; 243 return 0; 244 out_bad_xdr: 245 dprintk("%s: server returned invalid nlm4_stats value: %u\n", 246 __func__, be32_to_cpup(p)); 247 return -EIO; 248 out_overflow: 249 print_overflow_msg(__func__, xdr); 250 return -EIO; 251 } 252 253 /* 254 * struct nlm4_holder { 255 * bool exclusive; 256 * int32 svid; 257 * netobj oh; 258 * uint64 l_offset; 259 * uint64 l_len; 260 * }; 261 */ 262 static void encode_nlm4_holder(struct xdr_stream *xdr, 263 const struct nlm_res *result) 264 { 265 const struct nlm_lock *lock = &result->lock; 266 u64 l_offset, l_len; 267 __be32 *p; 268 269 encode_bool(xdr, lock->fl.fl_type == F_RDLCK); 270 encode_int32(xdr, lock->svid); 271 encode_netobj(xdr, lock->oh.data, lock->oh.len); 272 273 p = xdr_reserve_space(xdr, 4 + 4); 274 nlm4_compute_offsets(lock, &l_offset, &l_len); 275 p = xdr_encode_hyper(p, l_offset); 276 xdr_encode_hyper(p, l_len); 277 } 278 279 static int decode_nlm4_holder(struct xdr_stream *xdr, struct nlm_res *result) 280 { 281 struct nlm_lock *lock = &result->lock; 282 struct file_lock *fl = &lock->fl; 283 u64 l_offset, l_len; 284 u32 exclusive; 285 int error; 286 __be32 *p; 287 s32 end; 288 289 memset(lock, 0, sizeof(*lock)); 290 locks_init_lock(fl); 291 292 p = xdr_inline_decode(xdr, 4 + 4); 293 if (unlikely(p == NULL)) 294 goto out_overflow; 295 exclusive = be32_to_cpup(p++); 296 lock->svid = be32_to_cpup(p); 297 fl->fl_pid = (pid_t)lock->svid; 298 299 error = decode_netobj(xdr, &lock->oh); 300 if (unlikely(error)) 301 goto out; 302 303 p = xdr_inline_decode(xdr, 8 + 8); 304 if (unlikely(p == NULL)) 305 goto out_overflow; 306 307 fl->fl_flags = FL_POSIX; 308 fl->fl_type = exclusive != 0 ? F_WRLCK : F_RDLCK; 309 p = xdr_decode_hyper(p, &l_offset); 310 xdr_decode_hyper(p, &l_len); 311 end = l_offset + l_len - 1; 312 313 fl->fl_start = (loff_t)l_offset; 314 if (l_len == 0 || end < 0) 315 fl->fl_end = OFFSET_MAX; 316 else 317 fl->fl_end = (loff_t)end; 318 error = 0; 319 out: 320 return error; 321 out_overflow: 322 print_overflow_msg(__func__, xdr); 323 return -EIO; 324 } 325 326 /* 327 * string caller_name<LM_MAXSTRLEN>; 328 */ 329 static void encode_caller_name(struct xdr_stream *xdr, const char *name) 330 { 331 /* NB: client-side does not set lock->len */ 332 u32 length = strlen(name); 333 __be32 *p; 334 335 p = xdr_reserve_space(xdr, 4 + length); 336 xdr_encode_opaque(p, name, length); 337 } 338 339 /* 340 * struct nlm4_lock { 341 * string caller_name<LM_MAXSTRLEN>; 342 * netobj fh; 343 * netobj oh; 344 * int32 svid; 345 * uint64 l_offset; 346 * uint64 l_len; 347 * }; 348 */ 349 static void encode_nlm4_lock(struct xdr_stream *xdr, 350 const struct nlm_lock *lock) 351 { 352 u64 l_offset, l_len; 353 __be32 *p; 354 355 encode_caller_name(xdr, lock->caller); 356 encode_fh(xdr, &lock->fh); 357 encode_netobj(xdr, lock->oh.data, lock->oh.len); 358 359 p = xdr_reserve_space(xdr, 4 + 8 + 8); 360 *p++ = cpu_to_be32(lock->svid); 361 362 nlm4_compute_offsets(lock, &l_offset, &l_len); 363 p = xdr_encode_hyper(p, l_offset); 364 xdr_encode_hyper(p, l_len); 365 } 366 367 368 /* 369 * NLMv4 XDR encode functions 370 * 371 * NLMv4 argument types are defined in Appendix II of RFC 1813: 372 * "NFS Version 3 Protocol Specification" and Chapter 10 of X/Open's 373 * "Protocols for Interworking: XNFS, Version 3W". 374 */ 375 376 /* 377 * struct nlm4_testargs { 378 * netobj cookie; 379 * bool exclusive; 380 * struct nlm4_lock alock; 381 * }; 382 */ 383 static void nlm4_xdr_enc_testargs(struct rpc_rqst *req, 384 struct xdr_stream *xdr, 385 const void *data) 386 { 387 const struct nlm_args *args = data; 388 const struct nlm_lock *lock = &args->lock; 389 390 encode_cookie(xdr, &args->cookie); 391 encode_bool(xdr, lock->fl.fl_type == F_WRLCK); 392 encode_nlm4_lock(xdr, lock); 393 } 394 395 /* 396 * struct nlm4_lockargs { 397 * netobj cookie; 398 * bool block; 399 * bool exclusive; 400 * struct nlm4_lock alock; 401 * bool reclaim; 402 * int state; 403 * }; 404 */ 405 static void nlm4_xdr_enc_lockargs(struct rpc_rqst *req, 406 struct xdr_stream *xdr, 407 const void *data) 408 { 409 const struct nlm_args *args = data; 410 const struct nlm_lock *lock = &args->lock; 411 412 encode_cookie(xdr, &args->cookie); 413 encode_bool(xdr, args->block); 414 encode_bool(xdr, lock->fl.fl_type == F_WRLCK); 415 encode_nlm4_lock(xdr, lock); 416 encode_bool(xdr, args->reclaim); 417 encode_int32(xdr, args->state); 418 } 419 420 /* 421 * struct nlm4_cancargs { 422 * netobj cookie; 423 * bool block; 424 * bool exclusive; 425 * struct nlm4_lock alock; 426 * }; 427 */ 428 static void nlm4_xdr_enc_cancargs(struct rpc_rqst *req, 429 struct xdr_stream *xdr, 430 const void *data) 431 { 432 const struct nlm_args *args = data; 433 const struct nlm_lock *lock = &args->lock; 434 435 encode_cookie(xdr, &args->cookie); 436 encode_bool(xdr, args->block); 437 encode_bool(xdr, lock->fl.fl_type == F_WRLCK); 438 encode_nlm4_lock(xdr, lock); 439 } 440 441 /* 442 * struct nlm4_unlockargs { 443 * netobj cookie; 444 * struct nlm4_lock alock; 445 * }; 446 */ 447 static void nlm4_xdr_enc_unlockargs(struct rpc_rqst *req, 448 struct xdr_stream *xdr, 449 const void *data) 450 { 451 const struct nlm_args *args = data; 452 const struct nlm_lock *lock = &args->lock; 453 454 encode_cookie(xdr, &args->cookie); 455 encode_nlm4_lock(xdr, lock); 456 } 457 458 /* 459 * struct nlm4_res { 460 * netobj cookie; 461 * nlm4_stat stat; 462 * }; 463 */ 464 static void nlm4_xdr_enc_res(struct rpc_rqst *req, 465 struct xdr_stream *xdr, 466 const void *data) 467 { 468 const struct nlm_res *result = data; 469 470 encode_cookie(xdr, &result->cookie); 471 encode_nlm4_stat(xdr, result->status); 472 } 473 474 /* 475 * union nlm4_testrply switch (nlm4_stats stat) { 476 * case NLM4_DENIED: 477 * struct nlm4_holder holder; 478 * default: 479 * void; 480 * }; 481 * 482 * struct nlm4_testres { 483 * netobj cookie; 484 * nlm4_testrply test_stat; 485 * }; 486 */ 487 static void nlm4_xdr_enc_testres(struct rpc_rqst *req, 488 struct xdr_stream *xdr, 489 const void *data) 490 { 491 const struct nlm_res *result = data; 492 493 encode_cookie(xdr, &result->cookie); 494 encode_nlm4_stat(xdr, result->status); 495 if (result->status == nlm_lck_denied) 496 encode_nlm4_holder(xdr, result); 497 } 498 499 500 /* 501 * NLMv4 XDR decode functions 502 * 503 * NLMv4 argument types are defined in Appendix II of RFC 1813: 504 * "NFS Version 3 Protocol Specification" and Chapter 10 of X/Open's 505 * "Protocols for Interworking: XNFS, Version 3W". 506 */ 507 508 /* 509 * union nlm4_testrply switch (nlm4_stats stat) { 510 * case NLM4_DENIED: 511 * struct nlm4_holder holder; 512 * default: 513 * void; 514 * }; 515 * 516 * struct nlm4_testres { 517 * netobj cookie; 518 * nlm4_testrply test_stat; 519 * }; 520 */ 521 static int decode_nlm4_testrply(struct xdr_stream *xdr, 522 struct nlm_res *result) 523 { 524 int error; 525 526 error = decode_nlm4_stat(xdr, &result->status); 527 if (unlikely(error)) 528 goto out; 529 if (result->status == nlm_lck_denied) 530 error = decode_nlm4_holder(xdr, result); 531 out: 532 return error; 533 } 534 535 static int nlm4_xdr_dec_testres(struct rpc_rqst *req, 536 struct xdr_stream *xdr, 537 void *data) 538 { 539 struct nlm_res *result = data; 540 int error; 541 542 error = decode_cookie(xdr, &result->cookie); 543 if (unlikely(error)) 544 goto out; 545 error = decode_nlm4_testrply(xdr, result); 546 out: 547 return error; 548 } 549 550 /* 551 * struct nlm4_res { 552 * netobj cookie; 553 * nlm4_stat stat; 554 * }; 555 */ 556 static int nlm4_xdr_dec_res(struct rpc_rqst *req, 557 struct xdr_stream *xdr, 558 void *data) 559 { 560 struct nlm_res *result = data; 561 int error; 562 563 error = decode_cookie(xdr, &result->cookie); 564 if (unlikely(error)) 565 goto out; 566 error = decode_nlm4_stat(xdr, &result->status); 567 out: 568 return error; 569 } 570 571 572 /* 573 * For NLM, a void procedure really returns nothing 574 */ 575 #define nlm4_xdr_dec_norep NULL 576 577 #define PROC(proc, argtype, restype) \ 578 [NLMPROC_##proc] = { \ 579 .p_proc = NLMPROC_##proc, \ 580 .p_encode = nlm4_xdr_enc_##argtype, \ 581 .p_decode = nlm4_xdr_dec_##restype, \ 582 .p_arglen = NLM4_##argtype##_sz, \ 583 .p_replen = NLM4_##restype##_sz, \ 584 .p_statidx = NLMPROC_##proc, \ 585 .p_name = #proc, \ 586 } 587 588 static const struct rpc_procinfo nlm4_procedures[] = { 589 PROC(TEST, testargs, testres), 590 PROC(LOCK, lockargs, res), 591 PROC(CANCEL, cancargs, res), 592 PROC(UNLOCK, unlockargs, res), 593 PROC(GRANTED, testargs, res), 594 PROC(TEST_MSG, testargs, norep), 595 PROC(LOCK_MSG, lockargs, norep), 596 PROC(CANCEL_MSG, cancargs, norep), 597 PROC(UNLOCK_MSG, unlockargs, norep), 598 PROC(GRANTED_MSG, testargs, norep), 599 PROC(TEST_RES, testres, norep), 600 PROC(LOCK_RES, res, norep), 601 PROC(CANCEL_RES, res, norep), 602 PROC(UNLOCK_RES, res, norep), 603 PROC(GRANTED_RES, res, norep), 604 }; 605 606 static unsigned int nlm_version4_counts[ARRAY_SIZE(nlm4_procedures)]; 607 const struct rpc_version nlm_version4 = { 608 .number = 4, 609 .nrprocs = ARRAY_SIZE(nlm4_procedures), 610 .procs = nlm4_procedures, 611 .counts = nlm_version4_counts, 612 }; 613