lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 20 Aug 2018 14:32:22 +1000
From:   Stephen Rothwell <sfr@...b.auug.org.au>
To:     Andrew Morton <akpm@...ux-foundation.org>,
        Thomas Gleixner <tglx@...utronix.de>,
        Ingo Molnar <mingo@...e.hu>, "H. Peter Anvin" <hpa@...or.com>,
        Peter Zijlstra <peterz@...radead.org>
Cc:     Linux-Next Mailing List <linux-next@...r.kernel.org>,
        Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
        Adrian Hunter <adrian.hunter@...el.com>,
        Arnaldo Carvalho de Melo <acme@...hat.com>,
        James Morse <james.morse@....com>,
        Omar Sandoval <osandov@...com>
Subject: linux-next: manual merge of the akpm-current tree with the tip tree

Hi Andrew,

Today's linux-next merge of the akpm-current tree got conflicts in:

  fs/proc/kcore.c
  include/linux/kcore.h

between commit:

  6855dc41b246 ("x86: Add entry trampolines to kcore")

from the tip tree and commits:

  4eb27c275abf ("fs/proc/kcore.c: use __pa_symbol() for KCORE_TEXT list entries")
  ea551910d3f4 ("proc/kcore: clean up ELF header generation")
  537412a2958f ("proc/kcore: don't grab lock for kclist_add()")

