015-patch-cve-2015-7560.patch 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. From eb27f9b7bf9c1dc902d9545eecf805831bd4e46c Mon Sep 17 00:00:00 2001
  2. From: Jeremy Allison <jra@samba.org>
  3. Date: Tue, 5 Jan 2016 11:18:12 -0800
  4. Subject: [PATCH 1/8] CVE-2015-7560: s3: smbd: Add refuse_symlink() function
  5. that can be used to prevent operations on a symlink.
  6. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
  7. Signed-off-by: Jeremy Allison <jra@samba.org>
  8. Reviewed-by: Michael Adam <obnox@samba.org>
  9. ---
  10. source3/smbd/trans2.c | 28 ++++++++++++++++++++++++++++
  11. 1 file changed, 28 insertions(+)
  12. --- a/source3/smbd/trans2.c
  13. +++ b/source3/smbd/trans2.c
  14. @@ -51,6 +51,34 @@ static char *store_file_unix_basic_info2
  15. files_struct *fsp,
  16. const SMB_STRUCT_STAT *psbuf);
  17. +/****************************************************************************
  18. + Check if an open file handle or pathname is a symlink.
  19. +****************************************************************************/
  20. +
  21. +static NTSTATUS refuse_symlink(connection_struct *conn,
  22. + const files_struct *fsp,
  23. + const char *name)
  24. +{
  25. + SMB_STRUCT_STAT sbuf;
  26. + const SMB_STRUCT_STAT *pst = NULL;
  27. +
  28. + if (fsp) {
  29. + pst = &fsp->fsp_name->st;
  30. + } else {
  31. + int ret = vfs_stat_smb_fname(conn,
  32. + name,
  33. + &sbuf);
  34. + if (ret == -1) {
  35. + return map_nt_error_from_unix(errno);
  36. + }
  37. + pst = &sbuf;
  38. + }
  39. + if (S_ISLNK(pst->st_ex_mode)) {
  40. + return NT_STATUS_ACCESS_DENIED;
  41. + }
  42. + return NT_STATUS_OK;
  43. +}
  44. +
  45. /********************************************************************
  46. Roundup a value to the nearest allocation roundup size boundary.
  47. Only do this for Windows clients.
  48. @@ -181,12 +209,22 @@ NTSTATUS get_ea_names_from_file(TALLOC_C
  49. char **names, **tmp;
  50. size_t num_names;
  51. ssize_t sizeret = -1;
  52. + NTSTATUS status;
  53. +
  54. + if (pnames) {
  55. + *pnames = NULL;
  56. + }
  57. + *pnum_names = 0;
  58. if (!lp_ea_support(SNUM(conn))) {
  59. - if (pnames) {
  60. - *pnames = NULL;
  61. - }
  62. - *pnum_names = 0;
  63. + return NT_STATUS_OK;
  64. + }
  65. +
  66. + status = refuse_symlink(conn, fsp, fname);
  67. + if (!NT_STATUS_IS_OK(status)) {
  68. + /*
  69. + * Just return no EA's on a symlink.
  70. + */
  71. return NT_STATUS_OK;
  72. }
  73. @@ -236,10 +274,6 @@ NTSTATUS get_ea_names_from_file(TALLOC_C
  74. if (sizeret == 0) {
  75. TALLOC_FREE(names);
  76. - if (pnames) {
  77. - *pnames = NULL;
  78. - }
  79. - *pnum_names = 0;
  80. return NT_STATUS_OK;
  81. }
  82. @@ -550,6 +584,7 @@ NTSTATUS set_ea(connection_struct *conn,
  83. const struct smb_filename *smb_fname, struct ea_list *ea_list)
  84. {
  85. char *fname = NULL;
  86. + NTSTATUS status;
  87. if (!lp_ea_support(SNUM(conn))) {
  88. return NT_STATUS_EAS_NOT_SUPPORTED;
  89. @@ -559,6 +594,12 @@ NTSTATUS set_ea(connection_struct *conn,
  90. return NT_STATUS_ACCESS_DENIED;
  91. }
  92. + status = refuse_symlink(conn, fsp, smb_fname->base_name);
  93. + if (!NT_STATUS_IS_OK(status)) {
  94. + return status;
  95. + }
  96. +
  97. +
  98. /* For now setting EAs on streams isn't supported. */
  99. fname = smb_fname->base_name;
  100. @@ -4931,6 +4972,13 @@ NTSTATUS smbd_do_qfilepathinfo(connectio
  101. uint16 num_file_acls = 0;
  102. uint16 num_def_acls = 0;
  103. + status = refuse_symlink(conn,
  104. + fsp,
  105. + smb_fname->base_name);
  106. + if (!NT_STATUS_IS_OK(status)) {
  107. + return status;
  108. + }
  109. +
  110. if (fsp && fsp->fh->fd != -1) {
  111. file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp);
  112. } else {
  113. @@ -6452,6 +6500,7 @@ static NTSTATUS smb_set_posix_acl(connec
  114. uint16 num_def_acls;
  115. bool valid_file_acls = True;
  116. bool valid_def_acls = True;
  117. + NTSTATUS status;
  118. if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
  119. return NT_STATUS_INVALID_PARAMETER;
  120. @@ -6479,6 +6528,11 @@ static NTSTATUS smb_set_posix_acl(connec
  121. return NT_STATUS_INVALID_PARAMETER;
  122. }
  123. + status = refuse_symlink(conn, fsp, smb_fname->base_name);
  124. + if (!NT_STATUS_IS_OK(status)) {
  125. + return status;
  126. + }
  127. +
  128. DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
  129. smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp),
  130. (unsigned int)num_file_acls,
  131. --- a/source3/smbd/nttrans.c
  132. +++ b/source3/smbd/nttrans.c
  133. @@ -877,6 +877,12 @@ NTSTATUS set_sd(files_struct *fsp, struc
  134. return NT_STATUS_OK;
  135. }
  136. + if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
  137. + DEBUG(10, ("ACL set on symlink %s denied.\n",
  138. + fsp_str_dbg(fsp)));
  139. + return NT_STATUS_ACCESS_DENIED;
  140. + }
  141. +
  142. if (psd->owner_sid == NULL) {
  143. security_info_sent &= ~SECINFO_OWNER;
  144. }
  145. @@ -1925,6 +1931,12 @@ NTSTATUS smbd_do_query_security_desc(con
  146. return NT_STATUS_ACCESS_DENIED;
  147. }
  148. + if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
  149. + DEBUG(10, ("ACL get on symlink %s denied.\n",
  150. + fsp_str_dbg(fsp)));
  151. + return NT_STATUS_ACCESS_DENIED;
  152. + }
  153. +
  154. if (security_info_wanted & (SECINFO_DACL|SECINFO_OWNER|
  155. SECINFO_GROUP|SECINFO_SACL)) {
  156. /* Don't return SECINFO_LABEL if anything else was