aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2007-05-23 16:13:20 +0000
committerColin Percival <cperciva@FreeBSD.org>2007-05-23 16:13:20 +0000
commit723930a26af17f1cef8b639233dc7e6c5318bbd3 (patch)
tree76eeb28e3d9a4f6a16034ba2f70899fcb6f74b89
parentf64f1bc808da2132080f9440a01098352c860dfb (diff)
downloadsrc-723930a26af17f1cef8b639233dc7e6c5318bbd3.tar.gz
src-723930a26af17f1cef8b639233dc7e6c5318bbd3.zip
Fix buffer overflow in libmagic(3).
Security: FreeBSD-SA-07:04.file Approved by: so (cperciva)
Notes
Notes: svn path=/releng/5.5/; revision=169904
-rw-r--r--UPDATING3
-rw-r--r--contrib/file/file.h2
-rw-r--r--contrib/file/funcs.c41
-rw-r--r--contrib/file/magic.c3
-rw-r--r--sys/conf/newvers.sh2
5 files changed, 32 insertions, 19 deletions
diff --git a/UPDATING b/UPDATING
index 86162ce54174..92f0b395fbd4 100644
--- a/UPDATING
+++ b/UPDATING
@@ -8,6 +8,9 @@ Items affecting the ports and packages system can be found in
/usr/ports/UPDATING. Please read that file before running
portupgrade.
+20070523: p13 FreeBSD-SA-07:04.file
+ Fix buffer overflow in libmagic(3).
+
20070426: p12 FreeBSD-SA-07:03.ipv6
Disable processing of IPv6 type 0 Routing Headers. This behaviour
can be changed via the (newly added) net.inet6.ip6.rthdr0_allowed
diff --git a/contrib/file/file.h b/contrib/file/file.h
index d5fe2cc90447..d2d14ba0f7cd 100644
--- a/contrib/file/file.h
+++ b/contrib/file/file.h
@@ -225,7 +225,7 @@ struct magic_set {
/* Accumulation buffer */
char *buf;
char *ptr;
- size_t len;
+ size_t left;
size_t size;
/* Printable buffer */
char *pbuf;
diff --git a/contrib/file/funcs.c b/contrib/file/funcs.c
index 44cbdf1af354..2528a5cf847e 100644
--- a/contrib/file/funcs.c
+++ b/contrib/file/funcs.c
@@ -28,6 +28,7 @@
*/
#include "file.h"
#include "magic.h"
+#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@@ -43,27 +44,31 @@ protected int
file_printf(struct magic_set *ms, const char *fmt, ...)
{
va_list ap;
- size_t len;
+ size_t len, size;
char *buf;
va_start(ap, fmt);
- if ((len = vsnprintf(ms->o.ptr, ms->o.len, fmt, ap)) >= ms->o.len) {
+ if ((len = vsnprintf(ms->o.ptr, ms->o.left, fmt, ap)) >= ms->o.left) {
+ long diff; /* XXX: really ptrdiff_t */
+
va_end(ap);
- if ((buf = realloc(ms->o.buf, len + 1024)) == NULL) {
+ size = (ms->o.size - ms->o.left) + len + 1024;
+ if ((buf = realloc(ms->o.buf, size)) == NULL) {
file_oomem(ms);
return -1;
}
- ms->o.ptr = buf + (ms->o.ptr - ms->o.buf);
+ diff = ms->o.ptr - ms->o.buf;
+ ms->o.ptr = buf + diff;
ms->o.buf = buf;
- ms->o.len = ms->o.size - (ms->o.ptr - ms->o.buf);
- ms->o.size = len + 1024;
+ ms->o.left = size - diff;
+ ms->o.size = size;
va_start(ap, fmt);
- len = vsnprintf(ms->o.ptr, ms->o.len, fmt, ap);
+ len = vsnprintf(ms->o.ptr, ms->o.left, fmt, ap);
}
ms->o.ptr += len;
- ms->o.len -= len;
+ ms->o.left -= len;
va_end(ap);
return 0;
}
@@ -152,8 +157,8 @@ file_reset(struct magic_set *ms)
protected const char *
file_getbuffer(struct magic_set *ms)
{
- char *nbuf, *op, *np;
- size_t nsize;
+ char *pbuf, *op, *np;
+ size_t psize, len;
if (ms->haderr)
return NULL;
@@ -161,14 +166,20 @@ file_getbuffer(struct magic_set *ms)
if (ms->flags & MAGIC_RAW)
return ms->o.buf;
- nsize = ms->o.len * 4 + 1;
- if (ms->o.psize < nsize) {
- if ((nbuf = realloc(ms->o.pbuf, nsize)) == NULL) {
+ len = ms->o.size - ms->o.left;
+ if (len > (SIZE_T_MAX - 1) / 4) {
+ file_oomem(ms);
+ return NULL;
+ }
+ /* * 4 is for octal representation, + 1 is for NUL */
+ psize = len * 4 + 1;
+ if (ms->o.psize < psize) {
+ if ((pbuf = realloc(ms->o.pbuf, psize)) == NULL) {
file_oomem(ms);
return NULL;
}
- ms->o.psize = nsize;
- ms->o.pbuf = nbuf;
+ ms->o.psize = psize;
+ ms->o.pbuf = pbuf;
}
for (np = ms->o.pbuf, op = ms->o.buf; *op; op++) {
diff --git a/contrib/file/magic.c b/contrib/file/magic.c
index 0ecf2d30c298..2d11d822cbd5 100644
--- a/contrib/file/magic.c
+++ b/contrib/file/magic.c
@@ -92,8 +92,7 @@ magic_open(int flags)
return NULL;
}
- ms->o.ptr = ms->o.buf = malloc(ms->o.size = 1024);
- ms->o.len = 0;
+ ms->o.ptr = ms->o.buf = malloc(ms->o.left = ms->o.size = 1024);
if (ms->o.buf == NULL) {
free(ms);
return NULL;
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 2c6df5fc2dd6..2c7255945672 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
TYPE="FreeBSD"
REVISION="5.5"
-BRANCH="RELEASE-p12"
+BRANCH="RELEASE-p13"
RELEASE="${REVISION}-${BRANCH}"
VERSION="${TYPE} ${RELEASE}"