inline ASM helpers for proving bounds checks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



hi -

i was chatting with a few people off-list and mentioned that i wrote a couple helpers for ensuring ints are bounds-checked for things like array accesses. i used inline asm to prevent the compiler from doing things like copying the register, checking the copy, and using the original for the indexing operation.

i'll paste them below.

if this is the sort of thing that would be nice in one of the helper header files, let me know where you'd like it and i can send a patch.

thanks,

barret


/*
 * Returns pointer to idx element in the array arr, made of
 * arr_sz number of elements:
 *
 *      if (!arr)
 *              return NULL;
 *      if (idx >= arr_sz)
* return NULL;
 *      return &arr[idx];
 */
#define BOUNDED_ARRAY_IDX(arr, arr_sz, idx) ({      \
        typeof(&(arr)[0]) ___arr = arr;             \
        u64 ___idx = idx;                           \
        if (___arr) {                               \
                asm volatile("if %[__idx] >= %[__bound] goto 1f;\
                              %[__idx] *= %[__size];            \
                              %[__arr] += %[__idx];             \
                              goto 2f;                          \
                              1:;                               \
                              %[__arr] = 0;                     \
                              2:                                \
                              "                                 \
                             : [__arr]"+r"(___arr), [__idx]"+r"(___idx)\
                             : [__bound]"i"((arr_sz)),                 \
                               [__size]"i"(sizeof(typeof((arr)[0])))   \
                             : "cc");                                  \
        }                                                              \
        ___arr;                                                        \
})


/*
 * Forces the verifier to ensure idx is less than bound.  Returns 0 if
 * idx is not less than bound.
 */
static inline size_t bounded_idx(size_t idx, int bound)
{
        asm volatile("if %[__idx] < %[__bound] goto 1f; \
                      %[__idx] = 0;                     \
                      1:"
                      : [__idx]"+r"(idx) : [__bound]"i"(bound) : "cc");
        return idx;
}

this one is a little simpler, but also more dangerous. if the int isn't actually bounded, it'll set it to 0, which might not be what you want since you can't tell the difference between "out of bounds" and "actually 0". i use this in a place where i know the int is bounded (barring other horrendous bugs) and can't check.





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux