third_party/cap: initialize
This adds libcap which is needed for any chance at running chrony as non-root.
Upstream contains a multi-stage codegen based on various external utilities
which has been replaced by a clean Go script. Upstream is capable of also
using gperf to generate hash tables for faster lookups, but due to the
extremely low amount of items (~40) and the additional complexity this is
not enabled.
This is not tested standalone, but it has been tested with chrony.
Change-Id: I638f6aea98158cd2e2838531a5a6125e724838f5
Reviewed-on: https://review.monogon.dev/c/monogon/+/317
Reviewed-by: Sergiusz Bazanski <serge@monogon.tech>
diff --git a/third_party/cap/patches/add_go_codegen.patch b/third_party/cap/patches/add_go_codegen.patch
new file mode 100644
index 0000000..2572367
--- /dev/null
+++ b/third_party/cap/patches/add_go_codegen.patch
@@ -0,0 +1,78 @@
+--- /dev/null
++++ b/makenames.go
+@@ -0,0 +1,73 @@
++// makenames replaces the built-in array generation consisting of Perl incantations being
++// consumed by C code with a single implementation that's shorter anyways.
++package main
++
++import (
++ "io/ioutil"
++ "log"
++ "os"
++ "regexp"
++ "strconv"
++ "strings"
++ "text/template"
++)
++
++type tmplParams struct {
++ Bits int
++ NameSize int
++ Caps []string
++}
++
++var capNamesTmpl = template.Must(template.New("cap_names").Parse(`/*
++ * DO NOT EDIT: this file is generated automatically from
++ *
++ * <uapi/linux/capability.h>
++ */
++
++#define __CAP_BITS {{ .Bits }}
++#define __CAP_NAME_SIZE {{ .NameSize }}
++
++#ifdef LIBCAP_PLEASE_INCLUDE_ARRAY
++#define LIBCAP_CAP_NAMES { \
++{{ range $i, $name := .Caps }} /* {{ $i }} */ {{ if $name }}"{{ $name }}"{{else}}NULL, /* - presently unused */{{end}}, \
++{{end}} }
++#endif /* LIBCAP_PLEASE_INCLUDE_ARRAY */
++
++/* END OF FILE */
++`))
++
++var capRe = regexp.MustCompile(`(?m)^#define[ \t](CAP[_A-Z]+)[ \t]+([0-9]+)\s+$`)
++
++func main() {
++ sourceFile, err := ioutil.ReadFile(os.Args[1])
++ if err != nil {
++ log.Fatalln(err)
++ }
++
++ matches := capRe.FindAllStringSubmatch(string(sourceFile), -1)
++ out := tmplParams{
++ Caps: make([]string, 1024),
++ }
++ for _, m := range matches {
++ i, err := strconv.Atoi(m[2])
++ if err != nil {
++ log.Fatalln(err)
++ }
++ if i+1 > out.Bits {
++ out.Bits = i + 1
++ }
++ if len(m[1])+1 > out.NameSize {
++ out.NameSize = len(m[1]) + 1
++ }
++ out.Caps[i] = strings.ToLower(m[1])
++ }
++ out.Caps = out.Caps[:out.Bits]
++ outFile, err := os.Create(os.Args[2])
++ if err != nil {
++ log.Fatalln(err)
++ }
++ if err := capNamesTmpl.ExecuteTemplate(outFile, "cap_names", &out); err != nil {
++ log.Fatalln(err)
++ }
++ outFile.Close()
++}
+--
+2.25.1