Ejemplo n.º 1
0
/*
 * XDR an indirect pointer
 * xdr_reference is for recursively translating a structure that is
 * referenced by a pointer inside the structure that is currently being
 * translated.  pp references a pointer to storage. If *pp is null
 * the  necessary storage is allocated.
 * size is the sizeof the referneced structure.
 * proc is the routine to handle the referenced structure.
 */
bool_t
sec_xdr_reference(XDR *xdrs, uint8_t **pp, u_int size, xdrproc_t proc)
{
    uint8_t *loc = pp ? *pp : NULL;
    bool_t stat;

    if (size > 1024) {
        // Structure suspiciously large: 1024 is arbitrary upper bound
        // for struct sizes (non-nested size)
        assert(FALSE);
        return (FALSE);
    }
    uint8_t obj[size];

    bool_t sizeof_alloc = sec_xdr_arena_size_allocator(xdrs);

    if (loc == NULL)
            switch (xdrs->x_op) {
            case XDR_FREE:
                return (TRUE);
            case XDR_DECODE:
                {
                    if (!sec_mem_alloc(xdrs, size, &loc))
                        return (FALSE);
					if (!loc) {
                        memset(obj, 0, size);
						loc = &obj[0];
                    }
					if (!sizeof_alloc && pp != NULL)
						*pp = loc;
					break;
                }
            case XDR_ENCODE:
                break;
            }

    stat = (*proc)(xdrs, loc, 0);

    if (xdrs->x_op == XDR_FREE) {
        sec_mem_free(xdrs, loc, size);
        if(pp) {
            *pp = NULL;
        }
    }
    return (stat);
}
Ejemplo n.º 2
0
/*
 * XDR an array of arbitrary elements
 * *addrp is a pointer to the array, *sizep is the number of elements.
 * If addrp is NULL (*sizep * elsize) bytes are allocated.
 * elsize is the size (in bytes) of each element, and elproc is the
 * xdr procedure to call to handle each element of the array.
 */
bool_t
sec_xdr_array(XDR *xdrs, uint8_t **addrp, u_int *sizep, u_int maxsize, u_int elsize, xdrproc_t elproc)
{
    u_int i;
    bool_t stat = TRUE;

    u_int c = sizep ? *sizep : 0;  /* the actual element count */
    /* like strings, arrays are really counted arrays */
    if (!xdr_u_int(xdrs, &c))
        return (FALSE);

    if (sizep && (xdrs->x_op == XDR_DECODE))
        *sizep = c;

    // XXX/cs on decode if c == 0 return

    if ((c > maxsize || UINT_MAX/elsize < c) && (xdrs->x_op != XDR_FREE))
        return (FALSE);

    if (elsize > 1024) {
        // Structure suspiciously large: 1024 is arbitrary upper bound
        // for struct sizes (non-nested size)
        assert(FALSE);
        return (FALSE);
    }

    u_int nodesize = c * elsize;
    uint8_t *target = addrp ? *addrp : NULL;

    uint8_t obj[elsize];

    bool_t sizeof_alloc = sec_xdr_arena_size_allocator(xdrs);

    /*
     * if we are deserializing, we may need to allocate an array.
     * We also save time by checking for a null array if we are freeing.
     */
    if (target == NULL) {
        switch (xdrs->x_op) {
        case XDR_DECODE:
            if (c == 0)
                return (TRUE);
            if (!sec_mem_alloc(xdrs, nodesize, &target))
                return (FALSE);
            if (!target)
                target = &obj[0];
            if (!sizeof_alloc)
                *addrp = target;
            break;

        case XDR_FREE:
            return (TRUE);

        case XDR_ENCODE:
            break;
        }
    }

    /*
     * now we xdr each element of array
     */
    for (i = 0; (i < c) && stat; i++) {
        if ((xdrs->x_op == XDR_DECODE) && sizeof_alloc)
            memset(obj, 0, elsize);
        stat = (*elproc)(xdrs, target, 0);
        if ((xdrs->x_op == XDR_ENCODE) || !sizeof_alloc)
            target += elsize;
    }

    /*
     * the array may need freeing
     */
    if (xdrs->x_op == XDR_FREE) {
        sec_mem_free(xdrs, *addrp, nodesize);
        *addrp = NULL;
    }
    return (stat);
}