summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2014-10-21 20:20:07 +0000
committerdelphij <delphij@FreeBSD.org>2014-10-21 20:20:07 +0000
commit86df2c268fe2029d1252ce4749276b08f63686d3 (patch)
tree2e5146094191f4ae2f9b6865014442b39630b2de
parent6c5ddf4faffa85f792151d8ca53ecff60f5f3bb5 (diff)
downloadFreeBSD-src-86df2c268fe2029d1252ce4749276b08f63686d3.zip
FreeBSD-src-86df2c268fe2029d1252ce4749276b08f63686d3.tar.gz
Fix rtsold(8) remote buffer overflow vulnerability. [SA-14:20]
Fix memory leak in sandboxed namei lookup. [SA-14:22]
-rw-r--r--sys/kern/vfs_lookup.c41
-rw-r--r--usr.sbin/rtsold/rtsol.c3
2 files changed, 18 insertions, 26 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 3671117..c85f9ed 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -121,6 +121,16 @@ TUNABLE_INT("vfs.lookup_shared", &lookup_shared);
* if symbolic link, massage name in buffer and continue
* }
*/
+static void
+namei_cleanup_cnp(struct componentname *cnp)
+{
+ uma_zfree(namei_zone, cnp->cn_pnbuf);
+#ifdef DIAGNOSTIC
+ cnp->cn_pnbuf = NULL;
+ cnp->cn_nameptr = NULL;
+#endif
+}
+
int
namei(struct nameidata *ndp)
{
@@ -185,11 +195,7 @@ namei(struct nameidata *ndp)
}
#endif
if (error) {
- uma_zfree(namei_zone, cnp->cn_pnbuf);
-#ifdef DIAGNOSTIC
- cnp->cn_pnbuf = NULL;
- cnp->cn_nameptr = NULL;
-#endif
+ namei_cleanup_cnp(cnp);
ndp->ni_vp = NULL;
return (error);
}
@@ -256,11 +262,7 @@ namei(struct nameidata *ndp)
}
}
if (error) {
- uma_zfree(namei_zone, cnp->cn_pnbuf);
-#ifdef DIAGNOSTIC
- cnp->cn_pnbuf = NULL;
- cnp->cn_nameptr = NULL;
-#endif
+ namei_cleanup_cnp(cnp);
return (error);
}
}
@@ -286,6 +288,7 @@ namei(struct nameidata *ndp)
if (KTRPOINT(curthread, KTR_CAPFAIL))
ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
#endif
+ namei_cleanup_cnp(cnp);
return (ENOTCAPABLE);
}
while (*(cnp->cn_nameptr) == '/') {
@@ -298,11 +301,7 @@ namei(struct nameidata *ndp)
ndp->ni_startdir = dp;
error = lookup(ndp);
if (error) {
- uma_zfree(namei_zone, cnp->cn_pnbuf);
-#ifdef DIAGNOSTIC
- cnp->cn_pnbuf = NULL;
- cnp->cn_nameptr = NULL;
-#endif
+ namei_cleanup_cnp(cnp);
SDT_PROBE(vfs, namei, lookup, return, error, NULL, 0,
0, 0);
return (error);
@@ -312,11 +311,7 @@ namei(struct nameidata *ndp)
*/
if ((cnp->cn_flags & ISSYMLINK) == 0) {
if ((cnp->cn_flags & (SAVENAME | SAVESTART)) == 0) {
- uma_zfree(namei_zone, cnp->cn_pnbuf);
-#ifdef DIAGNOSTIC
- cnp->cn_pnbuf = NULL;
- cnp->cn_nameptr = NULL;
-#endif
+ namei_cleanup_cnp(cnp);
} else
cnp->cn_flags |= HASBUF;
@@ -378,11 +373,7 @@ namei(struct nameidata *ndp)
vput(ndp->ni_vp);
dp = ndp->ni_dvp;
}
- uma_zfree(namei_zone, cnp->cn_pnbuf);
-#ifdef DIAGNOSTIC
- cnp->cn_pnbuf = NULL;
- cnp->cn_nameptr = NULL;
-#endif
+ namei_cleanup_cnp(cnp);
vput(ndp->ni_vp);
ndp->ni_vp = NULL;
vrele(ndp->ni_dvp);
diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c
index c9b3d44..118206a 100644
--- a/usr.sbin/rtsold/rtsol.c
+++ b/usr.sbin/rtsold/rtsol.c
@@ -933,7 +933,8 @@ dname_labeldec(char *dst, size_t dlen, const char *src)
dst_origin = dst;
memset(dst, '\0', dlen);
while (src && (len = (uint8_t)(*src++) & 0x3f) &&
- (src + len) <= src_last) {
+ (src + len) <= src_last &&
+ (dst - dst_origin < (ssize_t)dlen)) {
if (dst != dst_origin)
*dst++ = '.';
warnmsg(LOG_DEBUG, __func__, "labellen = %zd", len);
OpenPOWER on IntegriCloud