Skip to content

Commit e176197

Browse files
cgzonesjwcart2
authored andcommitted
libselinux: correctly hash specfiles larger than 4G
The internal Sha1Update() functions only handles buffers up to a size of UINT32_MAX, due to its usage of the type uint32_t. This causes issues when processing more than UINT32_MAX bytes, e.g. with a specfile larger than 4G. 0aa974a ("libselinux: limit has buffer size") tried to address this issue, but failed since the overflow check if (digest->hashbuf_size + buf_len < digest->hashbuf_size) { will be done in the widest common type, which is size_t, the type of `buf_len`. Revert the type of `hashbuf_size` to size_t and instead process the data in blocks of supported size. Acked-by: James Carter <[email protected]> Signed-off-by: Christian Göttsche <[email protected]> Reverts: 0aa974a ("libselinux: limit has buffer size")
1 parent b9a4d13 commit e176197

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

libselinux/src/label_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ int selabel_service_init(struct selabel_handle *rec,
5757
struct selabel_digest {
5858
unsigned char *digest; /* SHA1 digest of specfiles */
5959
unsigned char *hashbuf; /* buffer to hold specfiles */
60-
uint32_t hashbuf_size; /* buffer size */
60+
size_t hashbuf_size; /* buffer size */
6161
size_t specfile_cnt; /* how many specfiles processed */
6262
char **specfile_list; /* and their names */
6363
};

libselinux/src/label_support.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,25 @@ int read_spec_entries(char *line_buf, const char **errbuf, int num_args, ...)
116116
void digest_gen_hash(struct selabel_digest *digest)
117117
{
118118
Sha1Context context;
119+
size_t remaining_size;
120+
const unsigned char *ptr;
119121

120122
/* If SELABEL_OPT_DIGEST not set then just return */
121123
if (!digest)
122124
return;
123125

124126
Sha1Initialise(&context);
125-
Sha1Update(&context, digest->hashbuf, digest->hashbuf_size);
127+
128+
/* Process in blocks of UINT32_MAX bytes */
129+
remaining_size = digest->hashbuf_size;
130+
ptr = digest->hashbuf;
131+
while (remaining_size > UINT32_MAX) {
132+
Sha1Update(&context, ptr, UINT32_MAX);
133+
remaining_size -= UINT32_MAX;
134+
ptr += UINT32_MAX;
135+
}
136+
Sha1Update(&context, ptr, remaining_size);
137+
126138
Sha1Finalise(&context, (SHA1_HASH *)digest->digest);
127139
free(digest->hashbuf);
128140
digest->hashbuf = NULL;

0 commit comments

Comments
 (0)