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