sandbox-2.6-check-empty-paths-at.patch 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. From dd726dcc6a95355d0e0cc949018d9c8aefc89a02 Mon Sep 17 00:00:00 2001
  2. From: Mike Frysinger <vapier@gentoo.org>
  3. Date: Mon, 24 Dec 2012 19:41:49 -0500
  4. Subject: [PATCH 1/2] libsandbox: reject "" paths with *at funcs before
  5. checking the dirfd
  6. When it comes to processing errors, an empty path is checked before
  7. an invalid dirfd. Make sure sandbox matches that behavior for the
  8. random testsuites out there that look for this.
  9. URL: https://bugs.gentoo.org/346929
  10. Reported-by: Marien Zwart <marienz@gentoo.org>
  11. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
  12. ---
  13. libsandbox/wrapper-funcs/__pre_check.c | 2 ++
  14. libsandbox/wrapper-funcs/mkdirat_pre_check.c | 17 +++++------------
  15. libsandbox/wrapper-funcs/openat_pre_check.c | 15 ++++-----------
  16. libsandbox/wrapper-funcs/unlinkat_pre_check.c | 17 +++++------------
  17. libsandbox/wrappers.h | 2 ++
  18. tests/mkdirat-3.sh | 7 +++++++
  19. tests/mkdirat.at | 1 +
  20. tests/openat-2.sh | 9 +++++++++
  21. tests/openat.at | 1 +
  22. tests/unlinkat-4.sh | 7 +++++++
  23. tests/unlinkat.at | 1 +
  24. 11 files changed, 44 insertions(+), 35 deletions(-)
  25. create mode 100755 tests/mkdirat-3.sh
  26. create mode 100755 tests/openat-2.sh
  27. create mode 100755 tests/unlinkat-4.sh
  28. diff --git a/libsandbox/wrapper-funcs/__pre_check.c b/libsandbox/wrapper-funcs/__pre_check.c
  29. index 2d5711f..28ad91f 100644
  30. --- a/libsandbox/wrapper-funcs/__pre_check.c
  31. +++ b/libsandbox/wrapper-funcs/__pre_check.c
  32. @@ -20,3 +20,5 @@
  33. #if SB_NR_UNLINK != SB_NR_UNDEF && SB_NR_UNLINKAT == SB_NR_UNDEF
  34. # include "unlinkat_pre_check.c"
  35. #endif
  36. +
  37. +#include "__pre_at_check.c"
  38. diff --git a/libsandbox/wrapper-funcs/mkdirat_pre_check.c b/libsandbox/wrapper-funcs/mkdirat_pre_check.c
  39. index 77a65df..0b48d1f 100644
  40. --- a/libsandbox/wrapper-funcs/mkdirat_pre_check.c
  41. +++ b/libsandbox/wrapper-funcs/mkdirat_pre_check.c
  42. @@ -1,20 +1,13 @@
  43. bool sb_mkdirat_pre_check(const char *func, const char *pathname, int dirfd)
  44. {
  45. char canonic[SB_PATH_MAX];
  46. - char dirfd_path[SB_PATH_MAX];
  47. save_errno();
  48. - /* Expand the dirfd path first */
  49. - switch (resolve_dirfd_path(dirfd, pathname, dirfd_path, sizeof(dirfd_path))) {
  50. - case -1:
  51. - sb_debug_dyn("EARLY FAIL: %s(%s) @ resolve_dirfd_path: %s\n",
  52. - func, pathname, strerror(errno));
  53. - return false;
  54. - case 0:
  55. - pathname = dirfd_path;
  56. - break;
  57. - }
  58. + /* Check incoming args against common *at issues */
  59. + char dirfd_path[SB_PATH_MAX];
  60. + if (!sb_common_at_pre_check(func, &pathname, dirfd, dirfd_path, sizeof(dirfd_path)))
  61. + return false;
  62. /* Then break down any relative/symlink paths */
  63. if (-1 == canonicalize(pathname, canonic))
  64. diff --git a/libsandbox/wrapper-funcs/openat_pre_check.c b/libsandbox/wrapper-funcs/openat_pre_check.c
  65. index 0127708..5fd5eaa 100644
  66. --- a/libsandbox/wrapper-funcs/openat_pre_check.c
  67. +++ b/libsandbox/wrapper-funcs/openat_pre_check.c
  68. @@ -15,17 +15,10 @@ bool sb_openat_pre_check(const char *func, const char *pathname, int dirfd, int
  69. save_errno();
  70. - /* Expand the dirfd path first */
  71. + /* Check incoming args against common *at issues */
  72. char dirfd_path[SB_PATH_MAX];
  73. - switch (resolve_dirfd_path(dirfd, pathname, dirfd_path, sizeof(dirfd_path))) {
  74. - case -1:
  75. - sb_debug_dyn("EARLY FAIL: %s(%s) @ resolve_dirfd_path: %s\n",
  76. - func, pathname, strerror(errno));
  77. - return false;
  78. - case 0:
  79. - pathname = dirfd_path;
  80. - break;
  81. - }
  82. + if (!sb_common_at_pre_check(func, &pathname, dirfd, dirfd_path, sizeof(dirfd_path)))
  83. + return false;
  84. /* Doesn't exist -> skip permission checks */
  85. struct stat st;
  86. diff --git a/libsandbox/wrapper-funcs/unlinkat_pre_check.c b/libsandbox/wrapper-funcs/unlinkat_pre_check.c
  87. index 9f5e7d7..c004d15 100644
  88. --- a/libsandbox/wrapper-funcs/unlinkat_pre_check.c
  89. +++ b/libsandbox/wrapper-funcs/unlinkat_pre_check.c
  90. @@ -1,20 +1,13 @@
  91. bool sb_unlinkat_pre_check(const char *func, const char *pathname, int dirfd)
  92. {
  93. char canonic[SB_PATH_MAX];
  94. - char dirfd_path[SB_PATH_MAX];
  95. save_errno();
  96. - /* Expand the dirfd path first */
  97. - switch (resolve_dirfd_path(dirfd, pathname, dirfd_path, sizeof(dirfd_path))) {
  98. - case -1:
  99. - sb_debug_dyn("EARLY FAIL: %s(%s) @ resolve_dirfd_path: %s\n",
  100. - func, pathname, strerror(errno));
  101. - return false;
  102. - case 0:
  103. - pathname = dirfd_path;
  104. - break;
  105. - }
  106. + /* Check incoming args against common *at issues */
  107. + char dirfd_path[SB_PATH_MAX];
  108. + if (!sb_common_at_pre_check(func, &pathname, dirfd, dirfd_path, sizeof(dirfd_path)))
  109. + return false;
  110. /* Then break down any relative/symlink paths */
  111. if (-1 == canonicalize(pathname, canonic))
  112. diff --git a/libsandbox/wrappers.h b/libsandbox/wrappers.h
  113. index 5b97787..0aa58bb 100644
  114. --- a/libsandbox/wrappers.h
  115. +++ b/libsandbox/wrappers.h
  116. @@ -28,5 +28,7 @@ attribute_hidden bool sb_mkdirat_pre_check (const char *func, const char *pathn
  117. attribute_hidden bool sb_openat_pre_check (const char *func, const char *pathname, int dirfd, int flags);
  118. attribute_hidden bool sb_openat64_pre_check (const char *func, const char *pathname, int dirfd, int flags);
  119. attribute_hidden bool sb_unlinkat_pre_check (const char *func, const char *pathname, int dirfd);
  120. +attribute_hidden bool sb_common_at_pre_check(const char *func, const char **pathname, int dirfd,
  121. + char *dirfd_path, size_t dirfd_path_len);
  122. #endif
  123. --
  124. 1.8.1.2
  125. From 0b8a6d9773cc0e6d86bf1187f46817d5716698fe Mon Sep 17 00:00:00 2001
  126. From: Mike Frysinger <vapier@gentoo.org>
  127. Date: Mon, 24 Dec 2012 19:41:49 -0500
  128. Subject: [PATCH 2/2] libsandbox: reject "" paths with *at funcs before
  129. checking the dirfd [missing file]
  130. When it comes to processing errors, an empty path is checked before
  131. an invalid dirfd. Make sure sandbox matches that behavior for the
  132. random testsuites out there that look for this.
  133. Forgot to `git add` in the previous commit :/.
  134. URL: https://bugs.gentoo.org/346929
  135. Reported-by: Marien Zwart <marienz@gentoo.org>
  136. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
  137. ---
  138. libsandbox/wrapper-funcs/__pre_at_check.c | 34 +++++++++++++++++++++++++++++++
  139. 1 file changed, 34 insertions(+)
  140. create mode 100644 libsandbox/wrapper-funcs/__pre_at_check.c
  141. diff --git a/libsandbox/wrapper-funcs/__pre_at_check.c b/libsandbox/wrapper-funcs/__pre_at_check.c
  142. new file mode 100644
  143. index 0000000..f72c40c
  144. --- /dev/null
  145. +++ b/libsandbox/wrapper-funcs/__pre_at_check.c
  146. @@ -0,0 +1,34 @@
  147. +/*
  148. + * common *at() pre-checks.
  149. + *
  150. + * Copyright 1999-2012 Gentoo Foundation
  151. + * Licensed under the GPL-2
  152. + */
  153. +
  154. +/* We assume the parent has nested use with save/restore errno */
  155. +bool sb_common_at_pre_check(const char *func, const char **pathname, int dirfd,
  156. + char *dirfd_path, size_t dirfd_path_len)
  157. +{
  158. + /* the empty path name should fail with ENOENT before any dirfd
  159. + * checks get a chance to run #346929
  160. + */
  161. + if (*pathname && *pathname[0] == '\0') {
  162. + errno = ENOENT;
  163. + sb_debug_dyn("EARLY FAIL: %s(%s): %s\n",
  164. + func, *pathname, strerror(errno));
  165. + return false;
  166. + }
  167. +
  168. + /* Expand the dirfd path first */
  169. + switch (resolve_dirfd_path(dirfd, *pathname, dirfd_path, dirfd_path_len)) {
  170. + case -1:
  171. + sb_debug_dyn("EARLY FAIL: %s(%s) @ resolve_dirfd_path: %s\n",
  172. + func, *pathname, strerror(errno));
  173. + return false;
  174. + case 0:
  175. + *pathname = dirfd_path;
  176. + break;
  177. + }
  178. +
  179. + return true;
  180. +}
  181. --
  182. 1.8.1.2