diag_uid.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright Amazon.com Inc. or its affiliates. */
  3. #define _GNU_SOURCE
  4. #include <sched.h>
  5. #include <unistd.h>
  6. #include <linux/netlink.h>
  7. #include <linux/rtnetlink.h>
  8. #include <linux/sock_diag.h>
  9. #include <linux/unix_diag.h>
  10. #include <sys/socket.h>
  11. #include <sys/stat.h>
  12. #include <sys/types.h>
  13. #include <sys/un.h>
  14. #include "kselftest_harness.h"
  15. FIXTURE(diag_uid)
  16. {
  17. int netlink_fd;
  18. int unix_fd;
  19. __u32 inode;
  20. __u64 cookie;
  21. };
  22. FIXTURE_VARIANT(diag_uid)
  23. {
  24. int unshare;
  25. int udiag_show;
  26. };
  27. FIXTURE_VARIANT_ADD(diag_uid, uid)
  28. {
  29. .unshare = 0,
  30. .udiag_show = UDIAG_SHOW_UID
  31. };
  32. FIXTURE_VARIANT_ADD(diag_uid, uid_unshare)
  33. {
  34. .unshare = CLONE_NEWUSER,
  35. .udiag_show = UDIAG_SHOW_UID
  36. };
  37. FIXTURE_SETUP(diag_uid)
  38. {
  39. struct stat file_stat;
  40. socklen_t optlen;
  41. int ret;
  42. if (variant->unshare)
  43. ASSERT_EQ(unshare(variant->unshare), 0);
  44. self->netlink_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
  45. ASSERT_NE(self->netlink_fd, -1);
  46. self->unix_fd = socket(AF_UNIX, SOCK_STREAM, 0);
  47. ASSERT_NE(self->unix_fd, -1);
  48. ret = fstat(self->unix_fd, &file_stat);
  49. ASSERT_EQ(ret, 0);
  50. self->inode = file_stat.st_ino;
  51. optlen = sizeof(self->cookie);
  52. ret = getsockopt(self->unix_fd, SOL_SOCKET, SO_COOKIE, &self->cookie, &optlen);
  53. ASSERT_EQ(ret, 0);
  54. }
  55. FIXTURE_TEARDOWN(diag_uid)
  56. {
  57. close(self->netlink_fd);
  58. close(self->unix_fd);
  59. }
  60. int send_request(struct __test_metadata *_metadata,
  61. FIXTURE_DATA(diag_uid) *self,
  62. const FIXTURE_VARIANT(diag_uid) *variant)
  63. {
  64. struct {
  65. struct nlmsghdr nlh;
  66. struct unix_diag_req udr;
  67. } req = {
  68. .nlh = {
  69. .nlmsg_len = sizeof(req),
  70. .nlmsg_type = SOCK_DIAG_BY_FAMILY,
  71. .nlmsg_flags = NLM_F_REQUEST
  72. },
  73. .udr = {
  74. .sdiag_family = AF_UNIX,
  75. .udiag_ino = self->inode,
  76. .udiag_cookie = {
  77. (__u32)self->cookie,
  78. (__u32)(self->cookie >> 32)
  79. },
  80. .udiag_show = variant->udiag_show
  81. }
  82. };
  83. struct sockaddr_nl nladdr = {
  84. .nl_family = AF_NETLINK
  85. };
  86. struct iovec iov = {
  87. .iov_base = &req,
  88. .iov_len = sizeof(req)
  89. };
  90. struct msghdr msg = {
  91. .msg_name = &nladdr,
  92. .msg_namelen = sizeof(nladdr),
  93. .msg_iov = &iov,
  94. .msg_iovlen = 1
  95. };
  96. return sendmsg(self->netlink_fd, &msg, 0);
  97. }
  98. void render_response(struct __test_metadata *_metadata,
  99. struct unix_diag_req *udr, __u32 len)
  100. {
  101. unsigned int rta_len = len - NLMSG_LENGTH(sizeof(*udr));
  102. struct rtattr *attr;
  103. uid_t uid;
  104. ASSERT_GT(len, sizeof(*udr));
  105. ASSERT_EQ(udr->sdiag_family, AF_UNIX);
  106. attr = (struct rtattr *)(udr + 1);
  107. ASSERT_NE(RTA_OK(attr, rta_len), 0);
  108. ASSERT_EQ(attr->rta_type, UNIX_DIAG_UID);
  109. uid = *(uid_t *)RTA_DATA(attr);
  110. ASSERT_EQ(uid, getuid());
  111. }
  112. void receive_response(struct __test_metadata *_metadata,
  113. FIXTURE_DATA(diag_uid) *self)
  114. {
  115. long buf[8192 / sizeof(long)];
  116. struct sockaddr_nl nladdr = {
  117. .nl_family = AF_NETLINK
  118. };
  119. struct iovec iov = {
  120. .iov_base = buf,
  121. .iov_len = sizeof(buf)
  122. };
  123. struct msghdr msg = {
  124. .msg_name = &nladdr,
  125. .msg_namelen = sizeof(nladdr),
  126. .msg_iov = &iov,
  127. .msg_iovlen = 1
  128. };
  129. struct nlmsghdr *nlh;
  130. int ret;
  131. ret = recvmsg(self->netlink_fd, &msg, 0);
  132. ASSERT_GT(ret, 0);
  133. nlh = (struct nlmsghdr *)buf;
  134. ASSERT_NE(NLMSG_OK(nlh, ret), 0);
  135. ASSERT_EQ(nlh->nlmsg_type, SOCK_DIAG_BY_FAMILY);
  136. render_response(_metadata, NLMSG_DATA(nlh), nlh->nlmsg_len);
  137. nlh = NLMSG_NEXT(nlh, ret);
  138. ASSERT_EQ(NLMSG_OK(nlh, ret), 0);
  139. }
  140. TEST_F(diag_uid, 1)
  141. {
  142. int ret;
  143. ret = send_request(_metadata, self, variant);
  144. ASSERT_GT(ret, 0);
  145. receive_response(_metadata, self);
  146. }
  147. TEST_HARNESS_MAIN