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-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20140320094105.14878.82749.stgit@localhost.localdomain>
Date:	Thu, 20 Mar 2014 15:11:05 +0530
From:	Janani Venkataraman <jananive@...ux.vnet.ibm.com>
To:	linux-kernel@...r.kernel.org
Cc:	amwang@...hat.com, procps@...elists.org, rdunlap@...otime.net,
	james.hogan@...tec.com, aravinda@...ux.vnet.ibm.com, hch@....de,
	mhiramat@...hat.com, jeremy.fitzhardinge@...rix.com,
	xemul@...allels.com, d.hatayama@...fujitsu.com, coreutils@....org,
	kosaki.motohiro@...fujitsu.com, adobriyan@...il.com,
	util-linux@...r.kernel.org, tarundsk@...ux.vnet.ibm.com,
	vapier@...too.org, roland@...k.frob.com, ananth@...ux.vnet.ibm.com,
	gorcunov@...nvz.org, avagin@...nvz.org, oleg@...hat.com,
	eparis@...hat.com, suzuki@...ux.vnet.ibm.com, andi@...stfloor.org,
	tj@...nel.org, akpm@...ux-foundation.org,
	torvalds@...ux-foundation.org
Subject: [PATCH 14/33] Populating Program Headers

Populates the program headers using memory maps linked list which was
populated in patch 5. The source, size and permissions of the maps are
found out and filled respectively.

Signed-off-by: Janani Venkataraman <jananive@...ux.vnet.ibm.com>
---
 src/coredump.c |    6 +++
 src/coredump.h |    2 +
 src/elf.c      |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/elf32.c    |    2 +
 src/elf64.c    |    1 +
 5 files changed, 119 insertions(+)

diff --git a/src/coredump.c b/src/coredump.c
index 0fd6343e..5cccb7a 100644
--- a/src/coredump.c
+++ b/src/coredump.c
@@ -231,6 +231,12 @@ cleanup:
 	if (cp.notes)
 		free_notes(cp.notes);
 
+	if (cp.phdrs)
+		free(cp.phdrs);
+
+	if (cp.phdrs_count)
+		free(cp.shdrs);
+
 	errno = status;
 
 	return ret;
diff --git a/src/coredump.h b/src/coredump.h
index dce6292..a729f16 100644
--- a/src/coredump.h
+++ b/src/coredump.h
@@ -68,4 +68,6 @@ struct core_proc {
 	int elf_class;			/* Elf class of the process */
 	void *elf_hdr;			/* Stores the ELF_header */
 	struct mem_note *notes;		/* Head of Notes */
+	void *shdrs;			/* Extra Program Headers */
+	void *phdrs;			/* Program Headers */
 };
diff --git a/src/elf.c b/src/elf.c
index 62dc5a9..a5a1feb 100644
--- a/src/elf.c
+++ b/src/elf.c
@@ -39,6 +39,11 @@
 
 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
 
