Merge pull request #2911 from stoeckmann/libarchive_opt_vals
libarchive: Check number ranges of supplied option values
(cherry picked from commit f084dfae97)
This commit is contained in:
1 parent
ab95301c36
commit
34b19b772b
7 files changed
+68
-18
No files matched your search
@@ -28,6 +28,9 @@
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
@@ -116,12 +119,20 @@ archive_filter_b64encode_options(struct archive_write_filter *f, const char *key
|
||||
struct private_b64encode *state = (struct private_b64encode *)f->data;
|
||||
|
||||
if (strcmp(key, "mode") == 0) {
|
||||
int64_t val;
|
||||
|
||||
if (value == NULL) {
|
||||
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
|
||||
"mode option requires octal digits");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
state->mode = (int)atol8(value, strlen(value)) & 0777;
|
||||
val = atol8(value, strlen(value));
|
||||
if (val < 0 || val > INT_MAX) {
|
||||
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
|
||||
"invalid mode option");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
state->mode = (int)val & 0777;
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "name") == 0) {
|
||||
if (value == NULL) {
|
||||
@@ -286,14 +297,19 @@ atol8(const char *p, size_t char_cnt)
|
||||
{
|
||||
int64_t l;
|
||||
int digit;
|
||||
|
||||
|
||||
if (char_cnt == 0)
|
||||
return (-1);
|
||||
|
||||
l = 0;
|
||||
while (char_cnt-- > 0) {
|
||||
if (*p >= '0' && *p <= '7')
|
||||
digit = *p - '0';
|
||||
else
|
||||
break;
|
||||
return (-1);
|
||||
p++;
|
||||
if (l > (INT64_MAX >> 3))
|
||||
return (-1);
|
||||
l <<= 3;
|
||||
l |= digit;
|
||||
}
|
||||
|
||||
@@ -175,8 +175,11 @@ archive_compressor_gzip_options(struct archive_write_filter *f, const char *key,
|
||||
if (strcmp(key, "original-filename") == 0) {
|
||||
free((void*)data->original_filename);
|
||||
data->original_filename = NULL;
|
||||
if (value)
|
||||
if (value) {
|
||||
data->original_filename = strdup(value);
|
||||
if (data->original_filename == NULL)
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
@@ -105,12 +108,20 @@ archive_filter_uuencode_options(struct archive_write_filter *f, const char *key,
|
||||
struct private_uuencode *state = (struct private_uuencode *)f->data;
|
||||
|
||||
if (strcmp(key, "mode") == 0) {
|
||||
int64_t val;
|
||||
|
||||
if (value == NULL) {
|
||||
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
|
||||
"mode option requires octal digits");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
state->mode = (int)atol8(value, strlen(value)) & 0777;
|
||||
val = atol8(value, strlen(value));
|
||||
if (val < 0 || val > INT_MAX) {
|
||||
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
|
||||
"invalid mode option");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
state->mode = (int)val & 0777;
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "name") == 0) {
|
||||
if (value == NULL) {
|
||||
@@ -277,14 +288,19 @@ atol8(const char *p, size_t char_cnt)
|
||||
{
|
||||
int64_t l;
|
||||
int digit;
|
||||
|
||||
|
||||
if (char_cnt == 0)
|
||||
return (-1);
|
||||
|
||||
l = 0;
|
||||
while (char_cnt-- > 0) {
|
||||
if (*p >= '0' && *p <= '7')
|
||||
digit = *p - '0';
|
||||
else
|
||||
break;
|
||||
return (-1);
|
||||
p++;
|
||||
if (l > (INT64_MAX >> 3))
|
||||
return (-1);
|
||||
l <<= 3;
|
||||
l |= digit;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
@@ -387,6 +390,7 @@ archive_compressor_xz_options(struct archive_write_filter *f,
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "threads") == 0) {
|
||||
char *endptr;
|
||||
unsigned long val;
|
||||
|
||||
if (value == NULL) {
|
||||
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
|
||||
@@ -394,13 +398,14 @@ archive_compressor_xz_options(struct archive_write_filter *f,
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
errno = 0;
|
||||
data->threads = (int)strtoul(value, &endptr, 10);
|
||||
if (errno != 0 || *endptr != '\0') {
|
||||
val = strtoul(value, &endptr, 10);
|
||||
if (errno != 0 || *endptr != '\0' || val > (unsigned)INT_MAX) {
|
||||
data->threads = 1;
|
||||
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
|
||||
"threads invalid");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
data->threads = (int)val;
|
||||
if (data->threads == 0) {
|
||||
#ifdef HAVE_LZMA_STREAM_ENCODER_MT
|
||||
data->threads = lzma_cputhreads();
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
@@ -333,6 +336,7 @@ string_to_number(const char *string, intmax_t *numberp)
|
||||
|
||||
if (string == NULL || *string == '\0')
|
||||
return (ARCHIVE_WARN);
|
||||
errno = 0;
|
||||
*numberp = strtoimax(string, &end, 10);
|
||||
if (end == string || *end != '\0' || errno == EOVERFLOW) {
|
||||
*numberp = 0;
|
||||
@@ -487,8 +491,9 @@ _7z_options(struct archive_write *a, const char *key, const char *value)
|
||||
}
|
||||
|
||||
char *end = NULL;
|
||||
errno = 0;
|
||||
long lvl = strtol(value, &end, 10);
|
||||
if (end == NULL || *end != '\0') {
|
||||
if (errno != 0 || end == NULL || *end != '\0') {
|
||||
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
|
||||
"parsing compression-level option value failed `%s'", value);
|
||||
return (ARCHIVE_FAILED);
|
||||
@@ -525,7 +530,7 @@ _7z_options(struct archive_write *a, const char *key, const char *value)
|
||||
if (string_to_number(value, &threads) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
if (threads < 0) {
|
||||
if (threads < 0 || threads > INT_MAX) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
if (threads == 0) {
|
||||
|
||||
@@ -526,12 +526,13 @@ xar_options(struct archive_write *a, const char *key, const char *value)
|
||||
}
|
||||
if (strcmp(key, "threads") == 0) {
|
||||
char *endptr;
|
||||
unsigned long val;
|
||||
|
||||
if (value == NULL)
|
||||
return (ARCHIVE_FAILED);
|
||||
errno = 0;
|
||||
xar->opt_threads = (int)strtoul(value, &endptr, 10);
|
||||
if (errno != 0 || *endptr != '\0') {
|
||||
val = strtoul(value, &endptr, 10);
|
||||
if (errno != 0 || *endptr != '\0' || val > (unsigned)INT_MAX) {
|
||||
xar->opt_threads = 1;
|
||||
archive_set_error(&(a->archive),
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
@@ -539,6 +540,7 @@ xar_options(struct archive_write *a, const char *key, const char *value)
|
||||
value);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
xar->opt_threads = (int)val;
|
||||
if (xar->opt_threads == 0) {
|
||||
#ifdef HAVE_LZMA_STREAM_ENCODER_MT
|
||||
xar->opt_threads = lzma_cputhreads();
|
||||
|
||||
@@ -398,16 +398,17 @@ archive_write_zip_options(struct archive_write *a, const char *key,
|
||||
return (ret);
|
||||
} else if (strcmp(key, "compression-level") == 0) {
|
||||
char *endptr;
|
||||
unsigned long v;
|
||||
|
||||
if (val == NULL)
|
||||
return (ARCHIVE_WARN);
|
||||
errno = 0;
|
||||
zip->compression_level = (short)strtoul(val, &endptr, 10);
|
||||
if (errno != 0 || *endptr != '\0' || zip->compression_level < 0 ||
|
||||
zip->compression_level > 9) {
|
||||
v = strtoul(val, &endptr, 10);
|
||||
if (errno != 0 || *endptr != '\0' || v > 9) {
|
||||
zip->compression_level = 6; // set to default
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
zip->compression_level = (short)v;
|
||||
|
||||
if (zip->compression_level == 0) {
|
||||
zip->requested_compression = COMPRESSION_STORE;
|
||||
@@ -435,17 +436,19 @@ archive_write_zip_options(struct archive_write *a, const char *key,
|
||||
}
|
||||
} else if (strcmp(key, "threads") == 0) {
|
||||
char *endptr;
|
||||
unsigned long v;
|
||||
|
||||
if (val == NULL)
|
||||
return (ARCHIVE_FAILED);
|
||||
errno = 0;
|
||||
zip->threads = (short)strtoul(val, &endptr, 10);
|
||||
if (errno != 0 || *endptr != '\0') {
|
||||
v = strtoul(val, &endptr, 10);
|
||||
if (errno != 0 || *endptr != '\0' || v > SHRT_MAX) {
|
||||
zip->threads = 1;
|
||||
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
|
||||
"Illegal value `%s'", val);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
zip->threads = (short)v;
|
||||
if (zip->threads == 0) {
|
||||
#ifdef HAVE_LZMA_STREAM_ENCODER_MT
|
||||
zip->threads = lzma_cputhreads();
|
||||
|
||||
Reference in new issue
Block a user