clntxdr.c 13 KB

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