git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Jonathan Nieder <jrnieder@gmail.com>
Cc: Ronnie Sahlberg <sahlberg@google.com>,
	"git\@vger.kernel.org" <git@vger.kernel.org>,
	Michael Haggerty <mhagger@alum.mit.edu>
Subject: Re: [PATCH 19/24] refs.c: allow listing and deleting badly named refs
Date: Thu, 02 Oct 2014 11:55:29 -0700	[thread overview]
Message-ID: <xmqqa95envxa.fsf@gitster.dls.corp.google.com> (raw)
In-Reply-To: <20141002022819.GL1175@google.com> (Jonathan Nieder's message of "Wed, 1 Oct 2014 19:28:19 -0700")

Jonathan Nieder <jrnieder@gmail.com> writes:

> From: Ronnie Sahlberg <sahlberg@google.com>
> ...
> In resolving functions, refuse to resolve refs that don't pass the
> check-ref-format(1) check unless the new RESOLVE_REF_ALLOW_BAD_NAME
> flag is passed.  Even with RESOLVE_REF_ALLOW_BAD_NAME, refuse to
> resolve refs that escape the refs/ directory and do not match the
> pattern [A-Z_]* (think "HEAD" and "MERGE_HEAD").
>
> In locking functions, refuse to act on badly named refs unless they
> are being deleted and either are in the refs/ directory or match [A-Z_]*.
>
> Just like other invalid refs, flag resolved, badly named refs with the
> REF_ISBROKEN flag, treat them as resolving to null_sha1, and skip them
> in all iteration functions except for for_each_rawref.
>
> Flag badly named refs with a REF_BAD_NAME flag to make it easier for
> future callers to notice and handle them specially.
>
> In the transaction API, refuse to create or update badly named refs,
> but allow deleting them (unless they escape refs/ and don't match
> [A-Z_]*).
>
> Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>

Thanks.  We originally threw all the different kind of breakages
into ISBROKEN, but a ref can have a malformed name or can contain a
bad/non value and allowing us to tell them apart is a good direction
to go.

> diff --git a/cache.h b/cache.h
> index 5ca7f2b..0c0ac60 100644
> --- a/cache.h
> +++ b/cache.h
> @@ -978,16 +978,26 @@ extern int read_ref(const char *refname, unsigned char *sha1);
>   * If flags is non-NULL, set the value that it points to the
>   * combination of REF_ISPACKED (if the reference was found among the
>   * packed references), REF_ISSYMREF (if the initial reference was a
> - * symbolic reference) and REF_ISBROKEN (if the ref is malformed).
> + * symbolic reference), REF_BAD_NAME (if the reference name is ill
> + * formed --- see RESOLVE_REF_ALLOW_BAD_NAME below), and REF_ISBROKEN
> + * (if the ref is malformed).

You want to define "is malformed" here.

The original defines REF_ISBROKEN as "malformed" because

 (1) resolve_ref_unsafe() uses get_sha1_hex() and read_loose_refs()
     uses read_ref_full(), both to catch "malformed values" stored;

 (2) resolve_ref_unsafe() uses check_refname_format() and catches
     "malformed names" stored as a symref target.

I _think_ you are introducing ALLOW_BAD_NAME to allow add the third
class ".git/refs/remotes/origin/mal..formed..name".  I do not know
if they should be the same class as a symref with a good name
".git/refs/remotes/origin/HEAD" that points at a bad name
"mal..formed..name", which is (2) above).  Perhaps not.  (2) is
still above what is stored in the ref, and the ref in question may
or may not have a well-formed name, which is orthogonal.

