~ubuntu-branches/ubuntu/intrepid/git-core/intrepid-security

« back to all changes in this revision

Viewing changes to pack-check.c

  • Committer: Package Import Robot
  • Author(s): Gerrit Pape
  • Date: 2007-10-04 08:27:01 UTC
  • mfrom: (1.1.23)
  • Revision ID: package-import@ubuntu.com-20071004082701-rsd058ontoqz4i30
Tags: 1:1.5.3.4-1
new upstream point release (closes: #445188).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include "cache.h"
2
2
#include "pack.h"
3
3
 
 
4
struct idx_entry
 
5
{
 
6
        const unsigned char *sha1;
 
7
        off_t                offset;
 
8
};
 
9
 
 
10
static int compare_entries(const void *e1, const void *e2)
 
11
{
 
12
        const struct idx_entry *entry1 = e1;
 
13
        const struct idx_entry *entry2 = e2;
 
14
        if (entry1->offset < entry2->offset)
 
15
                return -1;
 
16
        if (entry1->offset > entry2->offset)
 
17
                return 1;
 
18
        return 0;
 
19
}
 
20
 
4
21
static int verify_packfile(struct packed_git *p,
5
22
                struct pack_window **w_curs)
6
23
{
11
28
        off_t offset = 0, pack_sig = p->pack_size - 20;
12
29
        uint32_t nr_objects, i;
13
30
        int err;
 
31
        struct idx_entry *entries;
14
32
 
15
33
        /* Note that the pack header checks are actually performed by
16
34
         * use_pack when it first opens the pack file.  If anything
41
59
         * we do not do scan-streaming check on the pack file.
42
60
         */
43
61
        nr_objects = p->num_objects;
 
62
        entries = xmalloc(nr_objects * sizeof(*entries));
 
63
        /* first sort entries by pack offset, since unpacking them is more efficient that way */
 
64
        for (i = 0; i < nr_objects; i++) {
 
65
                entries[i].sha1 = nth_packed_object_sha1(p, i);
 
66
                if (!entries[i].sha1)
 
67
                        die("internal error pack-check nth-packed-object");
 
68
                entries[i].offset = find_pack_entry_one(entries[i].sha1, p);
 
69
                if (!entries[i].offset)
 
70
                        die("internal error pack-check find-pack-entry-one");
 
71
        }
 
72
        qsort(entries, nr_objects, sizeof(*entries), compare_entries);
 
73
 
44
74
        for (i = 0, err = 0; i < nr_objects; i++) {
45
 
                const unsigned char *sha1;
46
75
                void *data;
47
76
                enum object_type type;
48
77
                unsigned long size;
49
 
                off_t offset;
50
78
 
51
 
                sha1 = nth_packed_object_sha1(p, i);
52
 
                if (!sha1)
53
 
                        die("internal error pack-check nth-packed-object");
54
 
                offset = find_pack_entry_one(sha1, p);
55
 
                if (!offset)
56
 
                        die("internal error pack-check find-pack-entry-one");
57
 
                data = unpack_entry(p, offset, &type, &size);
 
79
                data = unpack_entry(p, entries[i].offset, &type, &size);
58
80
                if (!data) {
59
81
                        err = error("cannot unpack %s from %s",
60
 
                                    sha1_to_hex(sha1), p->pack_name);
 
82
                                    sha1_to_hex(entries[i].sha1), p->pack_name);
61
83
                        continue;
62
84
                }
63
 
                if (check_sha1_signature(sha1, data, size, typename(type))) {
 
85
                if (check_sha1_signature(entries[i].sha1, data, size, typename(type))) {
64
86
                        err = error("packed %s from %s is corrupt",
65
 
                                    sha1_to_hex(sha1), p->pack_name);
 
87
                                    sha1_to_hex(entries[i].sha1), p->pack_name);
66
88
                        free(data);
67
89
                        continue;
68
90
                }
69
91
                free(data);
70
92
        }
 
93
        free(entries);
71
94
 
72
95
        return err;
73
96
}
74
97
 
75
98
 
76
 
#define MAX_CHAIN 40
 
99
#define MAX_CHAIN 50
77
100
 
78
101
static void show_pack_info(struct packed_git *p)
79
102
{
80
 
        uint32_t nr_objects, i, chain_histogram[MAX_CHAIN];
81
 
 
 
103
        uint32_t nr_objects, i, chain_histogram[MAX_CHAIN+1];
82
104
        nr_objects = p->num_objects;
83
105
        memset(chain_histogram, 0, sizeof(chain_histogram));
84
106
 
109
131
                        printf("%-6s %lu %"PRIuMAX" %u %s\n",
110
132
                               type, size, (uintmax_t)offset,
111
133
                               delta_chain_length, sha1_to_hex(base_sha1));
112
 
                        if (delta_chain_length < MAX_CHAIN)
 
134
                        if (delta_chain_length <= MAX_CHAIN)
113
135
                                chain_histogram[delta_chain_length]++;
114
136
                        else
115
137
                                chain_histogram[0]++;
116
138
                }
117
139
        }
118
140
 
119
 
        for (i = 0; i < MAX_CHAIN; i++) {
 
141
        for (i = 0; i <= MAX_CHAIN; i++) {
120
142
                if (!chain_histogram[i])
121
143
                        continue;
122
 
                printf("chain length %s %d: %d object%s\n",
123
 
                       i ? "=" : ">=",
124
 
                       i ? i : MAX_CHAIN,
125
 
                       chain_histogram[i],
126
 
                       1 < chain_histogram[i] ? "s" : "");
 
144
                printf("chain length = %d: %d object%s\n", i,
 
145
                       chain_histogram[i], chain_histogram[i] > 1 ? "s" : "");
127
146
        }
 
147
        if (chain_histogram[0])
 
148
                printf("chain length > %d: %d object%s\n", MAX_CHAIN,
 
149
                       chain_histogram[0], chain_histogram[0] > 1 ? "s" : "");
128
150
}
129
151
 
130
152
int verify_pack(struct packed_git *p, int verbose)
131
153
{
132
 
        off_t index_size = p->index_size;
133
 
        const unsigned char *index_base = p->index_data;
 
154
        off_t index_size;
 
155
        const unsigned char *index_base;
134
156
        SHA_CTX ctx;
135
157
        unsigned char sha1[20];
136
158
        int ret;
137
159
 
 
160
        if (open_pack_index(p))
 
161
                return error("packfile %s index not opened", p->pack_name);
 
162
        index_size = p->index_size;
 
163
        index_base = p->index_data;
 
164
 
138
165
        ret = 0;
139
166
        /* Verify SHA1 sum of the index file */
140
167
        SHA1_Init(&ctx);