mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-23 11:29:46 +00:00
all: add optional close_fds feature to reproducers
Instead of always closing open fds (number 3 to 30) after each program, add an options called EnableCloseFds. It can be passed to syz-execprog, syz-prog2c and syz-stress via the -enable and -disable flags. Set the default value to true. Also minimize C repros over it, except for when repeat is enabled.
This commit is contained in:
parent
e619f52452
commit
5c51045d28
@ -483,6 +483,9 @@ again:
|
||||
}
|
||||
for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
|
||||
sleep_ms(1);
|
||||
#if SYZ_HAVE_CLOSE_FDS
|
||||
close_fds();
|
||||
#endif
|
||||
#if SYZ_COLLIDE
|
||||
if (!collide) {
|
||||
collide = 1;
|
||||
@ -571,8 +574,8 @@ static void loop(void)
|
||||
close(kOutPipeFd);
|
||||
#endif
|
||||
execute_one();
|
||||
#if SYZ_HAVE_RESET_TEST
|
||||
reset_test();
|
||||
#if SYZ_HAVE_CLOSE_FDS && !SYZ_THREADED
|
||||
close_fds();
|
||||
#endif
|
||||
doexit(0);
|
||||
#endif
|
||||
@ -659,6 +662,9 @@ void loop(void)
|
||||
#endif
|
||||
{
|
||||
/*SYSCALLS*/
|
||||
#if SYZ_HAVE_CLOSE_FDS && !SYZ_THREADED && !SYZ_REPEAT
|
||||
close_fds();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -690,6 +696,10 @@ int main(void)
|
||||
use_temporary_dir();
|
||||
#endif
|
||||
/*SANDBOX_FUNC*/
|
||||
#if SYZ_HAVE_CLOSE_FDS && !SYZ_THREADED && !SYZ_REPEAT && !SYZ_SANDBOX_NONE && \
|
||||
!SYZ_SANDBOX_SETUID && !SYZ_SANDBOX_NAMESPACE && !SYZ_SANDBOX_ANDROID_UNTRUSTED_APP
|
||||
close_fds();
|
||||
#endif
|
||||
#if SYZ_PROCS
|
||||
}
|
||||
}
|
||||
|
@ -2612,12 +2612,20 @@ static void setup_test()
|
||||
flush_tun();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SYZ_HAVE_RESET_TEST 1
|
||||
static void reset_test()
|
||||
#if SYZ_EXECUTOR || SYZ_ENABLE_CLOSE_FDS
|
||||
#define SYZ_HAVE_CLOSE_FDS 1
|
||||
static void close_fds()
|
||||
{
|
||||
#if SYZ_EXECUTOR
|
||||
if (!flag_enable_close_fds)
|
||||
return;
|
||||
#endif
|
||||
// Keeping a 9p transport pipe open will hang the proccess dead,
|
||||
// so close all opened file descriptors.
|
||||
// Also close all USB emulation descriptors to trigger exit from USB
|
||||
// event loop to collect coverage.
|
||||
int fd;
|
||||
for (fd = 3; fd < 30; fd++)
|
||||
close(fd);
|
||||
|
@ -119,6 +119,7 @@ static bool flag_enable_net_dev;
|
||||
static bool flag_enable_net_reset;
|
||||
static bool flag_enable_cgroups;
|
||||
static bool flag_enable_binfmt_misc;
|
||||
static bool flag_enable_close_fds;
|
||||
|
||||
static bool flag_collect_cover;
|
||||
static bool flag_dedup_cover;
|
||||
@ -454,6 +455,7 @@ void parse_env_flags(uint64 flags)
|
||||
flag_enable_net_reset = flags & (1 << 9);
|
||||
flag_enable_cgroups = flags & (1 << 10);
|
||||
flag_enable_binfmt_misc = flags & (1 << 11);
|
||||
flag_enable_close_fds = flags & (1 << 12);
|
||||
}
|
||||
|
||||
#if SYZ_EXECUTOR_USES_FORK_SERVER
|
||||
@ -732,6 +734,10 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
#if SYZ_HAVE_CLOSE_FDS
|
||||
close_fds();
|
||||
#endif
|
||||
|
||||
if (flag_collide && !flag_inject_fault && !colliding && !collide) {
|
||||
debug("enabling collider\n");
|
||||
collide = colliding = true;
|
||||
|
@ -89,6 +89,7 @@ func defineList(p, mmapProg *prog.Prog, opts Options) (defines []string) {
|
||||
"SYZ_ENABLE_NETDEV": opts.EnableNetDev,
|
||||
"SYZ_RESET_NET_NAMESPACE": opts.EnableNetReset,
|
||||
"SYZ_ENABLE_BINFMT_MISC": opts.EnableBinfmtMisc,
|
||||
"SYZ_ENABLE_CLOSE_FDS": opts.EnableCloseFds,
|
||||
"SYZ_USE_TMP_DIR": opts.UseTmpDir,
|
||||
"SYZ_HANDLE_SEGV": opts.HandleSegv,
|
||||
"SYZ_REPRO": opts.Repro,
|
||||
|
@ -4319,10 +4319,16 @@ static void setup_test()
|
||||
flush_tun();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SYZ_HAVE_RESET_TEST 1
|
||||
static void reset_test()
|
||||
#if SYZ_EXECUTOR || SYZ_ENABLE_CLOSE_FDS
|
||||
#define SYZ_HAVE_CLOSE_FDS 1
|
||||
static void close_fds()
|
||||
{
|
||||
#if SYZ_EXECUTOR
|
||||
if (!flag_enable_close_fds)
|
||||
return;
|
||||
#endif
|
||||
int fd;
|
||||
for (fd = 3; fd < 30; fd++)
|
||||
close(fd);
|
||||
@ -4614,6 +4620,9 @@ again:
|
||||
}
|
||||
for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
|
||||
sleep_ms(1);
|
||||
#if SYZ_HAVE_CLOSE_FDS
|
||||
close_fds();
|
||||
#endif
|
||||
#if SYZ_COLLIDE
|
||||
if (!collide) {
|
||||
collide = 1;
|
||||
@ -4698,8 +4707,8 @@ static void loop(void)
|
||||
close(kOutPipeFd);
|
||||
#endif
|
||||
execute_one();
|
||||
#if SYZ_HAVE_RESET_TEST
|
||||
reset_test();
|
||||
#if SYZ_HAVE_CLOSE_FDS && !SYZ_THREADED
|
||||
close_fds();
|
||||
#endif
|
||||
doexit(0);
|
||||
#endif
|
||||
@ -4771,6 +4780,9 @@ void loop(void)
|
||||
#endif
|
||||
{
|
||||
/*SYSCALLS*/
|
||||
#if SYZ_HAVE_CLOSE_FDS && !SYZ_THREADED && !SYZ_REPEAT
|
||||
close_fds();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if GOOS_akaros && SYZ_REPEAT
|
||||
@ -4800,6 +4812,10 @@ int main(void)
|
||||
use_temporary_dir();
|
||||
#endif
|
||||
/*SANDBOX_FUNC*/
|
||||
#if SYZ_HAVE_CLOSE_FDS && !SYZ_THREADED && !SYZ_REPEAT && !SYZ_SANDBOX_NONE && \
|
||||
!SYZ_SANDBOX_SETUID && !SYZ_SANDBOX_NAMESPACE && !SYZ_SANDBOX_ANDROID_UNTRUSTED_APP
|
||||
close_fds();
|
||||
#endif
|
||||
#if SYZ_PROCS
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ type Options struct {
|
||||
EnableNetReset bool `json:"resetnet,omitempty"`
|
||||
EnableCgroups bool `json:"cgroups,omitempty"`
|
||||
EnableBinfmtMisc bool `json:"binfmt_misc,omitempty"`
|
||||
EnableCloseFds bool `json:"close_fds"`
|
||||
|
||||
UseTmpDir bool `json:"tmpdir,omitempty"`
|
||||
HandleSegv bool `json:"segv,omitempty"`
|
||||
@ -117,6 +118,9 @@ func (opts Options) checkLinuxOnly(OS string) error {
|
||||
if opts.EnableBinfmtMisc {
|
||||
return fmt.Errorf("EnableBinfmtMisc is not supported on %v", OS)
|
||||
}
|
||||
if opts.EnableCloseFds {
|
||||
return fmt.Errorf("EnableCloseFds is not supported on %v", OS)
|
||||
}
|
||||
if opts.Sandbox == sandboxNamespace ||
|
||||
(opts.Sandbox == sandboxSetuid && !(OS == openbsd || OS == freebsd)) ||
|
||||
opts.Sandbox == sandboxAndroidUntrustedApp {
|
||||
@ -140,6 +144,7 @@ func DefaultOpts(cfg *mgrconfig.Config) Options {
|
||||
EnableNetReset: true,
|
||||
EnableCgroups: true,
|
||||
EnableBinfmtMisc: true,
|
||||
EnableCloseFds: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
Repro: true,
|
||||
@ -150,6 +155,7 @@ func DefaultOpts(cfg *mgrconfig.Config) Options {
|
||||
opts.EnableNetReset = false
|
||||
opts.EnableCgroups = false
|
||||
opts.EnableBinfmtMisc = false
|
||||
opts.EnableCloseFds = false
|
||||
}
|
||||
if cfg.Sandbox == "" || cfg.Sandbox == "setuid" {
|
||||
opts.EnableNetReset = false
|
||||
@ -170,6 +176,9 @@ func (opts Options) Serialize() []byte {
|
||||
|
||||
func DeserializeOptions(data []byte) (Options, error) {
|
||||
var opts Options
|
||||
// Before EnableCloseFds was added, close_fds() was always called,
|
||||
// so default to true.
|
||||
opts.EnableCloseFds = true
|
||||
if err := json.Unmarshal(data, &opts); err == nil {
|
||||
return opts, nil
|
||||
}
|
||||
@ -225,6 +234,7 @@ func defaultFeatures(value bool) Features {
|
||||
"net_reset": {"reset network namespace between programs", value},
|
||||
"cgroups": {"setup cgroups for testing", value},
|
||||
"binfmt_misc": {"setup binfmt_misc for testing", value},
|
||||
"close_fds": {"close fds after each program", value},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ func TestParseOptionsCanned(t *testing.T) {
|
||||
EnableNetReset: true,
|
||||
EnableCgroups: true,
|
||||
EnableBinfmtMisc: false,
|
||||
EnableCloseFds: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
Repro: true,
|
||||
@ -65,6 +66,7 @@ func TestParseOptionsCanned(t *testing.T) {
|
||||
EnableNetReset: true,
|
||||
EnableCgroups: true,
|
||||
EnableBinfmtMisc: false,
|
||||
EnableCloseFds: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
Repro: true,
|
||||
@ -81,6 +83,7 @@ func TestParseOptionsCanned(t *testing.T) {
|
||||
EnableTun: true,
|
||||
EnableCgroups: false,
|
||||
EnableBinfmtMisc: false,
|
||||
EnableCloseFds: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
Repro: false,
|
||||
@ -97,6 +100,7 @@ func TestParseOptionsCanned(t *testing.T) {
|
||||
EnableTun: true,
|
||||
EnableCgroups: false,
|
||||
EnableBinfmtMisc: false,
|
||||
EnableCloseFds: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
Repro: false,
|
||||
@ -113,6 +117,7 @@ func TestParseOptionsCanned(t *testing.T) {
|
||||
EnableTun: true,
|
||||
EnableCgroups: true,
|
||||
EnableBinfmtMisc: false,
|
||||
EnableCloseFds: true,
|
||||
UseTmpDir: true,
|
||||
HandleSegv: true,
|
||||
Repro: false,
|
||||
@ -208,28 +213,31 @@ func TestParseFeaturesFlags(t *testing.T) {
|
||||
Features map[string]bool
|
||||
}{
|
||||
{"none", "none", true, map[string]bool{
|
||||
"tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true,
|
||||
"tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true, "close_fds": true,
|
||||
}},
|
||||
{"none", "none", false, map[string]bool{
|
||||
"tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false,
|
||||
"tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false,
|
||||
}},
|
||||
{"all", "none", true, map[string]bool{
|
||||
"tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true,
|
||||
"tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true, "close_fds": true,
|
||||
}},
|
||||
{"", "none", true, map[string]bool{
|
||||
"tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false,
|
||||
"tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false,
|
||||
}},
|
||||
{"none", "all", true, map[string]bool{
|
||||
"tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false,
|
||||
"tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false,
|
||||
}},
|
||||
{"none", "", true, map[string]bool{
|
||||
"tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true,
|
||||
"tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true, "close_fds": true,
|
||||
}},
|
||||
{"tun,net_dev", "none", true, map[string]bool{
|
||||
"tun": true, "net_dev": true, "net_reset": false, "cgroups": false, "binfmt_misc": false,
|
||||
"tun": true, "net_dev": true, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false,
|
||||
}},
|
||||
{"none", "cgroups,net_dev", true, map[string]bool{
|
||||
"tun": true, "net_dev": false, "net_reset": true, "cgroups": false, "binfmt_misc": true,
|
||||
"tun": true, "net_dev": false, "net_reset": true, "cgroups": false, "binfmt_misc": true, "close_fds": true,
|
||||
}},
|
||||
{"close_fds", "none", true, map[string]bool{
|
||||
"tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": true,
|
||||
}},
|
||||
}
|
||||
for i, test := range tests {
|
||||
|
@ -38,6 +38,7 @@ const (
|
||||
FlagEnableNetReset // reset network namespace between programs
|
||||
FlagEnableCgroups // setup cgroups for testing
|
||||
FlagEnableBinfmtMisc // setup binfmt_misc for testing
|
||||
FlagEnableCloseFds // close fds after each program
|
||||
// Executor does not know about these:
|
||||
FlagUseShmem // use shared memory instead of pipes for communication
|
||||
FlagUseForkServer // use extended protocol with handshake
|
||||
|
@ -809,6 +809,7 @@ var cSimplifies = append(progSimplifies, []Simplify{
|
||||
opts.EnableNetReset = false
|
||||
opts.EnableCgroups = false
|
||||
opts.EnableBinfmtMisc = false
|
||||
opts.EnableCloseFds = false
|
||||
return true
|
||||
},
|
||||
func(opts *csource.Options) bool {
|
||||
@ -846,6 +847,15 @@ var cSimplifies = append(progSimplifies, []Simplify{
|
||||
opts.EnableBinfmtMisc = false
|
||||
return true
|
||||
},
|
||||
func(opts *csource.Options) bool {
|
||||
// We don't want to remove close_fds() call when repeat is enabled,
|
||||
// since that can lead to deadlocks, see executor/common_linux.h.
|
||||
if !opts.EnableCloseFds || opts.Repeat {
|
||||
return false
|
||||
}
|
||||
opts.EnableCloseFds = false
|
||||
return true
|
||||
},
|
||||
func(opts *csource.Options) bool {
|
||||
if !opts.UseTmpDir || opts.Sandbox == "namespace" || opts.EnableCgroups {
|
||||
return false
|
||||
|
@ -202,6 +202,7 @@ func main() {
|
||||
config.Flags |= ipc.FlagEnableNetReset
|
||||
config.Flags |= ipc.FlagEnableCgroups
|
||||
config.Flags |= ipc.FlagEnableBinfmtMisc
|
||||
config.Flags |= ipc.FlagEnableCloseFds
|
||||
|
||||
if *flagRunTest {
|
||||
runTest(target, manager, *flagName, config.Executor)
|
||||
|
@ -324,5 +324,8 @@ func createConfig(target *prog.Target, entries []*prog.LogEntry,
|
||||
if featuresFlags["binfmt_misc"].Enabled {
|
||||
config.Flags |= ipc.FlagEnableBinfmtMisc
|
||||
}
|
||||
if featuresFlags["close_fds"].Enabled {
|
||||
config.Flags |= ipc.FlagEnableCloseFds
|
||||
}
|
||||
return config, execOpts
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ func main() {
|
||||
EnableNetReset: features["net_reset"].Enabled,
|
||||
EnableCgroups: features["cgroups"].Enabled,
|
||||
EnableBinfmtMisc: features["binfmt_misc"].Enabled,
|
||||
EnableCloseFds: features["close_fds"].Enabled,
|
||||
UseTmpDir: *flagUseTmpDir,
|
||||
HandleSegv: *flagHandleSegv,
|
||||
Repro: false,
|
||||
|
@ -94,6 +94,9 @@ func main() {
|
||||
if featuresFlags["binfmt_misc"].Enabled {
|
||||
config.Flags |= ipc.FlagEnableBinfmtMisc
|
||||
}
|
||||
if featuresFlags["close_fds"].Enabled {
|
||||
config.Flags |= ipc.FlagEnableCloseFds
|
||||
}
|
||||
gate = ipc.NewGate(2**flagProcs, nil)
|
||||
for pid := 0; pid < *flagProcs; pid++ {
|
||||
pid := pid
|
||||
|
Loading…
Reference in New Issue
Block a user