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