Re: [PATCH 07/11] commit.c: use ref transactions for updates

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Apr 19, 2014 at 12:23 PM, Michael Haggerty <mhagger@xxxxxxxxxxxx> wrote:
> On 04/17/2014 09:46 PM, Ronnie Sahlberg wrote:
>> Change commit.c to use ref transactions for all ref updates.
>>
>> Signed-off-by: Ronnie Sahlberg <sahlberg@xxxxxxxxxx>
>> ---
>>  builtin/commit.c | 22 ++++++++++++----------
>>  1 file changed, 12 insertions(+), 10 deletions(-)
>>
>> diff --git a/builtin/commit.c b/builtin/commit.c
>> index d9550c5..b8e4389 100644
>> --- a/builtin/commit.c
>> +++ b/builtin/commit.c
>> @@ -1541,11 +1541,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
>>       const char *index_file, *reflog_msg;
>>       char *nl;
>>       unsigned char sha1[20];
>> -     struct ref_lock *ref_lock;
>>       struct commit_list *parents = NULL, **pptr = &parents;
>>       struct stat statbuf;
>>       struct commit *current_head = NULL;
>>       struct commit_extra_header *extra = NULL;
>> +     struct ref_transaction *transaction;
>>
>>       if (argc == 2 && !strcmp(argv[1], "-h"))
>>               usage_with_options(builtin_commit_usage, builtin_commit_options);
>> @@ -1667,12 +1667,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
>>       strbuf_release(&author_ident);
>>       free_commit_extra_headers(extra);
>>
>> -     ref_lock = lock_any_ref_for_update("HEAD",
>> -                                        !current_head
>> -                                        ? NULL
>> -                                        : current_head->object.sha1,
>> -                                        0, NULL);
>
> The old version, above, contemplates that current_head might be NULL...
>
>> -
>>       nl = strchr(sb.buf, '\n');
>>       if (nl)
>>               strbuf_setlen(&sb, nl + 1 - sb.buf);
>> @@ -1681,14 +1675,22 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
>>       strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
>>       strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
>>
>> -     if (!ref_lock) {
>> +     transaction = ref_transaction_begin();
>> +     if (!transaction) {
>>               rollback_index_files();
>> -             die(_("cannot lock HEAD ref"));
>> +             die(_("HEAD: cannot start transaction"));
>>       }
>> -     if (write_ref_sha1(ref_lock, sha1, sb.buf) < 0) {
>> +     if (ref_transaction_update(transaction, "HEAD", sha1,
>> +                                current_head->object.sha1,
>> +                                0, !!current_head)) {
>
> ...but here you dereference current_head without checking it first.
>
> It upsets me that the test suite didn't catch this NULL pointer
> dereference.  Either
>
> 1. current_head cannot in fact be NULL, in which case the commit message
> should explain that fact and the code should be simplified
>
> or
>
> 2. the test suite is incomplete.  If so, it would be great if you would
> add a test that exercises this branch of the code (and catches your
> error), and then fix the error.



Current_head can in fact be NULL here but we never actually
dereference any pointer in this case since !!current_head is 0.


current_head->object.sha1 just computes current_head +
offsetof(commit, object) + offsetof(object, sha1)
so we compute and pass a non-NULL garbage pointer into ref_transaction_update()

But since !!current_head is 0 this mean we never actually dereference
this pointer.
Way to subtle for its own good.


I will change ref_transaction_update and friends to use an additional
test to detect some subset of this kind of bug :

if (!have_old && old_sha1)
   die("have_old is false but old_sha1 is not NULL");

regards
ronnie sahlberg
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]