summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2000-07-23 16:54:18 +0000
committermarcel <marcel@FreeBSD.org>2000-07-23 16:54:18 +0000
commita069944f46211cf481f1414ec35e8e264169f6f2 (patch)
tree49112d177fe8ca7bbe4a30d621fca616e31f7195 /sys/compat
parent232803be5c159e6ffdab510c966bf2f5c001a490 (diff)
downloadFreeBSD-src-a069944f46211cf481f1414ec35e8e264169f6f2.zip
FreeBSD-src-a069944f46211cf481f1414ec35e8e264169f6f2.tar.gz
Add bounds checking to stackgap_alloc. Previously it was possible
to construct a path that was long enough (ie longer than SPARE_USRSPACE bytes) and trash the stack. Note that SPARE_USRSPACE is much smaller than MAXPATHLEN so that the Linuxulator will now return ENAMETOOLONG even if the path is smaller than MAXPATHLEN. PR: 12749
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linux/linux_misc.c2
-rw-r--r--sys/compat/linux/linux_util.c5
-rw-r--r--sys/compat/linux/linux_util.h18
3 files changed, 14 insertions, 11 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 1adea54..dcbff98 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -954,6 +954,8 @@ linux_utime(struct proc *p, struct linux_utime_args *args)
tv[1].tv_usec = 0;
/* so that utimes can copyin */
tvp = (struct timeval *)stackgap_alloc(&sg, sizeof(tv));
+ if (tvp == NULL)
+ return (ENAMETOOLONG);
if ((error = copyout(tv, tvp, sizeof(tv))))
return error;
bsdutimes.tptr = tvp;
diff --git a/sys/compat/linux/linux_util.c b/sys/compat/linux/linux_util.c
index 8faf35e..e0ea0cb 100644
--- a/sys/compat/linux/linux_util.c
+++ b/sys/compat/linux/linux_util.c
@@ -162,7 +162,10 @@ linux_emul_find(p, sgp, prefix, path, pbuf, cflag)
else {
sz = &ptr[len] - buf;
*pbuf = stackgap_alloc(sgp, sz + 1);
- error = copyout(buf, *pbuf, sz);
+ if (*pbuf != NULL)
+ error = copyout(buf, *pbuf, sz);
+ else
+ error = ENAMETOOLONG;
free(buf, M_TEMP);
}
diff --git a/sys/compat/linux/linux_util.h b/sys/compat/linux/linux_util.h
index f8775fb..a54ddfd 100644
--- a/sys/compat/linux/linux_util.h
+++ b/sys/compat/linux/linux_util.h
@@ -56,30 +56,28 @@
static __inline caddr_t stackgap_init(void);
static __inline void *stackgap_alloc(caddr_t *, size_t);
+#define szsigcode (*(curproc->p_sysent->sv_szsigcode))
+
static __inline caddr_t
stackgap_init()
{
-#define szsigcode (*(curproc->p_sysent->sv_szsigcode))
return (caddr_t)(PS_STRINGS - szsigcode - SPARE_USRSPACE);
}
-
static __inline void *
stackgap_alloc(sgp, sz)
caddr_t *sgp;
size_t sz;
{
- void *p = (void *) *sgp;
- *sgp += ALIGN(sz);
+ void *p = (void *) *sgp;
+
+ sz = ALIGN(sz);
+ if (*sgp + sz > (caddr_t)(PS_STRINGS - szsigcode))
+ return NULL;
+ *sgp += sz;
return p;
}
-#ifdef DEBUG_LINUX
-#define DPRINTF(a) printf a;
-#else
-#define DPRINTF(a)
-#endif
-
extern const char linux_emul_path[];
int linux_emul_find __P((struct proc *, caddr_t *, const char *, char *,
OpenPOWER on IntegriCloud