So probably you left only the "value stored in the ref is malformed"
(in other words, "we expected to find 40-hex object name but didn't
find one") case for REF_ISBROKEN?

Do we want to separate "value is not 40-hex" and "a symref points at
a malformed refname" as separate "malformed value" errors?

> + * RESOLVE_REF_ALLOW_BAD_NAME allows resolving refs even when their
> + * name is invalid according to git-check-ref-format(1).  If the name
> + * is bad then the value stored in sha1 will be null_sha1 and the
> + * REF_ISBROKEN and REF_BAD_NAME flags will be set.

Viewed with that light, I am not sure if a badly named ref should
yield null_sha1[] (REF_ISBROKEN, which I am assuming is about a
value that is badly formatted and cannot be read, should keep
yielding it as before).  Wouldn't it make it harder for the user if
you give null_sha1[] back to somebody who is trying to recover by
reading "refs/heads/mal..formed", creating "refs/heads/sensible" to
point at the same value and then removing the former?

Note that I am not saying we should give back the parsed value at
this step in the series.  Perhaps there are some existing callers
that do not check for ISBROKEN flag and instead says "null_sha1[]
ref is to be rejected/ignored", in which case they may need to be
corrected before that happens.  Or there may be some reason I
overlooked that makes it not so useful if we returned the object
name stored in a ref whose name is malformed.  Just wondering.

> @@ -272,6 +272,37 @@ static struct ref_dir *get_ref_dir(struct ref_entry *entry)
>  	return dir;
>  }
>  
> +static int escapes_cwd(const char *path) {
> +	char *buf;
> +	int result;
> +
> +	if (is_absolute_path(path))
> +		return 1;
> +	buf = xmalloc(strlen(path) + 1);
> +	result = !!normalize_path_copy(buf, path);
> +	free(buf);
> +	return result;
> +}

I think this function is misnamed for two reasons.

 - It does not have anything to do with cwd; it does not make any
   difference to the outcome of this function given the same input,
   if 'pwd' says "/u/jc/git" or "/u/jc/git/Documentation", no?

 - Even if this had something to do with cwd, I would expect a
   function whose name is escapes_cwd("/u/jc/git/Documentation") to
   yield false when 'pwd' says "/u/jc/git", but the implementation
   unconditionally rejects absolute path.  In the context of the
   (sole) caller of this function, which deals with a refname "refs/...",
   it makes no sense to see an absolute path, but that does not have
   anything to do with "does this path escape cwd?", no?

> +/*
> + * Check if a refname is safe.
> + * For refs that start with "refs/" we consider it safe as long as the rest
> + * of the path components does not allow it to escape from this directory.
> + * For all other refs we only consider them safe iff they only contain
> + * upper case characters and '_'.
> + */

I presume that the exception is to accomodate for "HEAD", "ORIG_HEAD",
"MERGE_HEAD" and friends, but you probably do not want the readers to
guess.

> +static int refname_is_safe(const char *refname)
> +{
> +	if (starts_with(refname, "refs/"))
> +		return !escapes_cwd(refname + strlen("refs/"));
> +	while (*refname) {
> +		if (!isupper(*refname) && *refname != '_')
> +			return 0;
> +		refname++;
> +	}
> +	return 1;
> +}

  reply	other threads:[~2014-10-02 18:55 UTC|newest]

