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