Changeset 94795812 in mainline


Ignore:
Timestamp:
2012-11-05T21:52:35Z (12 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2d53cfc, 33c2952, efdfebc
Parents:
0941e9ae
Message:

Check for dangerous unsigned integer overflows in check_area_conflicts().

  • Rename overflows_add() to overflows_into_positive().
  • Introduce overflows() for simple sum overflow tests.
Location:
kernel/generic
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/macros.h

    r0941e9ae r94795812  
    130130            | ((((uint64_t) (up)) & UINT32_C(0xffffffff)) << 32))
    131131
    132 /* Test for result wrap-around into positive numbers. */
    133 #define overflows_add(a, b) \
    134         (((a) + (b) < (a)) && ((a) + (b)))
     132/* Test for sum overflow. */
     133#define overflows(a, b) \
     134        ((a) + (b) < (a))
     135
     136/* Test for sum overflow into positive numbers. */
     137#define overflows_into_positive(a, b)   \
     138        (overflows((a), (b)) && ((a) + (b) > 0))
    135139
    136140/** Pseudorandom generator
  • kernel/generic/src/mm/as.c

    r0941e9ae r94795812  
    299299        ASSERT((addr % PAGE_SIZE) == 0);
    300300        ASSERT(mutex_locked(&as->lock));
    301         ASSERT(!overflows_add(addr, P2SZ(count)));
     301
     302        /*
     303         * If the addition of the supposed area address and size overflows,
     304         * report conflict.
     305         */
     306        if (overflows_into_positive(addr, P2SZ(count)))
     307                return false;
    302308       
    303309        /*
     
    331337                        mutex_lock(&area->lock);
    332338
    333                         /* If at least one of the two areas are protected
     339                        /*
     340                         * If at least one of the two areas are protected
    334341                         * by the AS_AREA_GUARD flag then we must be sure
    335342                         * that they are separated by at least one unmapped
     
    339346                            (area->flags & AS_AREA_GUARD)) ? 1 : 0;
    340347                       
     348                        /*
     349                         * The area comes from the left neighbour node, which
     350                         * means that there already are some areas in the leaf
     351                         * node, which in turn means that adding gp is safe and
     352                         * will not cause an integer overflow.
     353                         */
    341354                        if (overlaps(addr, P2SZ(count), area->base,
    342355                            P2SZ(area->pages + gp))) {
     
    354367               
    355368                if (area != avoid) {
     369                        int gp;
     370
    356371                        mutex_lock(&area->lock);
    357372
    358                         int const gp = (guarded ||
    359                             (area->flags & AS_AREA_GUARD)) ? 1 : 0;
     373                        gp = (guarded || (area->flags & AS_AREA_GUARD)) ? 1 : 0;
     374                        if (gp && overflows(addr, P2SZ(count))) {
     375                                /*
     376                                 * Guard page not needed if the supposed area
     377                                 * is adjacent to the end of the address space.
     378                                 * We already know that the following test is
     379                                 * going to fail...
     380                                 */
     381                                gp--;
     382                        }
    360383                       
    361384                        if (overlaps(addr, P2SZ(count + gp), area->base,
     
    373396        for (i = 0; i < leaf->keys; i++) {
    374397                area = (as_area_t *) leaf->value[i];
     398                int agp;
     399                int gp;
    375400               
    376401                if (area == avoid)
     
    379404                mutex_lock(&area->lock);
    380405
    381                 int const gp = (guarded ||
    382                     (area->flags & AS_AREA_GUARD)) ? 1 : 0;
     406                gp = (guarded || (area->flags & AS_AREA_GUARD)) ? 1 : 0;
     407                agp = gp;
     408
     409                /*
     410                 * Sanitize the two possible unsigned integer overflows.
     411                 */
     412                if (gp && overflows(addr, P2SZ(count)))
     413                        gp--;
     414                if (agp && overflows(area->base, P2SZ(area->pages)))
     415                        agp--;
    383416
    384417                if (overlaps(addr, P2SZ(count + gp), area->base,
    385                     P2SZ(area->pages + gp))) {
     418                    P2SZ(area->pages + agp))) {
    386419                        mutex_unlock(&area->lock);
    387420                        return false;
     
    533566        }
    534567
    535         if (overflows_add(*base, size))
     568        if (overflows_into_positive(*base, size))
    536569                return NULL;
    537570
     
    816849                 */
    817850
    818                 if (overflows_add(address, P2SZ(pages)))
     851                if (overflows_into_positive(address, P2SZ(pages)))
    819852                        return EINVAL;
    820853
Note: See TracChangeset for help on using the changeset viewer.