diff --git a/main.go b/main.go index 2b22d37..887794a 100644 --- a/main.go +++ b/main.go @@ -171,8 +171,9 @@ func main() { // Bump new compat files if !*dryRun { - log.Infoln("Bumping new compat tables") + log.Infoln("Bumping new compat tables and ia32 to 64 x86 map table") bumpCompats(linuxMap) + bumpIA32to64Map(linuxMap["x86_64"]) } else { log.Infoln("Would have bumped compat tables", linuxMap) } @@ -486,6 +487,7 @@ func bumpCompats(systemMap map[string]SyscallMap) { log.Fatal(err) } + writeBanner(fW) _, _ = fW.WriteString("#pragma once\n") for _, kv := range values { _, _ = fW.WriteString("#ifndef __NR_" + kv.Key + "\n") @@ -511,6 +513,71 @@ func bumpPatchSchemaVersion() { }) } +// Define here any translation between ia32 syscall nr and corresponding 64 bit compatible syscall. +var ia32TranslatorMap = map[int64]int64{ + /* + * 192 is mmap2 on ia32; since it is not defined on x86_64, + * and we manage it exactly like mmap, convert it to a mmap x86_64 + */ + 192: 9, +} + +func bumpIA32to64Map(x64Map SyscallMap) { + fp := *libsRepoRoot + "/driver/syscall_ia32_64_map.c" + + x32Map := loadSyscallMap("https://raw.githubusercontent.com/hrw/syscalls-table/master/tables/syscalls-i386", func(line string) (string, int64) { + fields := strings.Fields(line) + if len(fields) == 2 { + syscallNr, _ := strconv.ParseInt(fields[1], 10, 64) + return "__NR_" + fields[0], syscallNr + } + return "", -1 + }) + + // Step 2: dump the new content to local (temp) file + err := os.MkdirAll("driver", os.ModePerm) + if err != nil { + log.Fatal(err) + } + fW, err := os.Create("driver/" + filepath.Base(fp)) + if err != nil { + log.Fatal(err) + } + + writeBanner(fW) + + _, _ = fW.WriteString("#include \"ppm_events_public.h\"\n") + _, _ = fW.WriteString(` +/* + * This table is used by drivers when receiving a 32bit syscall. + * It is needed to convert a 32bit syscall (the array index) to a 64bit syscall value. + * NOTE: some syscalls might be unavailable on x86_64; their value will be set to -1. + * Some unavailable syscalls are identical to a compatible x86_64 syscall; in those cases, + * we use the compatible x86_64 syscall, eg: mmap2 -> mmap. + */ +`) + _, _ = fW.WriteString("const int g_ia32_64_map[SYSCALL_TABLE_SIZE] = {\n") + for x32Name, x32Nr := range x32Map { + x32NrStr := strconv.FormatInt(x32Nr, 10) + if x64Nr, ok := x64Map[x32Name]; ok { + x64NrStr := strconv.FormatInt(x64Nr, 10) + _, _ = fW.WriteString("\t[" + x32NrStr + "] = " + x64NrStr + ",\n") + } else { + x64Nr, translated := ia32TranslatorMap[x32Nr] + if translated { + x64NrStr := strconv.FormatInt(x64Nr, 10) + _, _ = fW.WriteString("\t[" + x32NrStr + "] = " + x64NrStr + ", // NOTE: syscall unmapped on x86_64, forcefully mapped to compatible syscall. See syscalls-bumper bumpIA32to64Map() call.\n") + } else { + _, _ = fW.WriteString("\t[" + x32NrStr + "] = -1, // ia32 only: " + x32Name + "\n") + } + } + } + _, _ = fW.WriteString("};\n") + + checkOverwriteRepoFile(fW, fp) + _ = fW.Close() +} + func checkOverwriteRepoFile(fW *os.File, fp string) { if *overwrite { // Step 3: no error -> move temp file to real file @@ -522,3 +589,23 @@ func checkOverwriteRepoFile(fW *os.File, fp string) { log.Infoln("Output file: ", fW.Name()) } } + +func writeBanner(fW *os.File) { + _, _ = fW.WriteString( + `// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + +Copyright (C) 2023 The Falco Authors. + +This file is dual licensed under either the MIT or GPL 2. See MIT.txt +or GPL2.txt for full copies of the license. + +*/ + +/* + * This file was automatically created by syscalls-bumper (https://github.com/falcosecurity/syscalls-bumper).") + * DO NOT EDIT THIS FILE MANUALLY.") + */ + +`) +}