Kernel Protections/refcount t

From Linux Kernel Security Subsystem
Revision as of 11:20, 4 February 2017 by DavidWindsor (talk | contribs) (Minor language change in Reference Counting API)
Jump to navigation Jump to search

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 to r. If r + v causes an overflow, the result of the addition operation is not saved to r. Returns true if the resulting value of r is non-zero, false otherwise.
void refcount_add(unsigned int v, refcount_t *r)
Adds v to r and stores the value in r.
bool refcount_inc_not_zero(refcount_t *r)
Increments r and tests whether r + 1 causes an overflow. If an overflow does occur, the result of the increment operation is not saved to r. Will saturate at UINT_MAX and WARN. Returns true if the resulting value of r is non-zero, false otherwise.
void refcount_inc(refcount_t *r)
Increment r. Will saturate at UINT_MAX and WARN.
bool refcount_sub_and_test(unsigned int v, refcount_t *r)
Subtract v from r and tests whether r - v causes an underflow. If an underflow does occur, the result of the decrement operation is not saved to r. Will fail to decrement when saturated at UINT_MAX. Returns true if the resulting value of r is non-zero, false otherwise.
void refcount_dec(refcount_t *r)
Decrement r. If r - 1 causes an underflow, the result of the decrement operation is not saved to r. Will fail to decrement when saturated at UINT_MAX.
bool refcount_dec_if_one(refcount_t *r)
Attempts to transition r from 1 to 0. If r is 1, decrement it to 0. Returns true if r was decremented, false otherwise.
bool refcount_dec_not_one(refcount_t *r)
Decrement r unless the value of r is 1. Returns true if r was decremented, false otherwise.
bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock)
Decrement r and lock mutex if r becomes 0. Will WARN on underflow and fail to decrement if r is saturated at UINT_MAX. Returns true if r is 0 and mutex is held, false otherwise.
bool refcount_dec_and_lock(refcount_t *r, spinlock_t *s)
Decrement r and lock spinlock if r becomes 0. Will WARN on underflow and fail to decrement if r is saturated at UINT_MAX. Returns true if r is 0 and spinlock is held, false otherwise.