void vsf_secbuf_alloc(char** p_ptr, unsigned int size) { unsigned int page_offset; unsigned int round_up; char* p_mmap; char* p_no_access_page; unsigned int page_size = vsf_sysutil_getpagesize(); /* Free any previous buffer */ vsf_secbuf_free(p_ptr); /* Round up to next page size */ page_offset = size % page_size; if (page_offset) { unsigned int num_pages = size / page_size; num_pages++; round_up = num_pages * page_size; } else { /* Allocation is on a page-size boundary */ round_up = size; } /* Add on another two pages to make inaccessible */ round_up += page_size * 2; p_mmap = vsf_sysutil_map_anon_pages(round_up); /* Map the first and last page inaccessible */ p_no_access_page = p_mmap + round_up - page_size; vsf_sysutil_memprotect(p_no_access_page, page_size, kVSFSysUtilMapProtNone); /* Before we make the "before" page inaccessible, store the size in it. * A little hack so that we don't need to explicitly be passed the size * when freeing an existing secure buffer */ *((unsigned int*)p_mmap) = round_up; p_no_access_page = p_mmap; /* fix issue with MIPS SCACHE on MT7621 (and no sense to hide value of mapped block size) */ vsf_sysutil_memprotect(p_no_access_page, page_size, kVSFSysUtilMapProtReadOnly); p_mmap += page_size; if (page_offset) { p_mmap += (page_size - page_offset); } *p_ptr = p_mmap; }
int str_fileread(struct mystr* p_str, const char* p_filename, unsigned int maxsize) { int fd; int retval = 0; filesize_t size; char* p_sec_buf = 0; struct vsf_sysutil_statbuf* p_stat = 0; /* In case we fail, make sure we return an empty string */ str_empty(p_str); fd = vsf_sysutil_open_file(p_filename, kVSFSysUtilOpenReadOnly); if (vsf_sysutil_retval_is_error(fd)) { return fd; } vsf_sysutil_fstat(fd, &p_stat); if (vsf_sysutil_statbuf_is_regfile(p_stat)) { size = vsf_sysutil_statbuf_get_size(p_stat); if (size > maxsize) { size = maxsize; } vsf_secbuf_alloc(&p_sec_buf, (unsigned int) size); retval = vsf_sysutil_read_loop(fd, p_sec_buf, (unsigned int) size); if (vsf_sysutil_retval_is_error(retval)) { goto free_out; } else if ((unsigned int) retval != size) { die("read size mismatch"); } str_alloc_memchunk(p_str, p_sec_buf, size); } free_out: vsf_sysutil_free(p_stat); vsf_secbuf_free(&p_sec_buf); vsf_sysutil_close(fd); return retval; }