git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 3/4] ref: add symbolic ref content check for files backend

From
shejialuo <shejialuo@gmail.com>
Date
Aug 28, 2024, 15:26 UTC
Message-ID
<Zs9BwpUbWBLvsFMZ@ArchLinux>
In-Reply-To
<xmqq1q2993kg.fsf@gitster.g>
On Tue, Aug 27, 2024 at 12:19:11PM -0700, Junio C Hamano wrote:
Show 18 quoted lines
> shejialuo <shejialuo@gmail.com> writes:
> 
> > In order to check the content of the symbolic ref, create a function
> > "files_fsck_symref_target". It will first check whether the "pointee" is
> > under the "refs/" directory and then we will check the "pointee" itself.
> 
> Hmph, as the pointee must be within the usual places that you would
> find refs (either in refs/ directory or pseudo ref files immediately
> below $GIT_DIR), wouldn't we check the pointee when fsck (or "git
> refs verify") run and check everything?  The pointee will have its
> turn to be checked, and I am not sure why you need to check the
> pointee when you find a symbolic ref is pointing at it, which will
> lead for it to be checked twice (or more).
> 
> I however did not find an additional code to "check the pointee itself"
> in the patch, so perhaps it is OK---the only thing that needs fixing
> may be the above paragraph if that is the case.
> 

Yes, "we will check the 'pointee'" itself makes the reader confused. I will fix the above paragraph. Actually we do not check the "pointee", but check the symref content. Will fix this in the next version.

Show 24 quoted lines
> > There is no specification about the content of the symbolic ref.
> > Although we do write "ref: %s\n" to create a symbolic ref by using
> > "git-symbolic-ref(1)" command. However, this is not mandatory. We still
> > accept symbolic refs with null trailing garbage. Put it more specific,
> > the following are correct:
> >
> > 1. "ref: refs/heads/master   "
> > 2. "ref: refs/heads/master   \n  \n"
> > 3. "ref: refs/heads/master\n\n"
> >
> > But we do not allow any non-null trailing garbage.
> 
> Your use of word "null" is probably too confusing to contributors to
> this project.  None of the above has NUL bytes in them.  I think you
> want to say something like this:
> 
>     A regular file is accepted as a textual symbolic ref if it
>     begins with "ref:", followed by zero or more whitespaces,
>     followed by the full refname (e.g. "refs/heads/master",
>     "refs/tags/v1.0"), followed only by whitespace characters.  We
>     always write a single SP after "ref:" and a single LF after the
>     full refname, but third-party reimplementations of Git may have
>     taken advantage of the looser syntax that is allowed as above.
> 
Thanks for your suggestion. I will improve this in the next version.
Show 14 quoted lines
> > The following are bad
> > symbolic contents which will be reported as fsck error by "git-fsck(1)".
> >
> > 1. "ref: refs/heads/master garbage\n"
> > 2. "ref: refs/heads/master \n\n\n garbage  "
> >
> > In order to provide above checks, we will use "strrchr" to check whether
> > we have newline in the ref content.
> 
> strrchr() to look for only LF is overly strict.  You need to match
> what refs/files-backend.c:read_ref_internal() does to the contents
> read from such a loose ref file, i.e. strbuf_rtrim().  Any isspace()
> bytes are trimmed at the end, including SP, HT, CR and LF.
> 

I will look into how "strbuf_rtrim" does to see whether we can reuse some functions to avoid repetition.

