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