aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2023-06-14 14:58:25 +0200
committerAleksandr Nogikh <wp32pw@gmail.com>2023-06-15 11:49:04 +0200
commit757d26edba7d7de8c564a87a262a0b1321ddf804 (patch)
treef78b5e053c0a61ef2771e130af410ee7ee1d40da /pkg
parent90d4044eae0123561d6cf2f667a4bc3357d93e7a (diff)
all: support swap feature on Linux
If the feature is supported on the device, allocate a 128MB swap file after VM boot and activate it.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/csource/common.go1
-rw-r--r--pkg/csource/generated.go60
-rw-r--r--pkg/csource/options.go4
-rw-r--r--pkg/csource/options_test.go7
-rw-r--r--pkg/host/features.go5
-rw-r--r--pkg/host/features_linux.go12
-rw-r--r--pkg/repro/repro.go11
-rw-r--r--pkg/runtest/run.go1
8 files changed, 92 insertions, 9 deletions
diff --git a/pkg/csource/common.go b/pkg/csource/common.go
index 6f3920126..3b30d85f4 100644
--- a/pkg/csource/common.go
+++ b/pkg/csource/common.go
@@ -127,6 +127,7 @@ func commonDefines(p *prog.Prog, opts Options) map[string]bool {
"SYZ_WIFI": opts.Wifi,
"SYZ_802154": opts.IEEE802154,
"SYZ_SYSCTL": opts.Sysctl,
+ "SYZ_SWAP": opts.Swap,
"SYZ_EXECUTOR_USES_SHMEM": sysTarget.ExecutorUsesShmem,
"SYZ_EXECUTOR_USES_FORK_SERVER": sysTarget.ExecutorUsesForkServer,
}
diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go
index 8c80cc363..bceb2dba4 100644
--- a/pkg/csource/generated.go
+++ b/pkg/csource/generated.go
@@ -3767,6 +3767,18 @@ static void initialize_wifi_devices(void)
}
#endif
+#if SYZ_EXECUTOR || (SYZ_NET_DEVICES && SYZ_NIC_VF) || SYZ_SWAP
+static int runcmdline(char* cmdline)
+{
+ debug("%s\n", cmdline);
+ int ret = system(cmdline);
+ if (ret) {
+ debug("FAIL: %s\n", cmdline);
+ }
+ return ret;
+}
+#endif
+
#if SYZ_EXECUTOR || SYZ_NET_DEVICES
#include <arpa/inet.h>
#include <errno.h>
@@ -4028,15 +4040,6 @@ error:
}
#if SYZ_EXECUTOR || SYZ_NIC_VF
-static int runcmdline(char* cmdline)
-{
- debug("%s\n", cmdline);
- int ret = system(cmdline);
- if (ret) {
- debug("FAIL: %s\n", cmdline);
- }
- return ret;
-}
static void netlink_nicvf_setup(void)
{
@@ -11762,6 +11765,42 @@ static long syz_pkey_set(volatile long pkey, volatile long val)
}
#endif
+#if SYZ_EXECUTOR || SYZ_SWAP
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/swap.h>
+#include <sys/types.h>
+
+#define SWAP_FILE "./swap-file"
+#define SWAP_FILE_SIZE (128 * 1000 * 1000)
+
+static void setup_swap()
+{
+ swapoff(SWAP_FILE);
+ unlink(SWAP_FILE);
+ int fd = open(SWAP_FILE, O_CREAT | O_WRONLY | O_CLOEXEC, 0600);
+ if (fd == -1) {
+ failmsg("swap file open failed", "file: %s", SWAP_FILE);
+ return;
+ }
+ fallocate(fd, FALLOC_FL_ZERO_RANGE, 0, SWAP_FILE_SIZE);
+ close(fd);
+ char cmdline[64];
+ sprintf(cmdline, "mkswap %s", SWAP_FILE);
+ if (runcmdline(cmdline)) {
+ fail("mkswap failed");
+ return;
+ }
+ if (swapon(SWAP_FILE, SWAP_FLAG_PREFER) == 1) {
+ failmsg("swapon failed", "file: %s", SWAP_FILE);
+ return;
+ }
+}
+
+#endif
+
#elif GOOS_test
#include <stdlib.h>
@@ -12645,6 +12684,9 @@ int main(void)
#if SYZ_802154
setup_802154();
#endif
+#if SYZ_SWAP
+ setup_swap();
+#endif
#if SYZ_HANDLE_SEGV
install_segv_handler();
#endif
diff --git a/pkg/csource/options.go b/pkg/csource/options.go
index 45cedb6a9..9a43c65fc 100644
--- a/pkg/csource/options.go
+++ b/pkg/csource/options.go
@@ -43,6 +43,7 @@ type Options struct {
Wifi bool `json:"wifi,omitempty"`
IEEE802154 bool `json:"ieee802154,omitempty"`
Sysctl bool `json:"sysctl,omitempty"`
+ Swap bool `json:"swap,omitempty"`
UseTmpDir bool `json:"tmpdir,omitempty"`
HandleSegv bool `json:"segv,omitempty"`
@@ -150,6 +151,7 @@ func (opts Options) checkLinuxOnly(OS string) error {
"Fault": &opts.Fault,
"Leak": &opts.Leak,
"Sysctl": &opts.Sysctl,
+ "Swap": &opts.Swap,
} {
if *opt {
return fmt.Errorf("option %v is not supported on %v", name, OS)
@@ -183,6 +185,7 @@ func DefaultOpts(cfg *mgrconfig.Config) Options {
opts.Wifi = true
opts.IEEE802154 = true
opts.Sysctl = true
+ opts.Swap = true
}
if cfg.Sandbox == "" || cfg.Sandbox == "setuid" {
opts.NetReset = false
@@ -316,6 +319,7 @@ func defaultFeatures(value bool) Features {
"wifi": {"setup and use mac80211_hwsim for wifi emulation", value},
"ieee802154": {"setup and use mac802154_hwsim for emulation", value},
"sysctl": {"setup sysctl's for fuzzing", value},
+ "swap": {"setup and use a swap file", value},
}
}
diff --git a/pkg/csource/options_test.go b/pkg/csource/options_test.go
index 5edc56d02..5452f22ce 100644
--- a/pkg/csource/options_test.go
+++ b/pkg/csource/options_test.go
@@ -314,6 +314,7 @@ func TestParseFeaturesFlags(t *testing.T) {
"wifi": true,
"ieee802154": true,
"sysctl": true,
+ "swap": true,
}},
{"none", "none", false, map[string]bool{}},
{"all", "none", true, map[string]bool{
@@ -330,6 +331,7 @@ func TestParseFeaturesFlags(t *testing.T) {
"wifi": true,
"ieee802154": true,
"sysctl": true,
+ "swap": true,
}},
{"", "none", true, map[string]bool{}},
{"none", "all", true, map[string]bool{}},
@@ -347,6 +349,7 @@ func TestParseFeaturesFlags(t *testing.T) {
"wifi": true,
"ieee802154": true,
"sysctl": true,
+ "swap": true,
}},
{"tun,net_dev", "none", true, map[string]bool{
"tun": true,
@@ -364,10 +367,14 @@ func TestParseFeaturesFlags(t *testing.T) {
"wifi": true,
"ieee802154": true,
"sysctl": true,
+ "swap": true,
}},
{"close_fds", "none", true, map[string]bool{
"close_fds": true,
}},
+ {"swap", "none", true, map[string]bool{
+ "swap": true,
+ }},
}
for i, test := range tests {
features, err := ParseFeaturesFlags(test.Enable, test.Disable, test.Default)
diff --git a/pkg/host/features.go b/pkg/host/features.go
index 343e76783..b8ec837f0 100644
--- a/pkg/host/features.go
+++ b/pkg/host/features.go
@@ -34,6 +34,7 @@ const (
FeatureVhciInjection
FeatureWifiEmulation
Feature802154Emulation
+ FeatureSwap
numFeatures
)
@@ -77,6 +78,7 @@ func Check(target *prog.Target) (*Features, error) {
FeatureVhciInjection: {Name: "hci packet injection", Reason: unsupported},
FeatureWifiEmulation: {Name: "wifi device emulation", Reason: unsupported},
Feature802154Emulation: {Name: "802.15.4 emulation", Reason: unsupported},
+ FeatureSwap: {Name: "swap file", Reason: unsupported},
}
if noHostChecks(target) {
return res, nil
@@ -125,6 +127,9 @@ func Setup(target *prog.Target, features *Features, featureFlags csource.Feature
if featureFlags["ieee802154"].Enabled && features[Feature802154Emulation].Enabled {
args = append(args, "802154")
}
+ if features[FeatureSwap].Enabled {
+ args = append(args, "swap")
+ }
output, err := osutil.RunCmd(5*time.Minute, "", executor, args...)
log.Logf(1, "executor %v\n%s", args, output)
return err
diff --git a/pkg/host/features_linux.go b/pkg/host/features_linux.go
index 142e58e3b..408e219eb 100644
--- a/pkg/host/features_linux.go
+++ b/pkg/host/features_linux.go
@@ -5,6 +5,7 @@ package host
import (
"fmt"
+ "os/exec"
"regexp"
"runtime"
"runtime/debug"
@@ -37,6 +38,7 @@ func init() {
checkFeature[FeatureVhciInjection] = checkVhciInjection
checkFeature[FeatureWifiEmulation] = checkWifiEmulation
checkFeature[Feature802154Emulation] = check802154Emulation
+ checkFeature[FeatureSwap] = checkSwap
}
func checkCoverage() string {
@@ -287,6 +289,16 @@ func check802154Emulation() string {
return ""
}
+func checkSwap() string {
+ if err := osutil.IsAccessible("/proc/swaps"); err != nil {
+ return err.Error()
+ }
+ if _, err := exec.LookPath("mkswap"); err != nil {
+ return "mkswap is not available"
+ }
+ return ""
+}
+
func requireKernel(x, y int) string {
info := new(unix.Utsname)
if err := unix.Uname(info); err != nil {
diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go
index 87b9eaa4c..9cfb28dd8 100644
--- a/pkg/repro/repro.go
+++ b/pkg/repro/repro.go
@@ -201,6 +201,9 @@ func createStartOptions(cfg *mgrconfig.Config, features *host.Features, crashTyp
if !features[host.Feature802154Emulation].Enabled {
opts.IEEE802154 = false
}
+ if !features[host.FeatureSwap].Enabled {
+ opts.Swap = false
+ }
}
return opts
}
@@ -817,6 +820,7 @@ var cSimplifies = append(progSimplifies, []Simplify{
opts.USB = false
opts.VhciInjection = false
opts.Wifi = false
+ opts.Swap = false
return true
},
func(opts *csource.Options) bool {
@@ -926,4 +930,11 @@ var cSimplifies = append(progSimplifies, []Simplify{
opts.Sysctl = false
return true
},
+ func(opts *csource.Options) bool {
+ if !opts.Swap {
+ return false
+ }
+ opts.Swap = false
+ return true
+ },
}...)
diff --git a/pkg/runtest/run.go b/pkg/runtest/run.go
index 1952a9f98..3e4543fab 100644
--- a/pkg/runtest/run.go
+++ b/pkg/runtest/run.go
@@ -467,6 +467,7 @@ func (ctx *Context) createCTest(p *prog.Prog, sandbox string, threaded bool, tim
HandleSegv: true,
Cgroups: p.Target.OS == targets.Linux && sandbox != "",
Trace: true,
+ Swap: ctx.Features[host.FeatureSwap].Enabled,
}
if sandbox != "" {
if ctx.Features[host.FeatureNetInjection].Enabled {