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