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 ssize_t ret; 129 130 ret = xdr_stream_decode_opaque_inline(xdr, (void *)&obj->data, 131 XDR_MAX_NETOBJ); 132 if (unlikely(ret < 0)) 133 return -EIO; 134 obj->len = ret; 135 return 0; 136 } 137 138 /* 139 * netobj cookie; 140 */ 141 static void encode_cookie(struct xdr_stream *xdr, 142 const struct nlm_cookie *cookie) 143 { 144 encode_netobj(xdr, (u8 *)&cookie->data, cookie->len); 145 } 146 147 static int decode_cookie(struct xdr_stream *xdr, 148 struct nlm_cookie *cookie) 149 { 150 u32 length; 151 __be32 *p; 152 153 p = xdr_inline_decode(xdr, 4); 154 if (unlikely(p == NULL)) 155 goto out_overflow; 156 length = be32_to_cpup(p++); 157 /* apparently HPUX can return empty cookies */ 158 if (length == 0) 159 goto out_hpux; 160 if (length > NLM_MAXCOOKIELEN) 161 goto out_size; 162 p = xdr_inline_decode(xdr, length); 163 if (unlikely(p == NULL)) 164 goto out_overflow; 165 cookie->len = length; 166 memcpy(cookie->data, p, length); 167 return 0; 168 out_hpux: 169 cookie->len = 4; 170 memset(cookie->data, 0, 4); 171 return 0; 172 out_size: 173 dprintk("NFS: returned cookie was too long: %u\n", length); 174 return -EIO; 175 out_overflow: 176 print_overflow_msg(__func__, xdr); 177 return -EIO; 178 } 179 180 /* 181 * netobj fh; 182 */ 183 static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh) 184 { 185 encode_netobj(xdr, (u8 *)&fh->data, NFS2_FHSIZE); 186 } 187 188 /* 189 * enum nlm_stats { 190 * LCK_GRANTED = 0, 191 * LCK_DENIED = 1, 192 * LCK_DENIED_NOLOCKS = 2, 193 * LCK_BLOCKED = 3, 194 * LCK_DENIED_GRACE_PERIOD = 4 195 * }; 196 * 197 * 198 * struct nlm_stat { 199 * nlm_stats stat; 200 * }; 201 * 202 * NB: we don't swap bytes for the NLM status values. The upper 203 * layers deal directly with the status value in network byte 204 * order. 205 */ 206 207 static void encode_nlm_stat(struct xdr_stream *xdr, 208 const __be32 stat) 209 { 210 __be32 *p; 211 212 WARN_ON_ONCE(be32_to_cpu(stat) > NLM_LCK_DENIED_GRACE_PERIOD); 213 p = xdr_reserve_space(xdr, 4); 214 *p = stat; 215 } 216 217 static int decode_nlm_stat(struct xdr_stream *xdr, 218 __be32 *stat) 219 { 220 __be32 *p; 221 222 p = xdr_inline_decode(xdr, 4); 223 if (unlikely(p == NULL)) 224 goto out_overflow; 225 if (unlikely(ntohl(*p) > ntohl(nlm_lck_denied_grace_period))) 226 goto out_enum; 227 *stat = *p; 228 return 0; 229 out_enum: 230 dprintk("%s: server returned invalid nlm_stats value: %u\n", 231 __func__, be32_to_cpup(p)); 232 return -EIO; 233 out_overflow: 234 print_overflow_msg(__func__, xdr); 235 return -EIO; 236 } 237 238 /* 239 * struct nlm_holder { 240 * bool exclusive; 241 * int uppid; 242 * netobj oh; 243 * unsigned l_offset; 244 * unsigned l_len; 245 * }; 246 */ 247 static void encode_nlm_holder(struct xdr_stream *xdr, 248 const struct nlm_res *result) 249 { 250 const struct nlm_lock *lock = &result->lock; 251 u32 l_offset, l_len; 252 __be32 *p; 253 254 encode_bool(xdr, lock->fl.fl_type == F_RDLCK); 255 encode_int32(xdr, lock->svid); 256 encode_netobj(xdr, lock->oh.data, lock->oh.len); 257 258 p = xdr_reserve_space(xdr, 4 + 4); 259 nlm_compute_offsets(lock, &l_offset, &l_len); 260 *p++ = cpu_to_be32(l_offset); 261 *p = cpu_to_be32(l_len); 262 } 263 264 static int decode_nlm_holder(struct xdr_stream *xdr, struct nlm_res *result) 265 { 266 struct nlm_lock *lock = &result->lock; 267 struct file_lock *fl = &lock->fl; 268 u32 exclusive, l_offset, l_len; 269 int error; 270 __be32 *p; 271 s32 end; 272 273 memset(lock, 0, sizeof(*lock)); 274 locks_init_lock(fl); 275 276 p = xdr_inline_decode(xdr, 4 + 4); 277 if (unlikely(p == NULL)) 278 goto out_overflow; 279 exclusive = be32_to_cpup(p++); 280 lock->svid = be32_to_cpup(p); 281 fl->fl_pid = (pid_t)lock->svid; 282 283 error = decode_netobj(xdr, &lock->oh); 284 if (unlikely(error)) 285 goto out; 286 287 p = xdr_inline_decode(xdr, 4 + 4); 288 if (unlikely(p == NULL)) 289 goto out_overflow; 290 291 fl->fl_flags = FL_POSIX; 292 fl->fl_type = exclusive != 0 ? F_WRLCK : F_RDLCK; 293 l_offset = be32_to_cpup(p++); 294 l_len = be32_to_cpup(p); 295 end = l_offset + l_len - 1; 296 297 fl->fl_start = (loff_t)l_offset; 298 if (l_len == 0 || end < 0) 299 fl->fl_end = OFFSET_MAX; 300 else 301 fl->fl_end = (loff_t)end; 302 error = 0; 303 out: 304 return error; 305 out_overflow: 306 print_overflow_msg(__func__, xdr); 307 return -EIO; 308 } 309 310 /* 311 * string caller_name<LM_MAXSTRLEN>; 312 */ 313 static void encode_caller_name(struct xdr_stream *xdr, const char *name) 314 { 315 /* NB: client-side does not set lock->len */ 316 u32 length = strlen(name); 317 __be32 *p; 318 319 p = xdr_reserve_space(xdr, 4 + length); 320 xdr_encode_opaque(p, name, length); 321 } 322 323 /* 324 * struct nlm_lock { 325 * string caller_name<LM_MAXSTRLEN>; 326 * netobj fh; 327 * netobj oh; 328 * int uppid; 329 * unsigned l_offset; 330 * unsigned l_len; 331 * }; 332 */ 333 static void encode_nlm_lock(struct xdr_stream *xdr, 334 const struct nlm_lock *lock) 335 { 336 u32 l_offset, l_len; 337 __be32 *p; 338 339 encode_caller_name(xdr, lock->caller); 340 encode_fh(xdr, &lock->fh); 341 encode_netobj(xdr, lock->oh.data, lock->oh.len); 342 343 p = xdr_reserve_space(xdr, 4 + 4 + 4); 344 *p++ = cpu_to_be32(lock->svid); 345 346 nlm_compute_offsets(lock, &l_offset, &l_len); 347 *p++ = cpu_to_be32(l_offset); 348 *p = cpu_to_be32(l_len); 349 } 350 351 352 /* 353 * NLMv3 XDR encode functions 354 * 355 * NLMv3 argument types are defined in Chapter 10 of The Open Group's 356 * "Protocols for Interworking: XNFS, Version 3W". 357 */ 358 359 /* 360 * struct nlm_testargs { 361 * netobj cookie; 362 * bool exclusive; 363 * struct nlm_lock alock; 364 * }; 365 */ 366 static void nlm_xdr_enc_testargs(struct rpc_rqst *req, 367 struct xdr_stream *xdr, 368 const void *data) 369 { 370 const struct nlm_args *args = data; 371 const struct nlm_lock *lock = &args->lock; 372 373 encode_cookie(xdr, &args->cookie); 374 encode_bool(xdr, lock->fl.fl_type == F_WRLCK); 375 encode_nlm_lock(xdr, lock); 376 } 377 378 /* 379 * struct nlm_lockargs { 380 * netobj cookie; 381 * bool block; 382 * bool exclusive; 383 * struct nlm_lock alock; 384 * bool reclaim; 385 * int state; 386 * }; 387 */ 388 static void nlm_xdr_enc_lockargs(struct rpc_rqst *req, 389 struct xdr_stream *xdr, 390 const void *data) 391 { 392 const struct nlm_args *args = data; 393 const struct nlm_lock *lock = &args->lock; 394 395 encode_cookie(xdr, &args->cookie); 396 encode_bool(xdr, args->block); 397 encode_bool(xdr, lock->fl.fl_type == F_WRLCK); 398 encode_nlm_lock(xdr, lock); 399 encode_bool(xdr, args->reclaim); 400 encode_int32(xdr, args->state); 401 } 402 403 /* 404 * struct nlm_cancargs { 405 * netobj cookie; 406 * bool block; 407 * bool exclusive; 408 * struct nlm_lock alock; 409 * }; 410 */ 411 static void nlm_xdr_enc_cancargs(struct rpc_rqst *req, 412 struct xdr_stream *xdr, 413 const void *data) 414 { 415 const struct nlm_args *args = data; 416 const struct nlm_lock *lock = &args->lock; 417 418 encode_cookie(xdr, &args->cookie); 419 encode_bool(xdr, args->block); 420 encode_bool(xdr, lock->fl.fl_type == F_WRLCK); 421 encode_nlm_lock(xdr, lock); 422 } 423 424 /* 425 * struct nlm_unlockargs { 426 * netobj cookie; 427 * struct nlm_lock alock; 428 * }; 429 */ 430 static void nlm_xdr_enc_unlockargs(struct rpc_rqst *req, 431 struct xdr_stream *xdr, 432 const void *data) 433 { 434 const struct nlm_args *args = data; 435 const struct nlm_lock *lock = &args->lock; 436 437 encode_cookie(xdr, &args->cookie); 438 encode_nlm_lock(xdr, lock); 439 } 440 441 /* 442 * struct nlm_res { 443 * netobj cookie; 444 * nlm_stat stat; 445 * }; 446 */ 447 static void nlm_xdr_enc_res(struct rpc_rqst *req, 448 struct xdr_stream *xdr, 449 const void *data) 450 { 451 const struct nlm_res *result = data; 452 453 encode_cookie(xdr, &result->cookie); 454 encode_nlm_stat(xdr, result->status); 455 } 456 457 /* 458 * union nlm_testrply switch (nlm_stats stat) { 459 * case LCK_DENIED: 460 * struct nlm_holder holder; 461 * default: 462 * void; 463 * }; 464 * 465 * struct nlm_testres { 466 * netobj cookie; 467 * nlm_testrply test_stat; 468 * }; 469 */ 470 static void encode_nlm_testrply(struct xdr_stream *xdr, 471 const struct nlm_res *result) 472 { 473 if (result->status == nlm_lck_denied) 474 encode_nlm_holder(xdr, result); 475 } 476 477 static void nlm_xdr_enc_testres(struct rpc_rqst *req, 478 struct xdr_stream *xdr, 479 const void *data) 480 { 481 const struct nlm_res *result = data; 482 483 encode_cookie(xdr, &result->cookie); 484 encode_nlm_stat(xdr, result->status); 485 encode_nlm_testrply(xdr, result); 486 } 487 488 489 /* 490 * NLMv3 XDR decode functions 491 * 492 * NLMv3 result types are defined in Chapter 10 of The Open Group's 493 * "Protocols for Interworking: XNFS, Version 3W". 494 */ 495 496 /* 497 * union nlm_testrply switch (nlm_stats stat) { 498 * case LCK_DENIED: 499 * struct nlm_holder holder; 500 * default: 501 * void; 502 * }; 503 * 504 * struct nlm_testres { 505 * netobj cookie; 506 * nlm_testrply test_stat; 507 * }; 508 */ 509 static int decode_nlm_testrply(struct xdr_stream *xdr, 510 struct nlm_res *result) 511 { 512 int error; 513 514 error = decode_nlm_stat(xdr, &result->status); 515 if (unlikely(error)) 516 goto out; 517 if (result->status == nlm_lck_denied) 518 error = decode_nlm_holder(xdr, result); 519 out: 520 return error; 521 } 522 523 static int nlm_xdr_dec_testres(struct rpc_rqst *req, 524 struct xdr_stream *xdr, 525 void *data) 526 { 527 struct nlm_res *result = data; 528 int error; 529 530 error = decode_cookie(xdr, &result->cookie); 531 if (unlikely(error)) 532 goto out; 533 error = decode_nlm_testrply(xdr, result); 534 out: 535 return error; 536 } 537 538 /* 539 * struct nlm_res { 540 * netobj cookie; 541 * nlm_stat stat; 542 * }; 543 */ 544 static int nlm_xdr_dec_res(struct rpc_rqst *req, 545 struct xdr_stream *xdr, 546 void *data) 547 { 548 struct nlm_res *result = data; 549 int error; 550 551 error = decode_cookie(xdr, &result->cookie); 552 if (unlikely(error)) 553 goto out; 554 error = decode_nlm_stat(xdr, &result->status); 555 out: 556 return error; 557 } 558 559 560 /* 561 * For NLM, a void procedure really returns nothing 562 */ 563 #define nlm_xdr_dec_norep NULL 564 565 #define PROC(proc, argtype, restype) \ 566 [NLMPROC_##proc] = { \ 567 .p_proc = NLMPROC_##proc, \ 568 .p_encode = nlm_xdr_enc_##argtype, \ 569 .p_decode = nlm_xdr_dec_##restype, \ 570 .p_arglen = NLM_##argtype##_sz, \ 571 .p_replen = NLM_##restype##_sz, \ 572 .p_statidx = NLMPROC_##proc, \ 573 .p_name = #proc, \ 574 } 575 576 static const struct rpc_procinfo nlm_procedures[] = { 577 PROC(TEST, testargs, testres), 578 PROC(LOCK, lockargs, res), 579 PROC(CANCEL, cancargs, res), 580 PROC(UNLOCK, unlockargs, res), 581 PROC(GRANTED, testargs, res), 582 PROC(TEST_MSG, testargs, norep), 583 PROC(LOCK_MSG, lockargs, norep), 584 PROC(CANCEL_MSG, cancargs, norep), 585 PROC(UNLOCK_MSG, unlockargs, norep), 586 PROC(GRANTED_MSG, testargs, norep), 587 PROC(TEST_RES, testres, norep), 588 PROC(LOCK_RES, res, norep), 589 PROC(CANCEL_RES, res, norep), 590 PROC(UNLOCK_RES, res, norep), 591 PROC(GRANTED_RES, res, norep), 592 }; 593 594 static unsigned int nlm_version1_counts[ARRAY_SIZE(nlm_procedures)]; 595 static const struct rpc_version nlm_version1 = { 596 .number = 1, 597 .nrprocs = ARRAY_SIZE(nlm_procedures), 598 .procs = nlm_procedures, 599 .counts = nlm_version1_counts, 600 }; 601 602 static unsigned int nlm_version3_counts[ARRAY_SIZE(nlm_procedures)]; 603 static const struct rpc_version nlm_version3 = { 604 .number = 3, 605 .nrprocs = ARRAY_SIZE(nlm_procedures), 606 .procs = nlm_procedures, 607 .counts = nlm_version3_counts, 608 }; 609 610 static const struct rpc_version *nlm_versions[] = { 611 [1] = &nlm_version1, 612 [3] = &nlm_version3, 613 #ifdef CONFIG_LOCKD_V4 614 [4] = &nlm_version4, 615 #endif 616 }; 617 618 static struct rpc_stat nlm_rpc_stats; 619 620 const struct rpc_program nlm_program = { 621 .name = "lockd", 622 .number = NLM_PROGRAM, 623 .nrvers = ARRAY_SIZE(nlm_versions), 624 .version = nlm_versions, 625 .stats = &nlm_rpc_stats, 626 }; 627