> On Mar 6, 2018, at 10:25 AM, Peter Zijlstra <pet...@infradead.org> wrote: > > On Tue, Mar 06, 2018 at 10:09:13AM -0800, Song Liu wrote: >> +/* Parse build ID of ELF file mapped to vma */ >> +static int stack_map_get_build_id(struct vm_area_struct *vma, >> + unsigned char *build_id) >> +{ >> + Elf32_Ehdr *ehdr; >> + struct page *page; >> + int ret; >> + >> + /* >> + * vm_start is user memory, so we need to be careful with it. >> + * We don't want too many copy_from_user to reduce overhead. >> + * Most ELF file is at least one page long, and the build_id >> + * is stored in the first page. Therefore, we limit the search of >> + * build_id to the first page only. This can be made safe with >> + * get_user_pages_fast(). If the file is smaller than PAGE_SIZE, >> + * or the build_id is not in the first page, the look up fails. >> + */ >> + if (vma->vm_end - vma->vm_start < PAGE_SIZE || >> + vma->vm_start & (PAGE_SIZE - 1)) /* page aligned */ >> + return -EINVAL; >> + >> + if (get_user_pages_fast(vma->vm_start, 1, 0, &page) != 1) >> + return -EFAULT; >> + >> + ret = -EINVAL; >> + ehdr = (Elf32_Ehdr *)vma->vm_start; >> + > > You're still directly accessing a user pointer afaict. This will > insta-fault on SMAP enabled hardware due to the lack of STAC (or PAN on > ARM). > > You _really_ cannot just access user pointers without the proper APIs. > > Did you maybe mean to use: > > ehdr = (Elf32_Ehdr *)page_address(page); > > ?
Yeah, I missed this part. Let me fix it. Thanks again! Song >> + /* compare magic x7f "ELF" */ >> + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) >> + goto out; >> + >> + /* only support executable file and shared object file */ >> + if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) >> + goto out; >> + >> + if (ehdr->e_ident[EI_CLASS] == 1) >> + ret = stack_map_get_build_id_32(vma, build_id); >> + else if (ehdr->e_ident[EI_CLASS] == 2) >> + ret = stack_map_get_build_id_64(vma, build_id); >> +out: >> + put_page(page); >> + return ret; >> +}