Exemple #1
0
/* This implements svn_editor_cb_copy_t */
static svn_error_t *
copy_cb(void *baton,
        const char *src_relpath,
        svn_revnum_t src_revision,
        const char *dst_relpath,
        svn_revnum_t replaces_rev,
        apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = baton;
    const char *src_fspath = FSPATH(src_relpath, scratch_pool);
    const char *dst_fspath = FSPATH(dst_relpath, scratch_pool);
    svn_fs_root_t *root;
    svn_fs_root_t *src_root;

    SVN_ERR(get_root(&root, eb));

    /* Check if we can we replace the maybe-specified destination (revision).  */
    if (SVN_IS_VALID_REVNUM(replaces_rev))
    {
        SVN_ERR(can_modify(root, dst_fspath, replaces_rev, scratch_pool));
        SVN_ERR(svn_fs_delete(root, dst_fspath, scratch_pool));
    }
    else
    {
        SVN_ERR(can_create(root, dst_fspath, scratch_pool));
    }

    SVN_ERR(svn_fs_revision_root(&src_root, svn_fs_root_fs(root), src_revision,
                                 scratch_pool));
    SVN_ERR(svn_fs_copy(src_root, src_fspath, root, dst_fspath, scratch_pool));
    svn_fs_close_root(src_root);

    return SVN_NO_ERROR;
}
Exemple #2
0
/* This implements svn_editor_cb_alter_file_t */
static svn_error_t *
alter_file_cb(void *baton,
              const char *relpath,
              svn_revnum_t revision,
              apr_hash_t *props,
              const svn_checksum_t *checksum,
              svn_stream_t *contents,
              apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = baton;
    const char *fspath = FSPATH(relpath, scratch_pool);
    svn_fs_root_t *root;

    SVN_ERR(get_root(&root, eb));
    SVN_ERR(can_modify(root, fspath, revision, scratch_pool));

    if (contents != NULL)
    {
        SVN_ERR_ASSERT(checksum != NULL);
        SVN_ERR(set_text(root, fspath, checksum, contents,
                         eb->cancel_func, eb->cancel_baton, scratch_pool));
    }

    if (props != NULL)
    {
        SVN_ERR(alter_props(root, fspath, props, scratch_pool));
    }

    return SVN_NO_ERROR;
}
Exemple #3
0
/* This implements svn_editor_cb_add_file_t */
static svn_error_t *
add_file_cb(void *baton,
            const char *relpath,
            const svn_checksum_t *checksum,
            svn_stream_t *contents,
            apr_hash_t *props,
            svn_revnum_t replaces_rev,
            apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = baton;
    const char *fspath = FSPATH(relpath, scratch_pool);
    svn_fs_root_t *root;

    SVN_ERR(get_root(&root, eb));

    if (SVN_IS_VALID_REVNUM(replaces_rev))
    {
        SVN_ERR(can_modify(root, fspath, replaces_rev, scratch_pool));
        SVN_ERR(svn_fs_delete(root, fspath, scratch_pool));
    }
    else
    {
        SVN_ERR(can_create(root, fspath, scratch_pool));
    }

    SVN_ERR(svn_fs_make_file(root, fspath, scratch_pool));

    SVN_ERR(set_text(root, fspath, checksum, contents,
                     eb->cancel_func, eb->cancel_baton, scratch_pool));
    SVN_ERR(add_new_props(root, fspath, props, scratch_pool));

    return SVN_NO_ERROR;
}
Exemple #4
0
/* This implements svn_editor_cb_add_directory_t */
static svn_error_t *
add_directory_cb(void *baton,
                 const char *relpath,
                 const apr_array_header_t *children,
                 apr_hash_t *props,
                 svn_revnum_t replaces_rev,
                 apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = baton;
    const char *fspath = FSPATH(relpath, scratch_pool);
    svn_fs_root_t *root;

    /* Note: we ignore CHILDREN. We have no "incomplete" state to worry about,
       so we don't need to be aware of what children will be created.  */

    SVN_ERR(get_root(&root, eb));

    if (SVN_IS_VALID_REVNUM(replaces_rev))
    {
        SVN_ERR(can_modify(root, fspath, replaces_rev, scratch_pool));
        SVN_ERR(svn_fs_delete(root, fspath, scratch_pool));
    }
    else
    {
        SVN_ERR(can_create(root, fspath, scratch_pool));
    }

    SVN_ERR(svn_fs_make_dir(root, fspath, scratch_pool));
    SVN_ERR(add_new_props(root, fspath, props, scratch_pool));

    return SVN_NO_ERROR;
}
Exemple #5
0
/* This implements svn_editor_cb_move_t */
static svn_error_t *
move_cb(void *baton,
        const char *src_relpath,
        svn_revnum_t src_revision,
        const char *dst_relpath,
        svn_revnum_t replaces_rev,
        apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = baton;
    const char *src_fspath = FSPATH(src_relpath, scratch_pool);
    const char *dst_fspath = FSPATH(dst_relpath, scratch_pool);
    svn_fs_root_t *root;
    svn_fs_root_t *src_root;

    SVN_ERR(get_root(&root, eb));

    /* Check if we delete the specified source (revision), and can we replace
       the maybe-specified destination (revision).  */
    SVN_ERR(can_modify(root, src_fspath, src_revision, scratch_pool));
    if (SVN_IS_VALID_REVNUM(replaces_rev))
    {
        SVN_ERR(can_modify(root, dst_fspath, replaces_rev, scratch_pool));
        SVN_ERR(svn_fs_delete(root, dst_fspath, scratch_pool));
    }
    else
    {
        SVN_ERR(can_create(root, dst_fspath, scratch_pool));
    }

    /* ### would be nice to have svn_fs_move()  */

    /* Copy the src to the dst. */
    SVN_ERR(svn_fs_revision_root(&src_root, svn_fs_root_fs(root), src_revision,
                                 scratch_pool));
    SVN_ERR(svn_fs_copy(src_root, src_fspath, root, dst_fspath, scratch_pool));
    svn_fs_close_root(src_root);

    /* Notice: we're deleting the src repos path from the dst root. */
    SVN_ERR(svn_fs_delete(root, src_fspath, scratch_pool));

    return SVN_NO_ERROR;
}
Exemple #6
0
/* This implements svn_editor_cb_delete_t */
static svn_error_t *
delete_cb(void *baton,
          const char *relpath,
          svn_revnum_t revision,
          apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = baton;
    const char *fspath = FSPATH(relpath, scratch_pool);
    svn_fs_root_t *root;

    SVN_ERR(get_root(&root, eb));
    SVN_ERR(can_modify(root, fspath, revision, scratch_pool));

    SVN_ERR(svn_fs_delete(root, fspath, scratch_pool));

    return SVN_NO_ERROR;
}
Exemple #7
0
/* This implements svn_editor_cb_add_symlink_t */
static svn_error_t *
add_symlink_cb(void *baton,
               const char *relpath,
               const char *target,
               apr_hash_t *props,
               svn_revnum_t replaces_rev,
               apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = baton;
    const char *fspath = FSPATH(relpath, scratch_pool);
    svn_fs_root_t *root;

    SVN_ERR(get_root(&root, eb));

    if (SVN_IS_VALID_REVNUM(replaces_rev))
    {
        SVN_ERR(can_modify(root, fspath, replaces_rev, scratch_pool));
        SVN_ERR(svn_fs_delete(root, fspath, scratch_pool));
    }
    else
    {
        SVN_ERR(can_create(root, fspath, scratch_pool));
    }

    /* ### we probably need to construct a file with specific contents
       ### (until the FS grows some symlink APIs)  */
#if 0
    SVN_ERR(svn_fs_make_file(root, fspath, scratch_pool));
    SVN_ERR(svn_fs_apply_text(&fs_contents, root, fspath,
                              NULL /* result_checksum */,
                              scratch_pool));
    /* ### SVN_ERR(svn_stream_printf(fs_contents, ..., scratch_pool));  */
    apr_hash_set(props, SVN_PROP_SPECIAL, APR_HASH_KEY_STRING,
                 SVN_PROP_SPECIAL_VALUE);

    SVN_ERR(add_new_props(root, fspath, props, scratch_pool));
#endif

    SVN__NOT_IMPLEMENTED();
}
Exemple #8
0
/* This implements svn_editor_cb_alter_directory_t */
static svn_error_t *
alter_directory_cb(void *baton,
                   const char *relpath,
                   svn_revnum_t revision,
                   const apr_array_header_t *children,
                   apr_hash_t *props,
                   apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = baton;
    const char *fspath = FSPATH(relpath, scratch_pool);
    svn_fs_root_t *root;

    /* Note: we ignore CHILDREN. We have no "incomplete" state to worry about,
       so we don't need to be aware of what children will be created.  */

    SVN_ERR(get_root(&root, eb));
    SVN_ERR(can_modify(root, fspath, revision, scratch_pool));

    if (props)
        SVN_ERR(alter_props(root, fspath, props, scratch_pool));

    return SVN_NO_ERROR;
}
Exemple #9
0
/*
 * @func encrypt_or_clear_ip_sections modifies the content of some sections. 
 * 1. If section content cannot be modified without disrupting enclave signing or loading flows 
 *    then section content is not modified
 * 2. Allocable sections (copied to application address space at shared object's load time)
 *    are encrypted.
 * 3. The content of sections that are not allocable is zeroed
 * @param IN pcl_data_t* dat, ELF data
 * @param IN uint8_t* key, the AES key for GCM encrypt
 * @param INOUT uint8_t* elf_buf, base address of ELF binary buffer 
 * @param OUT pcl_table_t* tbl, pointer to PCL table 
 * @param OUT uint32_t* num_rvas_out, total number of sections that are encrypted
 * @param bool debug, true iff enclave is requried to support debug
 * @return encip_ret_e:
 * ENCIP_ERROR_ENCSECS_INVALID_PARAM any input parameter is NULL
 * PCL_MAX_NUM_ENCRYPTED_SECTIONS if out of entires in PCL table
 * Respective error results in case any of the functions encrypt or update_flags fail. 
 * ENCIP_SUCCESS if success
 */
