// SPDX-License-Identifier: GPL-2.0

#include <linux/buildid.h>
#include <linux/cache.h>
#include <linux/elf.h>
#include <linux/kernel.h>
#include <linux/pagemap.h>
#include <linux/secretmem.h>

#define BUILD_ID 3

/*
 * Parse build id from the note segment. This logic can be shared between
 * 32-bit and 64-bit system, because Elf32_Nhdr and Elf64_Nhdr are
 * identical.
 */
static int parse_build_id_buf(unsigned char *build_id,
			      __u32 *size,
			      const void *note_start,
			      Elf32_Word note_size)
{
	const char note_name[] = "GNU";
	const size_t note_name_sz = sizeof(note_name);
	u64 note_off = 0, new_off, name_sz, desc_sz;
	const char *data;

	while (note_off + sizeof(Elf32_Nhdr) < note_size &&
	       note_off + sizeof(Elf32_Nhdr) > note_off /* overflow */) {
		Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_off);

		name_sz = READ_ONCE(nhdr->n_namesz);
		desc_sz = READ_ONCE(nhdr->n_descsz);

		new_off = note_off + sizeof(Elf32_Nhdr);
		if (check_add_overflow(new_off, ALIGN(name_sz, 4), &new_off) ||
		    check_add_overflow(new_off, ALIGN(desc_sz, 4), &new_off) ||
		    new_off > note_size)
			break;

		if (nhdr->n_type == BUILD_ID &&
		    name_sz == note_name_sz &&
		    memcmp(nhdr + 1, note_name, note_name_sz) == 0 &&
		    desc_sz > 0 && desc_sz <= BUILD_ID_SIZE_MAX) {
			data = note_start + note_off + sizeof(Elf32_Nhdr) + ALIGN(note_name_sz, 4);
			memcpy(build_id, data, desc_sz);
			memset(build_id + desc_sz, 0, BUILD_ID_SIZE_MAX - desc_sz);
			if (size)
				*size = desc_sz;
			return 0;
		}

		note_off = new_off;
	}

	return -EINVAL;
}

static inline int parse_build_id(const void *page_addr,
				 unsigned char *build_id,
				 __u32 *size,
				 const void *note_start,
				 Elf32_Word note_size)
{
	/* check for overflow */
	if (note_start < page_addr || note_start + note_size < note_start)
		return -EINVAL;

	/* only supports note that fits in the first page */
	if (note_start + note_size > page_addr + PAGE_SIZE)
		return -EINVAL;

	return parse_build_id_buf(build_id, size, note_start, note_size);
}

/* Parse build ID from 32-bit ELF */
static int get_build_id_32(const void *page_addr, unsigned char *build_id,
			   __u32 *size)
{
	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)page_addr;
	Elf32_Phdr *phdr;
	__u32 i, phnum;

	/*
	 * FIXME
	 * Neither ELF spec nor ELF loader require that program headers
	 * start immediately after ELF header.
	 */
	if (ehdr->e_phoff != sizeof(Elf32_Ehdr))
		return -EINVAL;

	phnum = READ_ONCE(ehdr->e_phnum);
	/* only supports phdr that fits in one page */
	if (phnum > (PAGE_SIZE - sizeof(Elf32_Ehdr)) / sizeof(Elf32_Phdr))
		return -EINVAL;

	phdr = (Elf32_Phdr *)(page_addr + sizeof(Elf32_Ehdr));

	for (i = 0; i < phnum; ++i) {
		if (phdr[i].p_type == PT_NOTE &&
		    !parse_build_id(page_addr, build_id, size,
				    page_addr + READ_ONCE(phdr[i].p_offset),
				    READ_ONCE(phdr[i].p_filesz)))
			return 0;
	}
	return -EINVAL;
}

/* Parse build ID from 64-bit ELF */
static int get_build_id_64(const void *page_addr, unsigned char *build_id,
			   __u32 *size)
{
	Elf64_Ehdr *ehdr = (Elf64_Ehdr *)page_addr;
	Elf64_Phdr *phdr;
	__u32 i, phnum;

	/*
	 * FIXME
	 * Neither ELF spec nor ELF loader require that program headers
	 * start immediately after ELF header.
	 */
	if (ehdr->e_phoff != sizeof(Elf64_Ehdr))
		return -EINVAL;

	phnum = READ_ONCE(ehdr->e_phnum);
	/* only supports phdr that fits in one page */
	if (phnum > (PAGE_SIZE - sizeof(Elf64_Ehdr)) / sizeof(Elf64_Phdr))
		return -EINVAL;

	phdr = (Elf64_Phdr *)(page_addr + sizeof(Elf64_Ehdr));

	for (i = 0; i < phnum; ++i) {
		if (phdr[i].p_type == PT_NOTE &&
		    !parse_build_id(page_addr, build_id, size,
				    page_addr + READ_ONCE(phdr[i].p_offset),
				    READ_ONCE(phdr[i].p_filesz)))
			return 0;
	}
	return -EINVAL;
}

/*
 * Parse build ID of ELF file mapped to vma
 * @vma:      vma object
 * @build_id: buffer to store build id, at least BUILD_ID_SIZE long
 * @size:     returns actual build id size in case of success
 *
 * Return: 0 on success, -EINVAL otherwise
 */
int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
		   __u32 *size)
{
	Elf32_Ehdr *ehdr;
	struct page *page;
	void *page_addr;
	int ret;

	/* only works for page backed storage  */
	if (!vma->vm_file)
		return -EINVAL;

	/* reject secretmem folios created with memfd_secret() */
	if (vma_is_secretmem(vma))
		return -EFAULT;

	page = find_get_page(vma->vm_file->f_mapping, 0);
	if (!page)
		return -EFAULT;	/* page not mapped */
	if (!PageUptodate(page)) {
		put_page(page);
		return -EFAULT;
	}

	ret = -EINVAL;
	page_addr = kmap_atomic(page);
	ehdr = (Elf32_Ehdr *)page_addr;

	/* 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] == ELFCLASS32)
		ret = get_build_id_32(page_addr, build_id, size);
	else if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
		ret = get_build_id_64(page_addr, build_id, size);
out:
	kunmap_atomic(page_addr);
	put_page(page);
	return ret;
}

/**
 * build_id_parse_buf - Get build ID from a buffer
 * @buf:      ELF note section(s) to parse
 * @buf_size: Size of @buf in bytes
 * @build_id: Build ID parsed from @buf, at least BUILD_ID_SIZE_MAX long
 *
 * Return: 0 on success, -EINVAL otherwise
 */
int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size)
{
	return parse_build_id_buf(build_id, NULL, buf, buf_size);
}

#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) || IS_ENABLED(CONFIG_CRASH_CORE)
unsigned char vmlinux_build_id[BUILD_ID_SIZE_MAX] __ro_after_init;

/**
 * init_vmlinux_build_id - Compute and stash the running kernel's build ID
 */
void __init init_vmlinux_build_id(void)
{
	extern const void __start_notes __weak;
	extern const void __stop_notes __weak;
	unsigned int size = &__stop_notes - &__start_notes;

	build_id_parse_buf(&__start_notes, vmlinux_build_id, size);
}
#endif
