Difference between revisions of "Kernel Protections/refcount t"
Jump to navigation
Jump to search
DavidWindsor (talk | contribs) m (Minor language change in Reference Counting API) |
DavidWindsor (talk | contribs) (Change <tt> tags to <code>) |
||
Line 5: | Line 5: | ||
= Reference Counting API = | = Reference Counting API = | ||
HARDENED_ATOMIC introduces a new data type: < | HARDENED_ATOMIC introduces a new data type: <code>refcount_t</code>. This type is to be used for all kernel reference counters. | ||
The following is the kernel reference counting API. Please note that all operations are atomic, unless otherwise specified. | The following is the kernel reference counting API. Please note that all operations are atomic, unless otherwise specified. | ||
;'''< | ;'''<code>REFCOUNT_INIT(unsigned int)</code>''' | ||
: Initialize a < | : Initialize a <code>refcount_t</code> object. | ||
;'''< | ;'''<code>void refcount_set(refcount_t *, unsigned int)</code>''' | ||
: Set a < | : Set a <code>refcount_t</code> object's internal value. | ||
;'''< | ;'''<code>unsigned int refcount_read(refcount_t *)</code>''' | ||
: Returns the < | : Returns the <code>refcount_t</code> object's internal value. | ||
;'''< | ;'''<code>bool refcount_add_not_zero(unsigned int v, refcount_t *r)</code>''' | ||
: Add < | : Add <code>v</code> to <code>r</code>. If <code>r + v</code> causes an overflow, the result of the addition operation is not saved to <code>r</code>. Returns <code>true</code> if the resulting value of <code>r</code> is non-zero, <code>false</code> otherwise. | ||
;'''< | ;'''<code>void refcount_add(unsigned int v, refcount_t *r)</code>''' | ||
: Adds < | : Adds <code>v</code> to <code>r</code> and stores the value in <code>r</code>. | ||
;'''< | ;'''<code>bool refcount_inc_not_zero(refcount_t *r)</code>''' | ||
: Increments < | : Increments <code>r</code> and tests whether <code>r + 1</code> causes an overflow. If an overflow does occur, the result of the increment operation is not saved to <code>r</code>. Will saturate at <code>UINT_MAX</code> and <code>WARN</code>. Returns <code>true</code> if the resulting value of <code>r</code> is non-zero, <code>false</code> otherwise. | ||
;'''< | ;'''<code>void refcount_inc(refcount_t *r)</code>''' | ||
: Increment < | : Increment <code>r</code>. Will saturate at <code>UINT_MAX</code> and <code>WARN</code>. | ||
;'''< | ;'''<code>bool refcount_sub_and_test(unsigned int v, refcount_t *r)</code>''' | ||
: Subtract < | : Subtract <code>v</code> from <code>r</code> and tests whether <code>r - v</code> causes an underflow. If an underflow does occur, the result of the decrement operation is not saved to <code>r</code>. Will fail to decrement when saturated at <code>UINT_MAX</code>. Returns <code>true</code> if the resulting value of <code>r</code> is non-zero, <code>false</code> otherwise. | ||
;'''< | ;'''<code>void refcount_dec(refcount_t *r)</code>''' | ||
: Decrement < | : Decrement <code>r</code>. If <code>r - 1</code> causes an underflow, the result of the decrement operation is not saved to <code>r</code>. Will fail to decrement when saturated at <code>UINT_MAX</code>. | ||
;'''< | ;'''<code>bool refcount_dec_if_one(refcount_t *r)</code>''' | ||
: Attempts to transition < | : Attempts to transition <code>r</code> from 1 to 0. If <code>r</code> is 1, decrement it to 0. Returns <code>true</code> if <code>r</code> was decremented, <code>false</code> otherwise. | ||
;'''< | ;'''<code>bool refcount_dec_not_one(refcount_t *r)</code>''' | ||
: Decrement < | : Decrement <code>r</code> unless the value of <code>r</code> is 1. Returns <code>true</code> if <code>r</code> was decremented, </code>false</code> otherwise. | ||
;'''< | ;'''<code>bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock)</code>''' | ||
: Decrement < | : Decrement <code>r</code> and lock mutex if <code>r</code> becomes 0. Will <code>WARN</code> on underflow and fail to decrement if <code>r</code> is saturated at <code>UINT_MAX</code>. Returns <code>true</code> if <code>r</code> is 0 and mutex is held, <code>false</code> otherwise. | ||
;'''< | ;'''<code>bool refcount_dec_and_lock(refcount_t *r, spinlock_t *s)</code>''' | ||
: Decrement < | : Decrement <code>r</code> and lock spinlock if <code>r</code> becomes 0. Will <code>WARN</code> on underflow and fail to decrement if <code>r</code> is saturated at <code>UINT_MAX</code>. Returns <code>true</code> if <code>r</code> is 0 and spinlock is held, <code>false</code> otherwise. |
Revision as of 12:19, 6 February 2017
Summary
HARDENED_ATOMIC is a kernel self-protection mechanism that greatly helps with the mitigation of use-after-free bugs. It is based off of work done by the PaX Team, originally called PAX_REFCOUNT.
Reference Counting API
HARDENED_ATOMIC introduces a new data type: refcount_t
. This type is to be used for all kernel reference counters.
The following is the kernel reference counting API. Please note that all operations are atomic, unless otherwise specified.
REFCOUNT_INIT(unsigned int)
- Initialize a
refcount_t
object.
void refcount_set(refcount_t *, unsigned int)
- Set a
refcount_t
object's internal value.
unsigned int refcount_read(refcount_t *)
- Returns the
refcount_t
object's internal value.
bool refcount_add_not_zero(unsigned int v, refcount_t *r)
- Add
v
tor
. Ifr + v
causes an overflow, the result of the addition operation is not saved tor
. Returnstrue
if the resulting value ofr
is non-zero,false
otherwise.
void refcount_add(unsigned int v, refcount_t *r)
- Adds
v
tor
and stores the value inr
.
bool refcount_inc_not_zero(refcount_t *r)
- Increments
r
and tests whetherr + 1
causes an overflow. If an overflow does occur, the result of the increment operation is not saved tor
. Will saturate atUINT_MAX
andWARN
. Returnstrue
if the resulting value ofr
is non-zero,false
otherwise.
void refcount_inc(refcount_t *r)
- Increment
r
. Will saturate atUINT_MAX
andWARN
.
bool refcount_sub_and_test(unsigned int v, refcount_t *r)
- Subtract
v
fromr
and tests whetherr - v
causes an underflow. If an underflow does occur, the result of the decrement operation is not saved tor
. Will fail to decrement when saturated atUINT_MAX
. Returnstrue
if the resulting value ofr
is non-zero,false
otherwise.
void refcount_dec(refcount_t *r)
- Decrement
r
. Ifr - 1
causes an underflow, the result of the decrement operation is not saved tor
. Will fail to decrement when saturated atUINT_MAX
.
bool refcount_dec_if_one(refcount_t *r)
- Attempts to transition
r
from 1 to 0. Ifr
is 1, decrement it to 0. Returnstrue
ifr
was decremented,false
otherwise.
bool refcount_dec_not_one(refcount_t *r)
- Decrement
r
unless the value ofr
is 1. Returnstrue
ifr
was decremented, false otherwise.
bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock)
- Decrement
r
and lock mutex ifr
becomes 0. WillWARN
on underflow and fail to decrement ifr
is saturated atUINT_MAX
. Returnstrue
ifr
is 0 and mutex is held,false
otherwise.
bool refcount_dec_and_lock(refcount_t *r, spinlock_t *s)
- Decrement
r
and lock spinlock ifr
becomes 0. WillWARN
on underflow and fail to decrement ifr
is saturated atUINT_MAX
. Returnstrue
ifr
is 0 and spinlock is held,false
otherwise.