static encip_ret_e encrypt_or_clear_ip_sections(
                IN pcl_data_t* dat, 
                IN uint8_t* key,
                INOUT uint8_t* elf_buf, 
                size_t elf_size,
                OUT pcl_table_t* tbl, 
                OUT uint32_t* num_rvas_out, 
                bool debug)
{
    if(
       NULL == dat     ||
       NULL == key     ||
       NULL == elf_buf || 
       NULL == tbl     || 
       NULL == num_rvas_out)
        return ENCIP_ERROR_ENCSECS_INVALID_PARAM;
    uint32_t num_rvas = 0;
    // Go over sections headers to find sections to encrypt or clear: 
    char* sec_name = NULL;
    for(uint16_t secidx = 1; secidx < dat->nsections; secidx++)
    {
        if(dat->elf_sec[secidx].sh_name >= dat->elf_sec[dat->shstrndx].sh_size)
            return ENCIP_ERROR_PARSE_ELF_INVALID_IMAGE;
        sec_name = dat->sections_names + dat->elf_sec[secidx].sh_name;    
        /*
         * Verifying string starts before end of section. Assuming (but not checking) 
         * that string ends before end of section. Additional check will complicate code.
         * Assuming the platform this application is running on is not compromized. 
         */
        if((uint8_t*)sec_name > elf_buf + elf_size) 
            return ENCIP_ERROR_PARSE_ELF_INVALID_IMAGE;
        if(can_modify(sec_name, debug))
        {
            uint8_t* va = (uint8_t *)(elf_buf + dat->elf_sec[secidx].sh_offset);
            size_t size = dat->elf_sec[secidx].sh_size;
            if((va >= elf_buf + elf_size) ||
               (va + size < va)           ||
               (va + size > elf_buf + elf_size))
                return ENCIP_ERROR_PARSE_ELF_INVALID_IMAGE;
            // If section is allocable (mapped into process's virtual memory), decrypt it: 
            if(SHF_ALLOC & dat->elf_sec[secidx].sh_flags)
            {
                
                if(PCL_MAX_NUM_ENCRYPTED_SECTIONS <= num_rvas)
                {
                    /* 
                     * No more empty entries in PCL table. 
                     * To fix - redefine PCL_MAX_NUM_ENCRYPTED_SECTIONS in pcl_common.h
                     */
                    printf("Error: No more empty entries in Intel(R) SGX PCL table\n");
                    printf("To fix - redefine PCL_MAX_NUM_ENCRYPTED_SECTIONS in pcl_common.h\n");
                    return ENCIP_ERROR_ENCSECS_RVAS_OVERFLOW;
                }
                            
                if(PCL_GCM_NUM_BLOCKS(size) > PCL_GCM_MAX_NUM_BLOCKS)
                {
                    /*
                     * Size in 16-bytes-blocks exceeds (2^32 - 2).
                     * Only happen if cipher-text size is ~64GB.
                     */
                    return ENCIP_ERROR_ENCSECS_COUNTER_OVERFLOW;
                }

                uint8_t* iv = (uint8_t*)&(tbl->rvas_sizes_tags_ivs[num_rvas].iv.val);
                encip_ret_e ret = init_random_iv(iv);
                if(ENCIP_ERROR(ret))
                    return ret;

                uint8_t* tag = (uint8_t*)&(tbl->rvas_sizes_tags_ivs[num_rvas].tag);
                ret = gcm_encrypt(va, size, NULL, 0, (uint8_t *)key, iv, va, tag);
                if(ENCIP_ERROR(ret))
                {
                    printf("Failed to gcm-encrypt section %s\n", sec_name);
                    return ret;
                }

                // Insert entry to table: 
                tbl->rvas_sizes_tags_ivs[num_rvas].rva  = dat->elf_sec[secidx].sh_addr;
                tbl->rvas_sizes_tags_ivs[num_rvas].size = size;

                // Update flags to writable: 
                ret = update_flags(secidx, dat);
                if(ENCIP_ERROR(ret))
                    return ret;

                // Increment num_rvas:
                num_rvas++;
            }
            // Else (section is not allocable), zero it:
            else
            {
                memset(va, 0, size);
            }
        }
    }
    *num_rvas_out = num_rvas;
    return ENCIP_SUCCESS;
}