aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2015-12-23 19:58:15 +0100
committerDmitry Vyukov <dvyukov@google.com>2015-12-23 19:58:15 +0100
commit58509c75a2a2d472855da0683c36d7ef2f1a6c97 (patch)
tree01a5a400dc703bac7b8003aa2344ba36b24beb96
parent078517990325cd52828f3ba2d74ced12fc412db8 (diff)
prog: remove padding checking
So far it has found only false positives. Let's leave this to KMSAN.
-rw-r--r--csource/csource.go7
-rw-r--r--csource/csource_test.go2
-rw-r--r--executor/executor.cc56
-rw-r--r--ipc/ipc_test.go3
-rw-r--r--prog/encodingexec.go31
5 files changed, 15 insertions, 84 deletions
diff --git a/csource/csource.go b/csource/csource.go
index 5caa74af5..01d2152d5 100644
--- a/csource/csource.go
+++ b/csource/csource.go
@@ -161,13 +161,6 @@ loop:
size := read()
fmt.Fprintf(w, "\tif (r[%v] != -1)\n", lastCall)
fmt.Fprintf(w, "\t\tr[%v] = *(uint%v_t*)0x%x;\n", n, size*8, addr)
- case prog.ExecInstrSetPad:
- newCall()
- read() // addr
- read() // size
- case prog.ExecInstrCheckPad:
- read() // addr
- read() // size
default:
// Normal syscall.
newCall()
diff --git a/csource/csource_test.go b/csource/csource_test.go
index 388ab0e1a..c3e535cf5 100644
--- a/csource/csource_test.go
+++ b/csource/csource_test.go
@@ -43,11 +43,13 @@ func testOne(t *testing.T, p *prog.Prog, opts Options) {
src := Write(p, opts)
srcf, err := fileutil.WriteTempFile(src)
if err != nil {
+ t.Logf("program:\n%s\n", p.Serialize())
t.Fatalf("%v", err)
}
defer os.Remove(srcf)
bin, err := Build(srcf)
if err != nil {
+ t.Logf("program:\n%s\n", p.Serialize())
t.Fatalf("%v", err)
}
defer os.Remove(bin)
diff --git a/executor/executor.cc b/executor/executor.cc
index 9cdeb7ab8..4b1b38968 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -47,8 +47,6 @@ const int kCoverSize = 16 << 10;
const uint64_t instr_eof = -1;
const uint64_t instr_copyin = -2;
const uint64_t instr_copyout = -3;
-const uint64_t instr_set_pad = -4;
-const uint64_t instr_check_pad = -5;
const uint64_t arg_const = 0;
const uint64_t arg_result = 1;
@@ -314,17 +312,6 @@ retry:
// The copyout will happen when/if the call completes.
continue;
}
- if (call_num == instr_set_pad) {
- char* addr = (char*)read_input(&input_pos); // addr
- uint64_t size = read_input(&input_pos); // size
- memset(addr, 0, size);
- continue;
- }
- if (call_num == instr_check_pad) {
- read_input(&input_pos); // addr
- read_input(&input_pos); // size
- continue;
- }
// Normal syscall.
if (call_num >= sizeof(syscalls) / sizeof(syscalls[0]))
@@ -443,7 +430,6 @@ void handle_completion(thread_t* th)
if (th->ready || !th->done || th->handled)
fail("bad thread state in completion: ready=%d done=%d handled=%d",
th->ready, th->done, th->handled);
- uint64_t* copyout_pos = th->copyout_pos;
if (th->res != (uint64_t)-1) {
results[th->call_n].executed = true;
results[th->call_n].val = th->res;
@@ -460,12 +446,6 @@ void handle_completion(thread_t* th)
debug("copyout from %p\n", addr);
break;
}
- case instr_check_pad: {
- // Ignore for now, we will process them below.
- read_input(&th->copyout_pos);
- read_input(&th->copyout_pos);
- break;
- }
default:
done = true;
break;
@@ -473,39 +453,6 @@ void handle_completion(thread_t* th)
}
}
if (!collide) {
- th->copyout_pos = copyout_pos;
- for (bool done = false; !done;) {
- uint64_t call_num = read_input(&th->copyout_pos);
- switch (call_num) {
- case instr_copyout: {
- // Ignore, this is already handled above.
- read_input(&th->copyout_pos);
- read_input(&th->copyout_pos);
- break;
- }
- case instr_check_pad: {
- // Check that kernel returns zeros in struct padding.
- // Non-zeros can mean an information leak.
- char* addr = (char*)read_input(&th->copyout_pos);
- uint64_t size = read_input(&th->copyout_pos);
- for (uint64_t i = 0; i < size; i++) {
- if (addr[i] != 0) {
- printf("syscall '%s' (index %d): non-zero padding output at %p:",
- syscalls[th->call_num].name, th->call_index, addr);
- for (i = 0; i < size; i++)
- printf(" %02x", addr[i]);
- printf("\n");
- error("non-zero padding");
- }
- }
- break;
- }
- default:
- done = true;
- break;
- }
- }
-
write_output(th->call_index);
write_output(th->call_num);
write_output(th->res != (uint64_t)-1 ? 0 : th->reserrno);
@@ -842,12 +789,13 @@ void error(const char* msg, ...)
// just exit (e.g. due to temporal ENOMEM error)
void exitf(const char* msg, ...)
{
+ int e = errno;
fflush(stdout);
va_list args;
va_start(args, msg);
vfprintf(stderr, msg, args);
va_end(args);
- fprintf(stderr, "\n");
+ fprintf(stderr, " (errno %d)\n", e);
exit(1);
}
diff --git a/ipc/ipc_test.go b/ipc/ipc_test.go
index 1d85c4a8b..fb453b505 100644
--- a/ipc/ipc_test.go
+++ b/ipc/ipc_test.go
@@ -79,6 +79,8 @@ func TestEmptyProg(t *testing.T) {
}
func TestStrace(t *testing.T) {
+ t.Skip("strace is broken")
+
bin := buildExecutor(t)
defer os.Remove(bin)
@@ -118,6 +120,7 @@ func TestExecute(t *testing.T) {
p := prog.Generate(rs, 10, nil)
_, _, _, _, _, _, err := env.Exec(p)
if err != nil {
+ t.Logf("program:\n%s\n", p.Serialize())
t.Fatalf("failed to run executor: %v", err)
}
}
diff --git a/prog/encodingexec.go b/prog/encodingexec.go
index 7c75eccc9..3b0d4c28c 100644
--- a/prog/encodingexec.go
+++ b/prog/encodingexec.go
@@ -14,8 +14,6 @@ const (
ExecInstrEOF = ^uintptr(iota)
ExecInstrCopyin
ExecInstrCopyout
- ExecInstrSetPad
- ExecInstrCheckPad
)
const (
@@ -59,20 +57,16 @@ func (p *Prog) SerializeForExec() []byte {
}
return
}
+ if pad, _ := arg1.IsPad(); pad {
+ return
+ }
if arg1.Kind == ArgData && len(arg1.Data) == 0 {
return
}
- pad, padSize := arg1.IsPad()
- if (arg1.Dir == DirIn && !pad) || (arg1.Dir == DirOut && pad) || arg1.Dir == DirInOut {
- if pad {
- w.write(ExecInstrSetPad)
- w.write(physicalAddr(arg) + w.args[arg1].Offset)
- w.write(padSize)
- } else {
- w.write(ExecInstrCopyin)
- w.write(physicalAddr(arg) + w.args[arg1].Offset)
- w.writeArg(arg1)
- }
+ if arg1.Dir != DirOut {
+ w.write(ExecInstrCopyin)
+ w.write(physicalAddr(arg) + w.args[arg1].Offset)
+ w.writeArg(arg1)
instrSeq++
}
}
@@ -89,16 +83,7 @@ func (p *Prog) SerializeForExec() []byte {
instrSeq++
// Generate copyout instructions that persist interesting return values.
foreachArg(c, func(arg, base *Arg, _ *[]*Arg) {
- pad, padSize := arg.IsPad()
- if pad && arg.Dir != DirIn {
- instrSeq++
- info := w.args[arg]
- w.write(ExecInstrCheckPad)
- w.write(physicalAddr(base) + info.Offset)
- w.write(padSize)
- return
- }
- if pad || len(arg.Uses) == 0 {
+ if len(arg.Uses) == 0 {
return
}
switch arg.Kind {