mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-23 03:06:48 +00:00
dtrace: Fix a kernel panic in printm()
When using printm(), one should always pass a scratch pointer to it. This is achieved by calling printm with memref BEGIN { printm(fixed_len, memref(ptr, var_len)); } which will return a pointer to the DTrace scratch space of size sizeof(uintptr_t) * 2. However, one can easily call printm() as follows BEGIN { printm(10, (void *)NULL); } and panic the kernel as a result. This commit does two things: (1) adds a new macro DTRACE_INSCRATCHPTR(mstate, ptr, howmany) which checks if a certain pointer is in the DTrace scratch space; (2) uses DTRACE_INSCRATCHPTR() to implement a check on printm()'s DIFO return value in order to avoid the panic and sets CPU_DTRACE_BADADDR if the address is not in the scratch space. Reviewed by: markj MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D41722
This commit is contained in:
parent
56e3123fc8
commit
8527bb2aee
|
@ -515,6 +515,11 @@ do { \
|
|||
((mstate)->dtms_scratch_base + (mstate)->dtms_scratch_size - \
|
||||
(mstate)->dtms_scratch_ptr >= (alloc_sz))
|
||||
|
||||
#define DTRACE_INSCRATCHPTR(mstate, ptr, howmany) \
|
||||
((ptr) >= (mstate)->dtms_scratch_base && \
|
||||
(ptr) <= \
|
||||
((mstate)->dtms_scratch_base + (mstate)->dtms_scratch_size - (howmany)))
|
||||
|
||||
#define DTRACE_LOADFUNC(bits) \
|
||||
/*CSTYLED*/ \
|
||||
uint##bits##_t \
|
||||
|
@ -7739,9 +7744,24 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
|
|||
}
|
||||
|
||||
case DTRACEACT_PRINTM: {
|
||||
/* The DIF returns a 'memref'. */
|
||||
/*
|
||||
* printm() assumes that the DIF returns a
|
||||
* pointer returned by memref(). memref() is a
|
||||
* subroutine that is used to get around the
|
||||
* single-valued returns of DIF and is assumed
|
||||
* to always be allocated in the scratch space.
|
||||
* Therefore, we need to validate that the
|
||||
* pointer given to printm() is in the scratch
|
||||
* space in order to avoid a potential panic.
|
||||
*/
|
||||
uintptr_t *memref = (uintptr_t *)(uintptr_t) val;
|
||||
|
||||
if (!DTRACE_INSCRATCHPTR(&mstate,
|
||||
(uintptr_t)memref, 2 * sizeof(uintptr_t))) {
|
||||
*flags |= CPU_DTRACE_BADADDR;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the size from the memref. */
|
||||
size = memref[1];
|
||||
|
||||
|
|
Loading…
Reference in a new issue