+/* Default alignment for program headers */
+#ifndef ELF_EXEC_PAGESIZE
+#define ELF_EXEC_PAGESIZE PAGESIZE
+#endif
+
 /* Appending the note to the list */
 static void append_note(struct mem_note *new_note, struct core_proc *cp)
 {
@@ -110,6 +115,26 @@ static int add_note(const char *name, int type, unsigned int data_sz, void *data
 	return 0;
 }
 
+/*
+ * Reads first few bytes of the address specified and checks if it is
+ * an ELF by checking the magic number.
+ */
+static int get_elf_hdr_vaddr(int pid, Elf_Ehdr *elf, Elf_Addr addr)
+{
+	int ret;
+	struct iovec local, remote;
+
+	local.iov_base = elf;
+	local.iov_len = sizeof(Elf_Ehdr);
+	remote.iov_base = (void *)addr;
+	remote.iov_len = sizeof(Elf_Ehdr);
+	ret = process_vm_readv(pid, &local, 1, &remote, 1, 0);
+	if (ret == -1)
+		return -1;
+
+	return check_elf_hdr(elf->e_ident);
+}
+
 /* Fetchs ELF header of the executable */
 static int get_elf_hdr_exe_file(int pid, Elf_Ehdr *elf)
 {
@@ -568,6 +593,84 @@ static int fetch_thread_notes(struct core_proc *cp)
 	return 0;
 }
 
+/* Populate Program headers */
+static int get_phdrs(int pid, struct core_proc *cp)
+{
+	int n;
+	struct maps *map = cp->vmas;
+	Elf_Ehdr elf;
+	Elf_Phdr *cp_phdrs;
+	Elf_Shdr *cp_shdrs;
+	Elf_Ehdr *cp_elf;
+	cp_elf = (Elf_Ehdr *)cp->elf_hdr;
+
+	cp->phdrs = calloc(cp->phdrs_count, sizeof(Elf_Phdr));
+	if (!cp->phdrs) {
+		status = errno;
+		gencore_log("Could not allocate memory for Program headers.\n");
+		return -1;
+	}
+
+	cp_phdrs = (Elf_Phdr *)cp->phdrs;
+
+	cp_phdrs[0].p_type = PT_NOTE;
+	cp_phdrs[0].p_offset = 0;
+	cp_phdrs[0].p_vaddr = 0;
+	cp_phdrs[0].p_paddr = 0;
+	/* Will fill the size after filling notes */
+	cp_phdrs[0].p_filesz = 0;
+	cp_phdrs[0].p_memsz = 0;
+
+	n = 1;
+
+	while (map) {
+
+		/* Filling the Program Header Values */
+		cp_phdrs[n].p_type = PT_LOAD;
+		cp_phdrs[n].p_offset = 0;
+		cp_phdrs[n].p_vaddr = map->src;
+		cp_phdrs[n].p_paddr = 0;
+		cp_phdrs[n].p_flags = 0;
+		if (map->r == 'r')
+			cp_phdrs[n].p_flags |= PF_R;
+		if (map->w == 'w')
+			cp_phdrs[n].p_flags |= PF_W;
+		if (map->x == 'x')
+			cp_phdrs[n].p_flags |= PF_X;
+
+		cp_phdrs[n].p_memsz = map->dst - map->src;
+
+		if (!(cp_phdrs[n].p_flags & PF_R))
+			cp_phdrs[n].p_filesz = 0;
+		else if (map->inode &&
+			get_elf_hdr_vaddr(pid, &elf, cp_phdrs[n].p_vaddr) == 0)
+			cp_phdrs[n].p_filesz = ELF_EXEC_PAGESIZE;
+		else
+			cp_phdrs[n].p_filesz = cp_phdrs[n].p_memsz;
+		
+		cp_phdrs[n].p_align = ELF_EXEC_PAGESIZE;
+
+		n++;
+		map = map->next;
+	}
+
+	if (cp->phdrs_count > PN_XNUM) {
+		cp->shdrs = malloc(sizeof(Elf_Shdr));
+		if (!cp->shdrs) {
+			status = errno;
+			gencore_log("Could not allocate memory for Extra Program headers.\n");
+			return -1;
+		}
+		cp_shdrs = (Elf_Shdr *)cp->shdrs;
+		cp_shdrs->sh_type = SHT_NULL;
+		cp_shdrs->sh_size = cp_elf->e_shnum;
+		cp_shdrs->sh_link = cp_elf->e_shstrndx;
+		cp_shdrs->sh_info = cp->phdrs_count;
+	}
+
+	return 0;
+}
+
 int do_elf_coredump(int pid, struct core_proc *cp)
 {
 	int ret, i;
@@ -597,5 +700,10 @@ int do_elf_coredump(int pid, struct core_proc *cp)
 	if (ret)
 		return -1;
 
+	/* Get Program headers */
+	ret = get_phdrs(pid, cp);
+	if (ret)
+		return -1;
+
 	return 0;
 }
diff --git a/src/elf32.c b/src/elf32.c
index 8ec287b..daf9940 100644
--- a/src/elf32.c
+++ b/src/elf32.c
@@ -38,4 +38,6 @@
 #define Elf_Long int
 #define Elf_prstatus compat_elf_prstatus
 
+#define Elf_Addr Elf32_Addr
+
 #include "elf.c"
diff --git a/src/elf64.c b/src/elf64.c
index 780e2d4..651f218 100644
--- a/src/elf64.c
+++ b/src/elf64.c
@@ -37,5 +37,6 @@
 #define Elf_prpsinfo elf_prpsinfo
 #define Elf_Long long
 #define Elf_prstatus elf_prstatus
+#define Elf_Addr Elf64_Addr
 
 #include "elf.c"

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