Thread overview: 129+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-30 17:10 Transaction patch series overview Ronnie Sahlberg
2014-07-31 21:41 ` Ronnie Sahlberg
2014-08-08 16:50   ` Ronnie Sahlberg
2014-08-19 19:54     ` Ronnie Sahlberg
2014-08-19 22:28       ` Junio C Hamano
2014-08-20 23:17       ` Jonathan Nieder
2014-08-26  0:03         ` Jonathan Nieder
2014-08-26 21:01           ` Junio C Hamano
2014-08-26 22:14             ` Jonathan Nieder
2014-08-27  0:28               ` [PATCH 0/20] rs/ref-transaction-1 (Re: Transaction patch series overview) Jonathan Nieder
2014-08-27  0:29                 ` [PATCH 01/20] refs.c: change ref_transaction_create to do error checking and return status Jonathan Nieder
2014-08-27  0:29                 ` [PATCH 02/20] refs.c: update ref_transaction_delete to check for error " Jonathan Nieder
2014-08-27  0:30                 ` [PATCH 03/20] refs.c: make ref_transaction_begin take an err argument Jonathan Nieder
2014-08-27  0:30                 ` [PATCH 04/20] refs.c: add transaction.status and track OPEN/CLOSED Jonathan Nieder
2014-08-27  0:30                 ` [PATCH 05/20] tag.c: use ref transactions when doing updates Jonathan Nieder
2014-08-27  0:31                 ` [PATCH 06/20] replace.c: use the ref transaction functions for updates Jonathan Nieder
2014-08-27  0:31                 ` [PATCH 07/20] commit.c: use ref transactions " Jonathan Nieder
2014-08-27  0:32                 ` [PATCH 08/20] sequencer.c: use ref transactions for all ref updates Jonathan Nieder
2014-08-27  0:32                 ` [PATCH 09/20] fast-import.c: change update_branch to use ref transactions Jonathan Nieder
2014-08-27  0:32                 ` [PATCH 10/20] branch.c: use ref transaction for all ref updates Jonathan Nieder
2014-08-27  0:33                 ` [PATCH 11/20] refs.c: change update_ref to use a transaction Jonathan Nieder
2014-08-27  0:33                 ` [PATCH 12/20] receive-pack.c: use a reference transaction for updating the refs Jonathan Nieder
2014-08-27  0:33                 ` [PATCH 13/20] fast-import.c: use a ref transaction when dumping tags Jonathan Nieder
2014-08-27  0:34                 ` [PATCH 14/20] walker.c: use ref transaction for ref updates Jonathan Nieder
2014-08-27  0:34                 ` [PATCH 15/20] refs.c: make lock_ref_sha1 static Jonathan Nieder
2014-08-27  0:35                 ` [PATCH 16/20] refs.c: remove the update_ref_lock function Jonathan Nieder
2014-08-27  0:35                 ` [PATCH 17/20] refs.c: remove the update_ref_write function Jonathan Nieder
2014-08-27  0:35                 ` [PATCH 18/20] refs.c: remove lock_ref_sha1 Jonathan Nieder
2014-08-27  0:36                 ` [PATCH 19/20] refs.c: make prune_ref use a transaction to delete the ref Jonathan Nieder
2014-08-27  0:36                 ` [PATCH 20/20] refs.c: make delete_ref use a transaction Jonathan Nieder
2014-08-27 21:29                 ` [PATCH 0/20] rs/ref-transaction-1 (Re: Transaction patch series overview) Junio C Hamano
2014-08-27 22:37                   ` Junio C Hamano
2014-09-02 20:58                 ` [PATCH v22 0/22] " Jonathan Nieder
2014-09-02 20:59                   ` [PATCH 01/22] refs.c: change ref_transaction_create to do error checking and return status Jonathan Nieder
2014-09-02 21:00                   ` [PATCH 02/22] refs.c: update ref_transaction_delete to check for error " Jonathan Nieder
2014-09-02 21:00                   ` [PATCH 03/22] refs.c: make ref_transaction_begin take an err argument Jonathan Nieder
2014-09-02 21:00                   ` [PATCH 04/22] refs.c: add transaction.status and track OPEN/CLOSED Jonathan Nieder
2014-09-02 21:01                   ` [PATCH 05/22] tag.c: use ref transactions when doing updates Jonathan Nieder
2014-09-02 21:01                   ` [PATCH 06/22] replace.c: use the ref transaction functions for updates Jonathan Nieder
2014-09-02 21:02                   ` [PATCH 07/22] commit.c: use ref transactions " Jonathan Nieder
2014-09-02 21:02                   ` [PATCH 08/22] sequencer.c: use ref transactions for all ref updates Jonathan Nieder
2014-09-02 21:03                   ` [PATCH 09/22] fast-import.c: change update_branch to use ref transactions Jonathan Nieder
2014-09-02 21:04                   ` [PATCH 10/22] branch.c: use ref transaction for all ref updates Jonathan Nieder
2014-09-02 21:04                   ` [PATCH 11/22] refs.c: change update_ref to use a transaction Jonathan Nieder
2014-09-02 21:05                   ` [PATCH 12/22] receive-pack.c: use a reference transaction for updating the refs Jonathan Nieder
2014-09-02 21:06                   ` [PATCH 13/22] fast-import.c: use a ref transaction when dumping tags Jonathan Nieder
2014-09-02 21:07                   ` [PATCH 14/22] walker.c: use ref transaction for ref updates Jonathan Nieder
2014-09-02 21:08                   ` [PATCH 15/22] refs.c: make lock_ref_sha1 static Jonathan Nieder
2014-09-02 21:08                   ` [PATCH 16/22] refs.c: remove the update_ref_lock function Jonathan Nieder
2014-09-02 21:08                   ` [PATCH 17/22] refs.c: remove the update_ref_write function Jonathan Nieder
2014-09-02 21:09                   ` [PATCH 18/22] refs.c: remove lock_ref_sha1 Jonathan Nieder
2014-09-02 21:09                   ` [PATCH 19/22] refs.c: make prune_ref use a transaction to delete the ref Jonathan Nieder
2014-09-02 21:10                   ` [PATCH 20/22] refs.c: make delete_ref use a transaction Jonathan Nieder
2014-09-02 21:10                   ` [PATCH 21/22] update-ref --stdin: narrow scope of err strbuf Jonathan Nieder
2014-09-02 21:11                   ` [PATCH 22/22] update-ref --stdin: pass transaction around explicitly Jonathan Nieder
2014-08-27 21:53           ` Using Gerrit to review Git patches (was: Re: Transaction patch series overview) Michael Haggerty
2014-08-28  5:07             ` Shawn Pearce
2014-09-11  3:03         ` [PATCH v21 0/19] rs/ref-transaction (Re: " Jonathan Nieder
2014-09-11  3:04           ` [PATCH 01/19] mv test: recreate mod/ directory instead of relying on stale copy Jonathan Nieder
2014-09-11  3:04           ` [PATCH 02/19] wrapper.c: remove/unlink_or_warn: simplify, treat ENOENT as success Jonathan Nieder
2014-09-11  3:05           ` [PATCH 03/19] wrapper.c: add a new function unlink_or_msg Jonathan Nieder
2014-09-11  3:06           ` [PATCH 04/19] refs.c: add an err argument to delete_ref_loose Jonathan Nieder
2014-09-11  3:06           ` [PATCH 05/19] refs.c: pass the ref log message to _create/delete/update instead of _commit Jonathan Nieder
2014-09-11  3:06           ` [PATCH 06/19] rename_ref: don't ask read_ref_full where the ref came from Jonathan Nieder
2014-09-11  3:07           ` [PATCH 07/19] refs.c: move the check for valid refname to lock_ref_sha1_basic Jonathan Nieder
2014-09-11  3:07           ` [PATCH 08/19] refs.c: call lock_ref_sha1_basic directly from commit Jonathan Nieder
2014-09-11  3:08           ` [PATCH 09/19] refs.c: pass a skip list to name_conflict_fn Jonathan Nieder
2014-09-11  3:08           ` [PATCH 10/19] refs.c: ref_transaction_commit: distinguish name conflicts from other errors Jonathan Nieder
2014-09-11  3:08           ` [PATCH 11/19] fetch.c: change s_update_ref to use a ref transaction Jonathan Nieder
2014-09-11  3:08           ` [PATCH 12/19] refs.c: make write_ref_sha1 static Jonathan Nieder
2014-09-11  3:09           ` [PATCH 13/19] refs.c: change resolve_ref_unsafe reading argument to be a flags field Jonathan Nieder
2014-09-11  3:10           ` [PATCH 14/19] branch -d: avoid repeated symref resolution Jonathan Nieder
2014-09-11  3:10           ` [PATCH 15/19] refs.c: fix handling of badly named refs Jonathan Nieder
2014-09-11  3:11           ` [PATCH 16/19] for-each-ref.c: improve message before aborting on broken ref Jonathan Nieder
2014-09-11  3:11           ` [PATCH 17/19] refs.c: do not permit err == NULL Jonathan Nieder
2014-09-11  3:12           ` [PATCH 18/19] lockfile: remove unable_to_lock_error Jonathan Nieder
2014-09-11  3:12           ` [PATCH 19/19] ref_transaction_commit: bail out on failure to remove a ref Jonathan Nieder
2014-09-11 21:40           ` [PATCH v21 0/19] rs/ref-transaction (Re: Transaction patch series overview) Junio C Hamano
2014-09-11 22:20           ` Junio C Hamano
2014-09-12  0:47             ` Jonathan Nieder
2014-09-12 19:00               ` Junio C Hamano
2014-09-12 19:18                 ` Jonathan Nieder
2014-09-12 19:56                   ` Junio C Hamano
2014-09-12 20:47                     ` Junio C Hamano
2014-09-13 17:52                       ` Junio C Hamano
2014-09-12 21:52                     ` Michael Haggerty
2014-09-12 23:57                       ` Jonathan Nieder
2014-09-17 13:23                         ` Michael Haggerty
2014-09-18 16:42                           ` Junio C Hamano
2014-09-18 16:57                             ` Jonathan Nieder
2014-09-18 17:26                               ` Junio C Hamano
2014-09-18 17:38                                 ` Jonathan Nieder
2014-09-25 21:35           ` Junio C Hamano
2014-09-25 21:40             ` Jonathan Nieder
2014-09-25 21:55               ` Junio C Hamano
2014-10-02  1:48           ` [PATCH v22 0/24] rs/ref-transaction Jonathan Nieder
2014-10-02  1:50             ` [PATCH 01/24] mv test: recreate mod/ directory instead of relying on stale copy Jonathan Nieder
2014-10-02  1:54             ` [PATCH 02/24] wrapper.c: remove/unlink_or_warn: simplify, treat ENOENT as success Jonathan Nieder
2014-10-02  1:55             ` [PATCH 03/24] wrapper.c: add a new function unlink_or_msg Jonathan Nieder
2014-10-02  1:58             ` [PATCH 04/24] refs.c: add an err argument to delete_ref_loose Jonathan Nieder
2014-10-02  1:59             ` [PATCH 05/24] refs.c: pass the ref log message to _create/delete/update instead of _commit Jonathan Nieder
2014-10-02  2:00             ` [PATCH 06/24] rename_ref: don't ask read_ref_full where the ref came from Jonathan Nieder
2014-10-02  2:01             ` [PATCH 07/24] refs.c: refuse to lock badly named refs in lock_ref_sha1_basic Jonathan Nieder
2014-10-02  2:02             ` [PATCH 08/24] refs.c: call lock_ref_sha1_basic directly from commit Jonathan Nieder
2014-10-02  2:03             ` [PATCH 09/24] refs.c: pass a list of names to skip to is_refname_available Jonathan Nieder
2014-10-02 19:18               ` Junio C Hamano
2014-10-03 18:51                 ` Jonathan Nieder
2014-10-03 19:05                   ` Junio C Hamano
2014-10-03 21:39                     ` [PATCH v22.5 " Jonathan Nieder
2014-10-07 19:26                       ` Junio C Hamano
2014-10-02  2:05             ` [PATCH 10/24] refs.c: ref_transaction_commit: distinguish name conflicts from other errors Jonathan Nieder
2014-10-02  2:07             ` [PATCH 11/24] fetch.c: change s_update_ref to use a ref transaction Jonathan Nieder
2014-10-02  2:08             ` [PATCH 12/24] refs.c: make write_ref_sha1 static Jonathan Nieder
2014-10-02  2:10             ` [PATCH 13/24] refs.c: change resolve_ref_unsafe reading argument to be a flags field Jonathan Nieder
2014-10-02  2:10             ` [PATCH 14/24] reflog test: test interaction with detached HEAD Jonathan Nieder
2014-10-02  2:15             ` [PATCH 15/24] branch -d: avoid repeated symref resolution Jonathan Nieder
2014-10-02  2:15             ` [PATCH 16/24] branch -d: simplify by using RESOLVE_REF_READING flag Jonathan Nieder
2014-10-02  2:16             ` [PATCH 17/24] packed-ref cache: forbid dot-components in refnames Jonathan Nieder
2014-10-02  2:17             ` [PATCH 18/24] test: put tests for handling of bad ref names in one place Jonathan Nieder
2014-10-02  2:28             ` [PATCH 19/24] refs.c: allow listing and deleting badly named refs Jonathan Nieder
2014-10-02 18:55               ` Junio C Hamano [this message]
2014-10-03 20:25                 ` Ronnie Sahlberg
2014-10-03 20:32                   ` Ronnie Sahlberg
2014-10-03 20:39                   ` Junio C Hamano
2014-10-02  2:30             ` [PATCH 20/24] for-each-ref.c: improve message before aborting on broken ref Jonathan Nieder
2014-10-02  2:32             ` [PATCH 21/24] remote rm/prune: print a message when writing packed-refs fails Jonathan Nieder
2014-10-02  2:33             ` [PATCH 22/24] refs.c: do not permit err == NULL Jonathan Nieder
2014-10-02  2:34             ` [PATCH 23/24] lockfile: remove unable_to_lock_error Jonathan Nieder
2014-10-02  2:35             ` [PATCH 24/24] ref_transaction_commit: bail out on failure to remove a ref Jonathan Nieder

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqa95envxa.fsf@gitster.dls.corp.google.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=jrnieder@gmail.com \
    --cc=mhagger@alum.mit.edu \
    --cc=sahlberg@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).