Commit-ID:  cc4228d57c4c35ae0a29efa1e7687a817dc038d9
Gitweb:     http://git.kernel.org/tip/cc4228d57c4c35ae0a29efa1e7687a817dc038d9
Author:     Wang Nan <[email protected]>
AuthorDate: Wed, 1 Jul 2015 02:13:55 +0000
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 7 Aug 2015 10:16:56 -0300

bpf tools: Check endianness and make libbpf fail early

Check endianness according to EHDR. Code is taken from
tools/perf/util/symbol-elf.c.

Libbpf doesn't magically convert missmatched endianness. Even if we swap
eBPF instructions to correct byte order, we are unable to deal with
endianness in code logical generated by LLVM.

Therefore, libbpf should simply reject missmatched ELF object, and let
LLVM to create good code.

Signed-off-by: Wang Nan <[email protected]>
Acked-by: Alexei Starovoitov <[email protected]>
Cc: Brendan Gregg <[email protected]>
Cc: Daniel Borkmann <[email protected]>
Cc: David Ahern <[email protected]>
Cc: He Kuang <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Kaixu Xia <[email protected]>
Cc: Masami Hiramatsu <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Zefan Li <[email protected]>
Cc: [email protected]
Link: 
http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
 tools/lib/bpf/libbpf.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 36dfbc1..15b3e82 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -192,6 +192,34 @@ errout:
        return err;
 }
 
+static int
+bpf_object__check_endianness(struct bpf_object *obj)
+{
+       static unsigned int const endian = 1;
+
+       switch (obj->efile.ehdr.e_ident[EI_DATA]) {
+       case ELFDATA2LSB:
+               /* We are big endian, BPF obj is little endian. */
+               if (*(unsigned char const *)&endian != 1)
+                       goto mismatch;
+               break;
+
+       case ELFDATA2MSB:
+               /* We are little endian, BPF obj is big endian. */
+               if (*(unsigned char const *)&endian != 0)
+                       goto mismatch;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+
+mismatch:
+       pr_warning("Error: endianness mismatch.\n");
+       return -EINVAL;
+}
+
 static struct bpf_object *
 __bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz)
 {
@@ -208,6 +236,8 @@ __bpf_object__open(const char *path, void *obj_buf, size_t 
obj_buf_sz)
 
        if (bpf_object__elf_init(obj))
                goto out;
+       if (bpf_object__check_endianness(obj))
+               goto out;
 
        bpf_object__elf_finish(obj);
        return obj;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to