from the akpm-current tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc fs/proc/kcore.c
index 00282f134336,80464432dfe6..000000000000
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@@ -448,53 -291,148 +291,151 @@@ static ssize_
  read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
  {
  	char *buf = file->private_data;
- 	ssize_t acc = 0;
- 	size_t size, tsz;
- 	size_t elf_buflen;
+ 	size_t phdrs_offset, notes_offset, data_offset;
+ 	size_t phdrs_len, notes_len;
+ 	struct kcore_list *m;
+ 	size_t tsz;
  	int nphdr;
  	unsigned long start;
+ 	size_t orig_buflen = buflen;
+ 	int ret = 0;
  
- 	read_lock(&kclist_lock);
- 	size = get_kcore_size(&nphdr, &elf_buflen);
+ 	down_read(&kclist_lock);
+ 
+ 	get_kcore_size(&nphdr, &phdrs_len, &notes_len, &data_offset);
+ 	phdrs_offset = sizeof(struct elfhdr);
+ 	notes_offset = phdrs_offset + phdrs_len;
+ 
+ 	/* ELF file header. */
+ 	if (buflen && *fpos < sizeof(struct elfhdr)) {
+ 		struct elfhdr ehdr = {
+ 			.e_ident = {
+ 				[EI_MAG0] = ELFMAG0,
+ 				[EI_MAG1] = ELFMAG1,
+ 				[EI_MAG2] = ELFMAG2,
+ 				[EI_MAG3] = ELFMAG3,
+ 				[EI_CLASS] = ELF_CLASS,
+ 				[EI_DATA] = ELF_DATA,
+ 				[EI_VERSION] = EV_CURRENT,
+ 				[EI_OSABI] = ELF_OSABI,
+ 			},
+ 			.e_type = ET_CORE,
+ 			.e_machine = ELF_ARCH,
+ 			.e_version = EV_CURRENT,
+ 			.e_phoff = sizeof(struct elfhdr),
+ 			.e_flags = ELF_CORE_EFLAGS,
+ 			.e_ehsize = sizeof(struct elfhdr),
+ 			.e_phentsize = sizeof(struct elf_phdr),
+ 			.e_phnum = nphdr,
+ 		};
+ 
+ 		tsz = min_t(size_t, buflen, sizeof(struct elfhdr) - *fpos);
+ 		if (copy_to_user(buffer, (char *)&ehdr + *fpos, tsz)) {
+ 			ret = -EFAULT;
+ 			goto out;
+ 		}
  
- 	if (buflen == 0 || *fpos >= size) {
- 		read_unlock(&kclist_lock);
- 		return 0;
+ 		buffer += tsz;
+ 		buflen -= tsz;
+ 		*fpos += tsz;
  	}
  
- 	/* trim buflen to not go beyond EOF */
- 	if (buflen > size - *fpos)
- 		buflen = size - *fpos;
- 
- 	/* construct an ELF core header if we'll need some of it */
- 	if (*fpos < elf_buflen) {
- 		char * elf_buf;
- 
- 		tsz = elf_buflen - *fpos;
- 		if (buflen < tsz)
- 			tsz = buflen;
- 		elf_buf = kzalloc(elf_buflen, GFP_ATOMIC);
- 		if (!elf_buf) {
- 			read_unlock(&kclist_lock);
- 			return -ENOMEM;
+ 	/* ELF program headers. */
+ 	if (buflen && *fpos < phdrs_offset + phdrs_len) {
+ 		struct elf_phdr *phdrs, *phdr;
+ 
+ 		phdrs = kzalloc(phdrs_len, GFP_KERNEL);
+ 		if (!phdrs) {
+ 			ret = -ENOMEM;
+ 			goto out;
  		}
- 		elf_kcore_store_hdr(elf_buf, nphdr, elf_buflen);
- 		read_unlock(&kclist_lock);
- 		if (copy_to_user(buffer, elf_buf + *fpos, tsz)) {
- 			kfree(elf_buf);
- 			return -EFAULT;
+ 
+ 		phdrs[0].p_type = PT_NOTE;
+ 		phdrs[0].p_offset = notes_offset;
+ 		phdrs[0].p_filesz = notes_len;
+ 
+ 		phdr = &phdrs[1];
+ 		list_for_each_entry(m, &kclist_head, list) {
+ 			phdr->p_type = PT_LOAD;
+ 			phdr->p_flags = PF_R | PF_W | PF_X;
+ 			phdr->p_offset = kc_vaddr_to_offset(m->addr) + data_offset;
 -			phdr->p_vaddr = (size_t)m->addr;
 -			if (m->type == KCORE_RAM)
++			if (m->type == KCORE_REMAP)
++				phdr->p_vaddr	= (size_t)m->vaddr;
++			else
++				phdr->p_vaddr	= (size_t)m->addr;
++			if (m->type == KCORE_RAM || m->type == KCORE_REMAP)
+ 				phdr->p_paddr = __pa(m->addr);
+ 			else if (m->type == KCORE_TEXT)
+ 				phdr->p_paddr = __pa_symbol(m->addr);
+ 			else
+ 				phdr->p_paddr = (elf_addr_t)-1;
+ 			phdr->p_filesz = phdr->p_memsz = m->size;
+ 			phdr->p_align = PAGE_SIZE;
+ 			phdr++;
  		}
- 		kfree(elf_buf);
+ 
+ 		tsz = min_t(size_t, buflen, phdrs_offset + phdrs_len - *fpos);
+ 		if (copy_to_user(buffer, (char *)phdrs + *fpos - phdrs_offset,
+ 				 tsz)) {
+ 			kfree(phdrs);
+ 			ret = -EFAULT;
+ 			goto out;
+ 		}
+ 		kfree(phdrs);
+ 
+ 		buffer += tsz;
  		buflen -= tsz;
  		*fpos += tsz;
- 		buffer += tsz;
- 		acc += tsz;
+ 	}
+ 
+ 	/* ELF note segment. */
+ 	if (buflen && *fpos < notes_offset + notes_len) {
+ 		struct elf_prstatus prstatus = {};
+ 		struct elf_prpsinfo prpsinfo = {
+ 			.pr_sname = 'R',
+ 			.pr_fname = "vmlinux",
+ 		};
+ 		char *notes;
+ 		size_t i = 0;
+ 
+ 		strlcpy(prpsinfo.pr_psargs, saved_command_line,
+ 			sizeof(prpsinfo.pr_psargs));
+ 
+ 		notes = kzalloc(notes_len, GFP_KERNEL);
+ 		if (!notes) {
+ 			ret = -ENOMEM;
+ 			goto out;
+ 		}
+ 
+ 		append_kcore_note(notes, &i, CORE_STR, NT_PRSTATUS, &prstatus,
+ 				  sizeof(prstatus));
+ 		append_kcore_note(notes, &i, CORE_STR, NT_PRPSINFO, &prpsinfo,
+ 				  sizeof(prpsinfo));
+ 		append_kcore_note(notes, &i, CORE_STR, NT_TASKSTRUCT, current,
+ 				  arch_task_struct_size);
+ 		/*
+ 		 * vmcoreinfo_size is mostly constant after init time, but it
+ 		 * can be changed by crash_save_vmcoreinfo(). Racing here with a
+ 		 * panic on another CPU before the machine goes down is insanely
+ 		 * unlikely, but it's better to not leave potential buffer
+ 		 * overflows lying around, regardless.
+ 		 */
+ 		append_kcore_note(notes, &i, VMCOREINFO_NOTE_NAME, 0,
+ 				  vmcoreinfo_data,
+ 				  min(vmcoreinfo_size, notes_len - i));
+ 
+ 		tsz = min_t(size_t, buflen, notes_offset + notes_len - *fpos);
+ 		if (copy_to_user(buffer, notes + *fpos - notes_offset, tsz)) {
+ 			kfree(notes);
+ 			ret = -EFAULT;
+ 			goto out;
+ 		}
+ 		kfree(notes);
  
- 		/* leave now if filled buffer already */
- 		if (buflen == 0)
- 			return acc;
- 	} else
- 		read_unlock(&kclist_lock);
+ 		buffer += tsz;
+ 		buflen -= tsz;
+ 		*fpos += tsz;
+ 	}
  
  	/*
  	 * Check to see if our file offset matches with any of
diff --cc include/linux/kcore.h
index bc088ef96358,c20f296438fb..000000000000
--- a/include/linux/kcore.h
+++ b/include/linux/kcore.h
@@@ -37,13 -35,7 +37,13 @@@ struct vmcoredd_node 
  };
  
  #ifdef CONFIG_PROC_KCORE
- extern void kclist_add(struct kcore_list *, void *, size_t, int type);
+ void __init kclist_add(struct kcore_list *, void *, size_t, int type);
 +static inline
 +void kclist_add_remap(struct kcore_list *m, void *addr, void *vaddr, size_t sz)
 +{
 +	m->vaddr = (unsigned long)vaddr;
 +	kclist_add(m, addr, sz, KCORE_REMAP);
 +}
  #else
  static inline
  void kclist_add(struct kcore_list *new, void *addr, size_t size, int type)

Content of type "application/pgp-signature" skipped

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