Show 33 quoted lines
> > +static int files_fsck_symref_target(struct fsck_options *o,
> > +				    struct fsck_ref_report *report,
> > +				    const char *refname,
> > +				    struct strbuf *pointee_name,
> > +				    struct strbuf *pointee_path)
> > +{
> > +	const char *newline_pos = NULL;
> > +	const char *p = NULL;
> > +	struct stat st;
> > +	int ret = 0;
> > +
> > +	if (!skip_prefix(pointee_name->buf, "refs/", &p)) {
> > +
> > +		ret = fsck_report_ref(o, report,
> > +				      FSCK_MSG_BAD_SYMREF_POINTEE,
> > +				      "points to ref outside the refs directory");
> > +		goto out;
> > +	}
> > +
> > +	newline_pos = strrchr(p, '\n');
> > +	if (!newline_pos || *(newline_pos + 1)) {
> > +		ret = fsck_report_ref(o, report,
> > +				      FSCK_MSG_REF_MISSING_NEWLINE,
> > +				      "missing newline");
> 
> If newline_pos is NULL, it is truly a "missing newline" situation.
> If I am reading the code correctly, the severity level is set to
> INFO, which is good.
> 
> If newline_pos is not NULL but newline_pos[1] is not NUL, however,
> that is not a "missing newline".  "refs: refs/heads/master\n " would
> trigger this report, for example.
> 

When I design this, I actually consider "ref: refs/heads/master\n " is still missing the newline. And then we also report that it has garbage. I think "ref: refs/heads/master\n \n" is not missing the newline. But, I don't think this is good.

I will find a good way to handle this.
Show 5 quoted lines
> As far as I can tell, such a textual symbolic ref is taken as a
> valid symbolic ref pointing at "refs/heads/master" by
> refs/files-backend.c:read_ref_internal(), so we are trying to detect
> a valid but curiously formatted textual symbolic ref file with the
> above code?

Yes, these situations will be taken as a valid symbolic ref but actually there are something wrong. So this is what we need to care about.

Show 6 quoted lines
> 
> And strrchr() to find the last LF is not sufficient for that
> purpose.  We would never write "refs:  refs/head/master \n",
> but the above code will find the LF, be satisified that the LF is
> followed by NUL, without realizing that SP there is not something we
> would have written!

I totally ignored this situation, and in current patch, we cannot check this. I know why Patrick lets me use "strchr" but not "strrchr". I think we should find the last '\n'. But instead we need to find the first '\n'. However, in this example, we will still fail by using "strchr". This part should be totally re-designed.

Show 14 quoted lines
> 
> I am not sure if that is worth detecting that if it is something we
> would have written, but if that were the case, then you would
> probably need to do
> 
>     (1) check the last byte of pointee_name.buf[] to make sure that
>         it is LF; and
>     (2) remember pointee_name.len, run strbuf_rtrim() on pointee_name,
>         and that LF at the end was the only thing that was trimmed by
>         checking the pointee_name.len after trimming.
> 
> or something like that.  Then you do not have to have an ugly "oh we
> need to check again"---the production code would not do that, either.
> 
Yes, this is a good idea.
Show 17 quoted lines
> > +	if (check_refname_format(pointee_name->buf, 0)) {
> > +		/*
> > +		 * When containing null-garbage, "check_refname_format" will
> > +		 * fail, we should trim the "pointee" to check again.
> > +		 */
> > +		strbuf_rtrim(pointee_name);
> > +		if (!check_refname_format(pointee_name->buf, 0)) {
> > +			ret = fsck_report_ref(o, report,
> > +					      FSCK_MSG_TRAILING_REF_CONTENT,
> > +					      "trailing null-garbage");
> > +			goto out;
> > +		}
> 
> IOW, the above "let's retry" feels totally wrong.  You shouldn't
> have to do so, and that comes from running check_refname_format()
> before rtrimming the pointee_name.
> 

Yes, actually, I have thought I could compare the length change after executing the "strbuf_rtrim". I don't want to create two new variables, so I call "check_refname_format" twice.

Will fix this in the next version.
Show 12 quoted lines
> > +	if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {
> > +		ret = fsck_report_ref(o, report,
> > +				      FSCK_MSG_BAD_SYMREF_POINTEE,
> > +				      "points to an invalid file type");
> > +		goto out;
> 
> I do not think it is wrong per se, but I am not sure if this check
> is needed, either.  When "git fsck" or "git refs verify" is told to
> check the loose refs, wouldn't it walk the refs directory and report
> such an unusual filesystem entity that is not a regular file,
> symbolic link, or a directory as "there is unusual cruft exist
> here"?

When setting up the infrastructure, actually we DO report filesystem entity that is not a regular file or symbolic link like the following:

    if (S_ISDIR(iter->st.st_mode)) {
        continue;
    } else if (S_ISREG(iter->st.st_mode) ||
               S_ISLNK(iter->st.st_mode)) {
        ...;
    } else {
      // report file system error
    }

We do not check the directory, because the directory will be always valid in the filesystem. we could not say that

  "refs/heads/a/" is a bad ref.

So, this check mainly need to check whether the symref points to a directory. Actually, Patrick has also gave the review about this question in the previous version:

> What exactly are we guarding against here? Don't we already verify that
> files in `refs/` have the correct type? Or are we checking that it does
> not point to a directory?

However, we should remove this line, because "check_refname_format" will take care for us.

  git check-ref-format 'refs/heads/'

It will generate an error. So, we could entirely remove this line and let "check_refname_format" do this. And we could also remove the

    if (lstat(pointee_path->buf, &st) < 0)
        goto out;
The code will be much more clean.

Thanks, Jialuo

Previous: Junio C HamanoNext: Patrick Steinhardt
Message 42 of 209 in “[RFC] Implement ref content consistency check”
  1. shejialuoAug 13, 2024
  2. karthik nayakAug 15, 2024
  3. shejialuoAug 15, 2024
  4. Patrick SteinhardtAug 16, 2024
  5. Junio C HamanoAug 16, 2024
  6. 0/4 add ref content check for files backendshejialuo, Aug 18, 2024
  7. 1/4 fsck: introduce "FSCK_REF_REPORT_DEFAULT" macroshejialuo, Aug 18, 2024
  8. Junio C HamanoAug 20, 2024
  9. shejialuoAug 21, 2024
  10. 2/4 ref: add regular ref content check for files backendshejialuo, Aug 18, 2024
  11. Junio C HamanoAug 20, 2024
  12. shejialuoAug 21, 2024
  13. Patrick SteinhardtAug 22, 2024
  14. Junio C HamanoAug 22, 2024
  15. Junio C HamanoAug 22, 2024
  16. Patrick SteinhardtAug 23, 2024
  17. shejialuoAug 23, 2024
  18. Patrick SteinhardtAug 22, 2024
  19. shejialuoAug 22, 2024
  20. 3/4 ref: add symbolic ref content check for files backendshejialuo, Aug 18, 2024
  21. Patrick SteinhardtAug 22, 2024
  22. shejialuoAug 22, 2024
  23. Patrick SteinhardtAug 23, 2024
  24. shejialuoAug 23, 2024
  25. 4/4 ref: add symlink ref consistency check for files backendshejialuo, Aug 18, 2024
  26. 0/4 add ref content check for files backendshejialuo, Aug 27, 2024
  27. 1/4 ref: initialize "fsck_ref_report" with zeroshejialuo, Aug 27, 2024
  28. Junio C HamanoAug 27, 2024
  29. 2/4 ref: add regular ref content check for files backendshejialuo, Aug 27, 2024
  30. shejialuoAug 27, 2024
  31. Junio C HamanoAug 27, 2024
  32. Patrick SteinhardtAug 28, 2024
  33. Junio C HamanoAug 28, 2024
  34. Patrick SteinhardtAug 29, 2024
  35. shejialuoAug 28, 2024
  36. Junio C HamanoAug 28, 2024
  37. Patrick SteinhardtAug 28, 2024
  38. shejialuoAug 28, 2024
  39. Junio C HamanoAug 28, 2024
  40. 3/4 ref: add symbolic ref content check for files backendshejialuo, Aug 27, 2024
  41. Junio C HamanoAug 27, 2024
  42. shejialuoAug 28, 2024
  43. Patrick SteinhardtAug 28, 2024
  44. shejialuoAug 28, 2024
  45. Junio C HamanoAug 28, 2024
  46. Patrick SteinhardtAug 29, 2024
  47. 4/4 ref: add symlink ref check for files backendshejialuo, Aug 27, 2024
  48. SQUASH??? remove unused parametersJunio C Hamano, Aug 28, 2024
  49. Junio C HamanoAug 28, 2024
  50. Jeff KingAug 29, 2024
  51. Junio C HamanoAug 29, 2024
  52. Patrick SteinhardtAug 29, 2024
  53. Junio C HamanoAug 29, 2024
  54. Jeff KingAug 29, 2024
  55. shejialuoAug 29, 2024
  56. Junio C HamanoAug 29, 2024
  57. 8/6 CodingGuidelines: also mention MAYBE_UNUSEDJunio C Hamano, Aug 29, 2024
  58. Jeff KingAug 29, 2024
  59. Junio C HamanoAug 29, 2024
  60. CodingGuidelines: also mention MAYBE_UNUSEDJunio C Hamano, Aug 29, 2024
  61. 9/6 git-compat-util: guard definition of MAYBE_UNUSED with __GNUC__Junio C Hamano, Aug 29, 2024
  62. Jeff KingAug 29, 2024
  63. Junio C HamanoAug 29, 2024
  64. Jeff KingAug 29, 2024
  65. 0/4 add ref content check for files backendshejialuo, Sep 3, 2024
  66. 1/4 ref: initialize "fsck_ref_report" with zeroshejialuo, Sep 3, 2024
  67. 2/4 ref: add regular ref content check for files backendshejialuo, Sep 3, 2024
  68. Patrick SteinhardtSep 9, 2024
  69. shejialuoSep 10, 2024
  70. karthik nayakSep 10, 2024
  71. shejialuoSep 13, 2024
  72. 3/4 ref: add symref content check for files backendshejialuo, Sep 3, 2024
  73. Patrick SteinhardtSep 9, 2024
  74. shejialuoSep 10, 2024
  75. karthik nayakSep 10, 2024
  76. shejialuoSep 12, 2024
  77. 4/4 ref: add symlink ref content check for files backendshejialuo, Sep 3, 2024
  78. Patrick SteinhardtSep 9, 2024
  79. shejialuoSep 10, 2024
  80. 0/5 add ref content check for files backendshejialuo, Sep 13, 2024
  81. 1/5 ref: initialize "fsck_ref_report" with zeroshejialuo, Sep 13, 2024
  82. Junio C HamanoSep 18, 2024
  83. 2/5 ref: port git-fsck(1) regular refs check for files backendshejialuo, Sep 13, 2024
  84. Junio C HamanoSep 18, 2024
  85. shejialuoSep 22, 2024
  86. 3/5 ref: add more strict checks for regular refsshejialuo, Sep 13, 2024
  87. Junio C HamanoSep 18, 2024
  88. shejialuoSep 22, 2024
  89. Junio C HamanoSep 22, 2024
  90. 4/5 ref: add symref content check for files backendshejialuo, Sep 13, 2024
  91. Junio C HamanoSep 18, 2024
  92. shejialuoSep 22, 2024
  93. Junio C HamanoSep 22, 2024
  94. 5/5 ref: add symlink ref content check for files backendshejialuo, Sep 13, 2024
  95. Junio C HamanoSep 18, 2024
  96. Junio C HamanoSep 18, 2024
  97. 0/9 add ref content check for files backendshejialuo, Sep 29, 2024
  98. 1/9 ref: initialize "fsck_ref_report" with zeroshejialuo, Sep 29, 2024
  99. Karthik NayakOct 8, 2024
  100. 2/9 builtin/refs: support multiple worktrees check for refs.shejialuo, Sep 29, 2024
  101. Patrick SteinhardtOct 7, 2024
  102. shejialuoOct 7, 2024
  103. Patrick SteinhardtOct 7, 2024
  104. shejialuoOct 7, 2024
  105. 3/9 ref: port git-fsck(1) regular refs check for files backendshejialuo, Sep 29, 2024
  106. Patrick SteinhardtOct 7, 2024
  107. shejialuoOct 7, 2024
  108. Patrick SteinhardtOct 7, 2024
  109. shejialuoOct 7, 2024
  110. Karthik NayakOct 8, 2024
  111. shejialuoOct 8, 2024
  112. Junio C HamanoOct 8, 2024
  113. Patrick SteinhardtOct 9, 2024
  114. shejialuoOct 9, 2024
  115. Patrick SteinhardtOct 10, 2024
  116. Junio C HamanoOct 10, 2024
  117. shejialuoOct 9, 2024
  118. 4/9 ref: add more strict checks for regular refsshejialuo, Sep 29, 2024
  119. Patrick SteinhardtOct 7, 2024
  120. shejialuoOct 7, 2024
  121. Patrick SteinhardtOct 7, 2024
  122. shejialuoOct 7, 2024
  123. 5/9 ref: add basic symref content check for files backendshejialuo, Sep 29, 2024
  124. Karthik NayakOct 8, 2024
  125. shejialuoOct 8, 2024
  126. 6/9 ref: add escape check for the referent of symrefshejialuo, Sep 29, 2024
  127. Patrick SteinhardtOct 7, 2024
  128. shejialuoOct 7, 2024
  129. Patrick SteinhardtOct 7, 2024
  130. 7/9 ref: enhance escape situation for worktreesshejialuo, Sep 29, 2024
  131. Patrick SteinhardtOct 7, 2024
  132. shejialuoOct 7, 2024
  133. 8/9 t0602: add ref content checks for worktreesshejialuo, Sep 29, 2024
  134. Patrick SteinhardtOct 7, 2024
  135. shejialuoOct 7, 2024
  136. 9/9 ref: add symlink ref content check for files backendshejialuo, Sep 29, 2024
  137. Patrick SteinhardtOct 7, 2024
  138. shejialuoOct 7, 2024
  139. Junio C HamanoSep 30, 2024
  140. shejialuoOct 1, 2024
  141. shejialuoOct 7, 2024
  142. 0/9 add ref content check for files backendshejialuo, Oct 21, 2024
  143. 1/9 ref: initialize "fsck_ref_report" with zeroshejialuo, Oct 21, 2024
  144. 2/9 ref: check the full refname instead of basenameshejialuo, Oct 21, 2024
  145. karthik nayakOct 21, 2024
  146. shejialuoOct 22, 2024
  147. Patrick SteinhardtNov 5, 2024
  148. shejialuoNov 6, 2024
  149. 3/9 ref: initialize target name outside of check functionsshejialuo, Oct 21, 2024
  150. karthik nayakOct 21, 2024
  151. Patrick SteinhardtNov 5, 2024
  152. shejialuoNov 6, 2024
  153. Patrick SteinhardtNov 6, 2024
  154. 4/9 ref: support multiple worktrees check for refsshejialuo, Oct 21, 2024
  155. karthik nayakOct 21, 2024
  156. shejialuoOct 22, 2024
  157. Patrick SteinhardtNov 5, 2024
  158. shejialuoNov 5, 2024
  159. Patrick SteinhardtNov 6, 2024
  160. shejialuoNov 6, 2024
  161. 5/9 ref: port git-fsck(1) regular refs check for files backendshejialuo, Oct 21, 2024
  162. Patrick SteinhardtNov 5, 2024
  163. 6/9 ref: add more strict checks for regular refsshejialuo, Oct 21, 2024
  164. 7/9 ref: add basic symref content check for files backendshejialuo, Oct 21, 2024
  165. 8/9 ref: check whether the target of the symref is a refshejialuo, Oct 21, 2024
  166. 9/9 ref: add symlink ref content check for files backendshejialuo, Oct 21, 2024
  167. Taylor BlauOct 21, 2024
  168. shejialuoOct 22, 2024
  169. Taylor BlauOct 21, 2024
  170. 0/9 add ref content check for files backendshejialuo, Nov 10, 2024
  171. 1/9 ref: initialize "fsck_ref_report" with zeroshejialuo, Nov 10, 2024
  172. 2/9 ref: check the full refname instead of basenameshejialuo, Nov 10, 2024
  173. 3/9 ref: initialize ref name outside of check functionsshejialuo, Nov 10, 2024
  174. 4/9 ref: support multiple worktrees check for refsshejialuo, Nov 10, 2024
  175. 5/9 ref: port git-fsck(1) regular refs check for files backendshejialuo, Nov 10, 2024
  176. Patrick SteinhardtNov 13, 2024
  177. shejialuoNov 14, 2024
  178. 6/9 ref: add more strict checks for regular refsshejialuo, Nov 10, 2024
  179. 7/9 ref: add basic symref content check for files backendshejialuo, Nov 10, 2024
  180. 8/9 ref: check whether the target of the symref is a refshejialuo, Nov 10, 2024
  181. 9/9 ref: add symlink ref content check for files backendshejialuo, Nov 10, 2024
  182. Patrick SteinhardtNov 13, 2024
  183. shejialuoNov 14, 2024
  184. Patrick SteinhardtNov 13, 2024
  185. 0/9 add ref content check for files backendshejialuo, Nov 14, 2024
  186. 1/9 ref: initialize "fsck_ref_report" with zeroshejialuo, Nov 14, 2024
  187. 2/9 ref: check the full refname instead of basenameshejialuo, Nov 14, 2024
  188. 3/9 ref: initialize ref name outside of check functionsshejialuo, Nov 14, 2024
  189. 4/9 ref: support multiple worktrees check for refsshejialuo, Nov 14, 2024
  190. 5/9 ref: port git-fsck(1) regular refs check for files backendshejialuo, Nov 14, 2024
  191. Patrick SteinhardtNov 15, 2024
  192. shejialuoNov 15, 2024
  193. 6/9 ref: add more strict checks for regular refsshejialuo, Nov 14, 2024
  194. 7/9 ref: add basic symref content check for files backendshejialuo, Nov 14, 2024
  195. 8/9 ref: check whether the target of the symref is a refshejialuo, Nov 14, 2024
  196. 9/9 ref: add symlink ref content check for files backendshejialuo, Nov 14, 2024
  197. shejialuoNov 15, 2024
  198. 0/9 add ref content check for files backendshejialuo, Nov 20, 2024
  199. 1/9 ref: initialize "fsck_ref_report" with zeroshejialuo, Nov 20, 2024
  200. 2/9 ref: check the full refname instead of basenameshejialuo, Nov 20, 2024
  201. 3/9 ref: initialize ref name outside of check functionsshejialuo, Nov 20, 2024
  202. 4/9 ref: support multiple worktrees check for refsshejialuo, Nov 20, 2024
  203. 5/9 ref: port git-fsck(1) regular refs check for files backendshejialuo, Nov 20, 2024
  204. 6/9 ref: add more strict checks for regular refsshejialuo, Nov 20, 2024
  205. 7/9 ref: add basic symref content check for files backendshejialuo, Nov 20, 2024
  206. 8/9 ref: check whether the target of the symref is a refshejialuo, Nov 20, 2024
  207. 9/9 ref: add symlink ref content check for files backendshejialuo, Nov 20, 2024
  208. Patrick SteinhardtNov 20, 2024
  209. Junio C HamanoNov 20, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.