svn commit: r296306 - vendor-sys/illumos/dist/uts/common/dtrace
Mark Johnston
markj at FreeBSD.org
Wed Mar 2 05:43:18 UTC 2016
Author: markj
Date: Wed Mar 2 05:43:16 2016
New Revision: 296306
URL: https://svnweb.freebsd.org/changeset/base/296306
Log:
6604 harden DIF bounds checking
Author: Bryan Cantrill <bryan at joyent.com>
Reviewed by: Alex Wilson <alex.wilson at joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney at joyent.com>
Reviewed by: Dan McDonald <danmcd at omniti.com>
Approved by: Robert Mustacchi <rm at joyent.com>
illumos/illumos-gate at 1c0cef67dba05c477dba779bc99224693e809a14
Modified:
vendor-sys/illumos/dist/uts/common/dtrace/dtrace.c
Modified: vendor-sys/illumos/dist/uts/common/dtrace/dtrace.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/dtrace/dtrace.c Wed Mar 2 05:24:55 2016 (r296305)
+++ vendor-sys/illumos/dist/uts/common/dtrace/dtrace.c Wed Mar 2 05:43:16 2016 (r296306)
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2016, Joyent, Inc. All rights reserved.
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
*/
@@ -567,10 +567,12 @@ dtrace_error(uint32_t *counter)
* Use the DTRACE_LOADFUNC macro to define functions for each of loading a
* uint8_t, a uint16_t, a uint32_t and a uint64_t.
*/
+/* BEGIN CSTYLED */
DTRACE_LOADFUNC(8)
DTRACE_LOADFUNC(16)
DTRACE_LOADFUNC(32)
DTRACE_LOADFUNC(64)
+/* END CSTYLED */
static int
dtrace_inscratch(uintptr_t dest, size_t size, dtrace_mstate_t *mstate)
@@ -654,6 +656,7 @@ dtrace_canstore(uint64_t addr, size_t sz
uintptr_t base = (uintptr_t)dstate->dtds_base +
(dstate->dtds_hashsize * sizeof (dtrace_dynhash_t));
uintptr_t chunkoffs;
+ dtrace_dynvar_t *dvar;
/*
* Before we assume that we can store here, we need to make
@@ -670,6 +673,8 @@ dtrace_canstore(uint64_t addr, size_t sz
*
* (3) Not span a chunk boundary
*
+ * (4) Not be in the tuple space of a dynamic variable
+ *
*/
if (addr < base)
return (0);
@@ -682,6 +687,15 @@ dtrace_canstore(uint64_t addr, size_t sz
if (chunkoffs + sz > dstate->dtds_chunksize)
return (0);
+ dvar = (dtrace_dynvar_t *)((uintptr_t)addr - chunkoffs);
+
+ if (dvar->dtdv_hashval == DTRACE_DYNHASH_FREE)
+ return (0);
+
+ if (chunkoffs < sizeof (dtrace_dynvar_t) +
+ ((dvar->dtdv_tuple.dtt_nkeys - 1) * sizeof (dtrace_key_t)))
+ return (0);
+
return (1);
}
@@ -5337,6 +5351,12 @@ next:
ipaddr_t ip4;
uint8_t *ptr8, val;
+ if (!dtrace_canload(tupregs[argi].dttk_value,
+ sizeof (ipaddr_t), mstate, vstate)) {
+ regs[rd] = NULL;
+ break;
+ }
+
/*
* Safely load the IPv4 address.
*/
@@ -5390,6 +5410,12 @@ next:
* just the IPv4 string is returned for inet_ntoa6.
*/
+ if (!dtrace_canload(tupregs[argi].dttk_value,
+ sizeof (struct in6_addr), mstate, vstate)) {
+ regs[rd] = NULL;
+ break;
+ }
+
/*
* Safely load the IPv6 address.
*/
@@ -5864,6 +5890,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo,
ASSERT(id >= DIF_VAR_OTHER_UBASE);
id -= DIF_VAR_OTHER_UBASE;
+ VERIFY(id < vstate->dtvs_nglobals);
svar = vstate->dtvs_globals[id];
ASSERT(svar != NULL);
v = &svar->dtsv_var;
@@ -5955,7 +5982,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo,
ASSERT(id >= DIF_VAR_OTHER_UBASE);
id -= DIF_VAR_OTHER_UBASE;
- ASSERT(id < vstate->dtvs_nlocals);
+ VERIFY(id < vstate->dtvs_nlocals);
ASSERT(vstate->dtvs_locals != NULL);
svar = vstate->dtvs_locals[id];
@@ -6033,6 +6060,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo,
id = DIF_INSTR_VAR(instr);
ASSERT(id >= DIF_VAR_OTHER_UBASE);
id -= DIF_VAR_OTHER_UBASE;
+ VERIFY(id < vstate->dtvs_ntlocals);
key = &tupregs[DIF_DTR_NREGS];
key[0].dttk_value = (uint64_t)id;
@@ -6146,8 +6174,10 @@ dtrace_dif_emulate(dtrace_difo_t *difo,
if (DIF_INSTR_OP(instr) == DIF_OP_LDTAA) {
DTRACE_TLS_THRKEY(key[nkeys].dttk_value);
key[nkeys++].dttk_size = 0;
+ VERIFY(id < vstate->dtvs_ntlocals);
v = &vstate->dtvs_tlocals[id];
} else {
+ VERIFY(id < vstate->dtvs_nglobals);
v = &vstate->dtvs_globals[id]->dtsv_var;
}
@@ -6186,8 +6216,10 @@ dtrace_dif_emulate(dtrace_difo_t *difo,
if (DIF_INSTR_OP(instr) == DIF_OP_STTAA) {
DTRACE_TLS_THRKEY(key[nkeys].dttk_value);
key[nkeys++].dttk_size = 0;
+ VERIFY(id < vstate->dtvs_ntlocals);
v = &vstate->dtvs_tlocals[id];
} else {
+ VERIFY(id < vstate->dtvs_nglobals);
v = &vstate->dtvs_globals[id]->dtsv_var;
}
@@ -9009,6 +9041,7 @@ dtrace_difo_validate(dtrace_difo_t *dp,
int (*efunc)(uint_t pc, const char *, ...) = dtrace_difo_err;
int kcheckload;
uint_t pc;
+ int maxglobal = -1, maxlocal = -1, maxtlocal = -1;
kcheckload = cr == NULL ||
(vstate->dtvs_state->dts_cred.dcr_visible & DTRACE_CRV_KERNEL) == 0;
@@ -9338,6 +9371,9 @@ dtrace_difo_validate(dtrace_difo_t *dp,
switch (v->dtdv_scope) {
case DIFV_SCOPE_GLOBAL:
+ if (maxglobal == -1 || ndx > maxglobal)
+ maxglobal = ndx;
+
if (ndx < vstate->dtvs_nglobals) {
dtrace_statvar_t *svar;
@@ -9348,11 +9384,17 @@ dtrace_difo_validate(dtrace_difo_t *dp,
break;
case DIFV_SCOPE_THREAD:
+ if (maxtlocal == -1 || ndx > maxtlocal)
+ maxtlocal = ndx;
+
if (ndx < vstate->dtvs_ntlocals)
existing = &vstate->dtvs_tlocals[ndx];
break;
case DIFV_SCOPE_LOCAL:
+ if (maxlocal == -1 || ndx > maxlocal)
+ maxlocal = ndx;
+
if (ndx < vstate->dtvs_nlocals) {
dtrace_statvar_t *svar;
@@ -9401,6 +9443,37 @@ dtrace_difo_validate(dtrace_difo_t *dp,
}
}
+ for (pc = 0; pc < dp->dtdo_len && err == 0; pc++) {
+ dif_instr_t instr = dp->dtdo_buf[pc];
+
+ uint_t v = DIF_INSTR_VAR(instr);
+ uint_t op = DIF_INSTR_OP(instr);
+
+ switch (op) {
+ case DIF_OP_LDGS:
+ case DIF_OP_LDGAA:
+ case DIF_OP_STGS:
+ case DIF_OP_STGAA:
+ if (v > DIF_VAR_OTHER_UBASE + maxglobal)
+ err += efunc(pc, "invalid variable %u\n", v);
+ break;
+ case DIF_OP_LDTS:
+ case DIF_OP_LDTAA:
+ case DIF_OP_STTS:
+ case DIF_OP_STTAA:
+ if (v > DIF_VAR_OTHER_UBASE + maxtlocal)
+ err += efunc(pc, "invalid variable %u\n", v);
+ break;
+ case DIF_OP_LDLS:
+ case DIF_OP_STLS:
+ if (v > DIF_VAR_OTHER_UBASE + maxlocal)
+ err += efunc(pc, "invalid variable %u\n", v);
+ break;
+ default:
+ break;
+ }
+ }
+
return (err);
}
More information about the svn-src-all
mailing list