diff --git a/go.mod b/go.mod index 199dfb9c3016..00bc8ad293d1 100644 --- a/go.mod +++ b/go.mod @@ -61,11 +61,11 @@ require ( github.com/opencontainers/go-digest v1.0.0 github.com/openshift-eng/openshift-tests-extension v0.0.0-20251218142942-7ecc8801b9df github.com/openshift-kni/commatrix v0.0.5-0.20251111204857-e5a931eff73f - github.com/openshift/api v0.0.0-20260212193555-c06ab675261f + github.com/openshift/api v0.0.0-20260114133223-6ab113cb7368 github.com/openshift/apiserver-library-go v0.0.0-20251015164739-79d04067059d github.com/openshift/build-machinery-go v0.0.0-20250530140348-dc5b2804eeee github.com/openshift/client-go v0.0.0-20260108185524-48f4ccfc4e13 - github.com/openshift/library-go v0.0.0-20260223145824-7b234b47a906 + github.com/openshift/library-go v0.0.0-20251015151611-6fc7a74b67c5 github.com/ovn-org/ovn-kubernetes/go-controller v0.0.0-20250118001652-a8b9c3c31417 github.com/pborman/uuid v1.2.0 github.com/pkg/errors v0.9.1 @@ -89,12 +89,12 @@ require ( go.etcd.io/etcd/api/v3 v3.6.4 go.etcd.io/etcd/client/pkg/v3 v3.6.4 go.etcd.io/etcd/client/v3 v3.6.4 - golang.org/x/crypto v0.45.0 + golang.org/x/crypto v0.42.0 golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b - golang.org/x/mod v0.29.0 - golang.org/x/net v0.47.0 + golang.org/x/mod v0.27.0 + golang.org/x/net v0.43.0 golang.org/x/oauth2 v0.30.0 - golang.org/x/sync v0.18.0 + golang.org/x/sync v0.17.0 gonum.org/v1/plot v0.14.0 google.golang.org/api v0.247.0 google.golang.org/grpc v1.75.1 @@ -135,7 +135,6 @@ require ( cloud.google.com/go/compute/metadata v0.8.0 // indirect cloud.google.com/go/iam v1.5.2 // indirect cloud.google.com/go/monitoring v1.24.2 // indirect - cyphar.com/go-pathrs v0.2.1 // indirect git.sr.ht/~sbinet/gg v0.5.0 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/Azure/azure-pipeline-go v0.2.3 // indirect @@ -188,7 +187,7 @@ require ( github.com/coreos/go-oidc v2.3.0+incompatible // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/cyphar/filepath-securejoin v0.6.0 // indirect + github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/dimchansky/utfbom v1.1.1 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/go-connections v0.5.0 // indirect @@ -315,7 +314,7 @@ require ( github.com/opencontainers/image-spec v1.1.1 // indirect github.com/opencontainers/runc v1.2.5 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect - github.com/opencontainers/selinux v1.13.0 // indirect + github.com/opencontainers/selinux v1.11.1 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect @@ -374,11 +373,11 @@ require ( go.yaml.in/yaml/v2 v2.4.2 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/image v0.11.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect golang.org/x/time v0.12.0 // indirect - golang.org/x/tools v0.38.0 // indirect + golang.org/x/tools v0.36.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c // indirect @@ -413,11 +412,6 @@ require ( ) replace ( - // filepath-securejoin v0.6.0 removed MkdirAllHandle from the root package (moved to pathrs-lite). - // opencontainers/runc v1.2.5 still calls securejoin.MkdirAllHandle from root. - // Point to a patched fork that re-exports MkdirAllHandle from root for compatibility. - // TODO: Remove once opencontainers/runc is updated to use pathrs-lite directly. - github.com/cyphar/filepath-securejoin => github.com/wangke19/filepath-securejoin-1 v0.6.2-0.20260309113322-d8b3e820b3d6 github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 k8s.io/api => github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20251017123720-96593f323733 diff --git a/go.sum b/go.sum index 7dc4fb9dfe5c..a094396ccacb 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,6 @@ cloud.google.com/go/storage v1.56.0 h1:iixmq2Fse2tqxMbWhLWC9HfBj1qdxqAmiK8/eqtsL cloud.google.com/go/storage v1.56.0/go.mod h1:Tpuj6t4NweCLzlNbw9Z9iwxEkrSem20AetIeH/shgVU= cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4= cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI= -cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8= -cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -284,6 +282,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6N github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= +github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -822,14 +822,14 @@ github.com/opencontainers/runc v1.2.5 h1:8KAkq3Wrem8bApgOHyhRI/8IeLXIfmZ6Qaw6DNS github.com/opencontainers/runc v1.2.5/go.mod h1:dOQeFo29xZKBNeRBI0B19mJtfHv68YgCTh1X+YphA+4= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.13.0 h1:Zza88GWezyT7RLql12URvoxsbLfjFx988+LGaWfbL84= -github.com/opencontainers/selinux v1.13.0/go.mod h1:XxWTed+A/s5NNq4GmYScVy+9jzXhGBVEOAyucdRUY8s= +github.com/opencontainers/selinux v1.11.1 h1:nHFvthhM0qY8/m+vfhJylliSshm8G1jJ2jDMcgULaH8= +github.com/opencontainers/selinux v1.11.1/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/openshift-eng/openshift-tests-extension v0.0.0-20251218142942-7ecc8801b9df h1:/KiCxPFpkZN4HErfAX5tyhn6G3ziPFbkGswHVAZKY5Q= github.com/openshift-eng/openshift-tests-extension v0.0.0-20251218142942-7ecc8801b9df/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M= github.com/openshift-kni/commatrix v0.0.5-0.20251111204857-e5a931eff73f h1:E72Zoc+JImPehBrXkgaCbIDbSFuItvyX6RCaZ0FQE5k= github.com/openshift-kni/commatrix v0.0.5-0.20251111204857-e5a931eff73f/go.mod h1:cDVdp0eda7EHE6tLuSeo4IqPWdAX/KJK+ogBirIGtsI= -github.com/openshift/api v0.0.0-20260212193555-c06ab675261f h1:l1IgsK48Ym/nED30yfaCTF4MtswO1eOoyfXgh2rEmdw= -github.com/openshift/api v0.0.0-20260212193555-c06ab675261f/go.mod h1:d5uzF0YN2nQQFA0jIEWzzOZ+edmo6wzlGLvx5Fhz4uY= +github.com/openshift/api v0.0.0-20260114133223-6ab113cb7368 h1:kSr3DOlq0NCrHd65HB2o/pBsks7AfRm+fkpf9RLUPoc= +github.com/openshift/api v0.0.0-20260114133223-6ab113cb7368/go.mod h1:d5uzF0YN2nQQFA0jIEWzzOZ+edmo6wzlGLvx5Fhz4uY= github.com/openshift/apiserver-library-go v0.0.0-20251015164739-79d04067059d h1:Mfya3RxHWvidOrKyHj3bmFn5x2B89DLZIvDAhwm+C2s= github.com/openshift/apiserver-library-go v0.0.0-20251015164739-79d04067059d/go.mod h1:zm2/rIUp0p83pz0/1kkSoKTqhTr3uUKSKQ9fP7Z3g7Y= github.com/openshift/build-machinery-go v0.0.0-20250530140348-dc5b2804eeee h1:+Sp5GGnjHDhT/a/nQ1xdp43UscBMr7G5wxsYotyhzJ4= @@ -886,8 +886,8 @@ github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0 github.com/openshift/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20251017123720-96593f323733/go.mod h1:yuCdx9wLndqpNhmsYZh48wtbgrqc8ql1191ke9zIOfg= github.com/openshift/kubernetes/staging/src/k8s.io/sample-apiserver v0.0.0-20251017123720-96593f323733 h1:BGNp5XlBh6O6GGOzo2698VK5dCVUL58+pKNMb0DB98o= github.com/openshift/kubernetes/staging/src/k8s.io/sample-apiserver v0.0.0-20251017123720-96593f323733/go.mod h1:7JLAj6I7UWR3Akqvb3hwGRBdV3dgTASNQJhMqdowC0s= -github.com/openshift/library-go v0.0.0-20260223145824-7b234b47a906 h1:PkG3CmlU8+HtlW1rspnhwhbKki8rrwYN+L26aH11t2E= -github.com/openshift/library-go v0.0.0-20260223145824-7b234b47a906/go.mod h1:K3FoNLgNBFYbFuG+Kr8usAnQxj1w84XogyUp2M8rK8k= +github.com/openshift/library-go v0.0.0-20251015151611-6fc7a74b67c5 h1:bANtDc8SgetSK4nQehf59x3+H9FqVJCprgjs49/OTg0= +github.com/openshift/library-go v0.0.0-20251015151611-6fc7a74b67c5/go.mod h1:OlFFws1AO51uzfc48MsStGE4SFMWlMZD0+f5a/zCtKI= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 h1:PMTgifBcBRLJJiM+LgSzPDTk9/Rx4qS09OUrfpY6GBQ= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -1027,8 +1027,6 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7 github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/vmware/govmomi v0.51.0 h1:n3RLS9aw/irTOKbiIyJzAb6rOat4YOVv/uDoRsNTSQI= github.com/vmware/govmomi v0.51.0/go.mod h1:3ywivawGRfMP2SDCeyKqxTl2xNIHTXF0ilvp72dot5A= -github.com/wangke19/filepath-securejoin-1 v0.6.2-0.20260309113322-d8b3e820b3d6 h1:prZrj2ZRa0wugbd/r6qGFHRMxCYwhamQG/Xk8+zCKjc= -github.com/wangke19/filepath-securejoin-1 v0.6.2-0.20260309113322-d8b3e820b3d6/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= @@ -1149,8 +1147,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1192,8 +1190,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= +golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1239,8 +1237,8 @@ golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1268,8 +1266,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1332,15 +1330,15 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1354,8 +1352,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1416,8 +1414,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= +golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/test/extended/apiserver/tls.go b/test/extended/apiserver/tls.go index 33bf54a9c19d..58ac08e1524d 100644 --- a/test/extended/apiserver/tls.go +++ b/test/extended/apiserver/tls.go @@ -121,27 +121,11 @@ var _ = g.Describe("[sig-api-machinery][Feature:APIServer]", func() { config, err := oc.AdminConfigClient().ConfigV1().APIServers().Get(ctx, "cluster", metav1.GetOptions{}) o.Expect(err).NotTo(o.HaveOccurred()) - g.By("Determining expected TLS behavior based on the cluster's TLS profile") - var minTLSVersion uint16 - var testCipherSuites bool - switch { - case config.Spec.TLSSecurityProfile == nil, - config.Spec.TLSSecurityProfile.Type == configv1.TLSProfileIntermediateType: - minTLSVersion = crypto.DefaultTLSVersion() // TLS 1.2 - testCipherSuites = true - g.By("Using intermediate TLS profile: TLS ≥1.2 should work") - case config.Spec.TLSSecurityProfile.Type == configv1.TLSProfileModernType: - minTLSVersion = tls.VersionTLS13 - testCipherSuites = false // TLS 1.3 cipher suites are not configurable - g.By("Using modern TLS profile: only TLS 1.3 should work") - default: - g.Skip("Only intermediate or modern profiles are tested") + if config.Spec.TLSSecurityProfile != nil && + config.Spec.TLSSecurityProfile.Type != configv1.TLSProfileIntermediateType { + g.Skip("Cluster TLS profile is not default (intermediate), skipping cipher defaults check") } - g.By("Checking if the cluster is running in FIPS mode") - isFIPS, err := exutil.IsFIPS(oc.AdminKubeClient().CoreV1()) - o.Expect(err).NotTo(o.HaveOccurred()) - g.By("Verifying TLS version and cipher behavior via port-forward to apiserver") err = forwardPortAndExecute("apiserver", "openshift-kube-apiserver", "443", func(port int) error { host := fmt.Sprintf("localhost:%d", port) @@ -150,7 +134,7 @@ var _ = g.Describe("[sig-api-machinery][Feature:APIServer]", func() { // Test TLS versions for _, tlsVersionName := range crypto.ValidTLSVersions() { tlsVersion := crypto.TLSVersionOrDie(tlsVersionName) - expectSuccess := tlsVersion >= minTLSVersion + expectSuccess := tlsVersion >= crypto.DefaultTLSVersion() cfg := &tls.Config{MinVersion: tlsVersion, MaxVersion: tlsVersion, InsecureSkipVerify: true} t.Logf("Testing TLS version %s (0x%04x), expectSuccess=%v", tlsVersionName, tlsVersion, expectSuccess) @@ -169,70 +153,35 @@ var _ = g.Describe("[sig-api-machinery][Feature:APIServer]", func() { } } - // Test cipher suites (only for profiles where cipher suites are configurable) - if testCipherSuites { - defaultCiphers := map[uint16]bool{} - for _, c := range crypto.DefaultCiphers() { - defaultCiphers[c] = true - } - - for _, cipherName := range crypto.ValidCipherSuites() { - cipher, err := crypto.CipherSuite(cipherName) - if err != nil { - return err - } - - // Skip TLS 1.3 cipher suites when testing with TLS 1.2. - // TLS 1.3 ciphers are predetermined and cannot be configured via CipherSuites. - if isTLS13Cipher(cipher) { - continue - } - - expectFailure := !defaultCiphers[cipher] - - // ECDSA cipher suites require an ECDSA server certificate/key. - // OpenShift uses RSA keys for all certificates (library-go's - // NewKeyPair generates RSA), so ECDSA ciphers will always fail - // the TLS handshake even when the server has them configured. - // Go's TLS server silently skips cipher suites that are - // incompatible with the server's key type during negotiation. - // The TLS profiles (Old, Intermediate) intentionally include - // both ECDSA and RSA ciphers for broad compatibility per - // Mozilla Server Side TLS guidelines. - if strings.Contains(cipherName, "ECDSA") { - expectFailure = true - } - - // ChaCha20-Poly1305 is not a FIPS 140-2/140-3 approved algorithm. - // In FIPS mode, Go's crypto library disables ChaCha20-Poly1305, - // so the kube-apiserver cannot negotiate these ciphers even when - // they appear in the configured cipher list. - if isFIPS && strings.Contains(cipherName, "CHACHA20") { - expectFailure = true - } + // Test cipher suites + defaultCiphers := map[uint16]bool{} + for _, c := range crypto.DefaultCiphers() { + defaultCiphers[c] = true + } - // Constrain to TLS 1.2 because the intermediate profile allows both TLS 1.2 and TLS 1.3. - // If MaxVersion is unspecified, the client negotiates TLS 1.3 when the server supports it. - // TLS 1.3 does not support configuring cipher suites (predetermined by the spec), so - // specifying any cipher suite (RC4 or otherwise) has no effect with TLS 1.3. - // By forcing TLS 1.2, we can actually test the cipher suite restrictions. - cfg := &tls.Config{ - CipherSuites: []uint16{cipher}, - MinVersion: tls.VersionTLS12, - MaxVersion: tls.VersionTLS12, - InsecureSkipVerify: true, - } + for _, cipherName := range crypto.ValidCipherSuites() { + cipher, err := crypto.CipherSuite(cipherName) + if err != nil { + return err + } + expectFailure := !defaultCiphers[cipher] + // Constrain to TLS 1.2 because the intermediate profile allows both TLS 1.2 and TLS 1.3. + // If MaxVersion is unspecified, the client negotiates TLS 1.3 when the server supports it. + // TLS 1.3 does not support configuring cipher suites (predetermined by the spec), so + // specifying any cipher suite (RC4 or otherwise) has no effect with TLS 1.3. + // By forcing TLS 1.2, we can actually test the cipher suite restrictions. + cfg := &tls.Config{ + CipherSuites: []uint16{cipher}, + MinVersion: tls.VersionTLS12, + MaxVersion: tls.VersionTLS12, + InsecureSkipVerify: true, + } - conn, dialErr := tls.Dial("tcp", host, cfg) - if dialErr != nil { - if !expectFailure { - return fmt.Errorf("expected success on cipher %s, got error: %v", cipherName, dialErr) - } - } else { - closeErr := conn.Close() - if expectFailure { - return fmt.Errorf("expected failure on cipher %s, got success. Closing conn: %v", cipherName, closeErr) - } + conn, dialErr := tls.Dial("tcp", host, cfg) + if dialErr == nil { + closeErr := conn.Close() + if expectFailure { + return fmt.Errorf("expected failure on cipher %s, got success. Closing conn: %v", cipherName, closeErr) } } } @@ -243,14 +192,6 @@ var _ = g.Describe("[sig-api-machinery][Feature:APIServer]", func() { }) }) -// isTLS13Cipher returns true if the cipher suite is TLS 1.3-specific. -// TLS 1.3 cipher suites are predetermined and cannot be configured via CipherSuites. -func isTLS13Cipher(cipher uint16) bool { - return cipher == tls.TLS_AES_128_GCM_SHA256 || - cipher == tls.TLS_AES_256_GCM_SHA384 || - cipher == tls.TLS_CHACHA20_POLY1305_SHA256 -} - func forwardPortAndExecute(serviceName, namespace, remotePort string, toExecute func(localPort int) error) error { var err error for i := 0; i < 3; i++ { diff --git a/vendor/cyphar.com/go-pathrs/.golangci.yml b/vendor/cyphar.com/go-pathrs/.golangci.yml deleted file mode 100644 index 2778a3268ef1..000000000000 --- a/vendor/cyphar.com/go-pathrs/.golangci.yml +++ /dev/null @@ -1,43 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# -# libpathrs: safe path resolution on Linux -# Copyright (C) 2019-2025 Aleksa Sarai -# Copyright (C) 2019-2025 SUSE LLC -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -version: "2" -linters: - enable: - - bidichk - - cyclop - - errname - - errorlint - - exhaustive - - goconst - - godot - - gomoddirectives - - gosec - - mirror - - misspell - - mnd - - nilerr - - nilnil - - perfsprint - - prealloc - - reassign - - revive - - unconvert - - unparam - - usestdlibvars - - wastedassign -formatters: - enable: - - gofumpt - - goimports - settings: - goimports: - local-prefixes: - - cyphar.com/go-pathrs diff --git a/vendor/cyphar.com/go-pathrs/COPYING b/vendor/cyphar.com/go-pathrs/COPYING deleted file mode 100644 index d0a1fa1482ee..000000000000 --- a/vendor/cyphar.com/go-pathrs/COPYING +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at https://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/vendor/cyphar.com/go-pathrs/doc.go b/vendor/cyphar.com/go-pathrs/doc.go deleted file mode 100644 index a7ee4bc487fa..000000000000 --- a/vendor/cyphar.com/go-pathrs/doc.go +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/* - * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai - * Copyright (C) 2019-2025 SUSE LLC - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -// Package pathrs provides bindings for libpathrs, a library for safe path -// resolution on Linux. -package pathrs diff --git a/vendor/cyphar.com/go-pathrs/handle_linux.go b/vendor/cyphar.com/go-pathrs/handle_linux.go deleted file mode 100644 index 3221ef673898..000000000000 --- a/vendor/cyphar.com/go-pathrs/handle_linux.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build linux - -// SPDX-License-Identifier: MPL-2.0 -/* - * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai - * Copyright (C) 2019-2025 SUSE LLC - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package pathrs - -import ( - "fmt" - "os" - - "cyphar.com/go-pathrs/internal/fdutils" - "cyphar.com/go-pathrs/internal/libpathrs" -) - -// Handle is a handle for a path within a given [Root]. This handle references -// an already-resolved path which can be used for only one purpose -- to -// "re-open" the handle and get an actual [os.File] which can be used for -// ordinary operations. -// -// If you wish to open a file without having an intermediate [Handle] object, -// you can try to use [Root.Open] or [Root.OpenFile]. -// -// It is critical that perform all relevant operations through this [Handle] -// (rather than fetching the file descriptor yourself with [Handle.IntoRaw]), -// because the security properties of libpathrs depend on users doing all -// relevant filesystem operations through libpathrs. -// -// [os.File]: https://pkg.go.dev/os#File -type Handle struct { - inner *os.File -} - -// HandleFromFile creates a new [Handle] from an existing file handle. The -// handle will be copied by this method, so the original handle should still be -// freed by the caller. -// -// This is effectively the inverse operation of [Handle.IntoRaw], and is used -// for "deserialising" pathrs root handles. -func HandleFromFile(file *os.File) (*Handle, error) { - newFile, err := fdutils.DupFile(file) - if err != nil { - return nil, fmt.Errorf("duplicate handle fd: %w", err) - } - return &Handle{inner: newFile}, nil -} - -// Open creates an "upgraded" file handle to the file referenced by the -// [Handle]. Note that the original [Handle] is not consumed by this operation, -// and can be opened multiple times. -// -// The handle returned is only usable for reading, and this is method is -// shorthand for [Handle.OpenFile] with os.O_RDONLY. -// -// TODO: Rename these to "Reopen" or something. -func (h *Handle) Open() (*os.File, error) { - return h.OpenFile(os.O_RDONLY) -} - -// OpenFile creates an "upgraded" file handle to the file referenced by the -// [Handle]. Note that the original [Handle] is not consumed by this operation, -// and can be opened multiple times. -// -// The provided flags indicate which open(2) flags are used to create the new -// handle. -// -// TODO: Rename these to "Reopen" or something. -func (h *Handle) OpenFile(flags int) (*os.File, error) { - return fdutils.WithFileFd(h.inner, func(fd uintptr) (*os.File, error) { - newFd, err := libpathrs.Reopen(fd, flags) - if err != nil { - return nil, err - } - return os.NewFile(newFd, h.inner.Name()), nil - }) -} - -// IntoFile unwraps the [Handle] into its underlying [os.File]. -// -// You almost certainly want to use [Handle.OpenFile] to get a non-O_PATH -// version of this [Handle]. -// -// This operation returns the internal [os.File] of the [Handle] directly, so -// calling [Handle.Close] will also close any copies of the returned [os.File]. -// If you want to get an independent copy, use [Handle.Clone] followed by -// [Handle.IntoFile] on the cloned [Handle]. -// -// [os.File]: https://pkg.go.dev/os#File -func (h *Handle) IntoFile() *os.File { - // TODO: Figure out if we really don't want to make a copy. - // TODO: We almost certainly want to clear r.inner here, but we can't do - // that easily atomically (we could use atomic.Value but that'll make - // things quite a bit uglier). - return h.inner -} - -// Clone creates a copy of a [Handle], such that it has a separate lifetime to -// the original (while referring to the same underlying file). -func (h *Handle) Clone() (*Handle, error) { - return HandleFromFile(h.inner) -} - -// Close frees all of the resources used by the [Handle]. -func (h *Handle) Close() error { - return h.inner.Close() -} diff --git a/vendor/cyphar.com/go-pathrs/internal/fdutils/fd_linux.go b/vendor/cyphar.com/go-pathrs/internal/fdutils/fd_linux.go deleted file mode 100644 index 41aea3e4b3de..000000000000 --- a/vendor/cyphar.com/go-pathrs/internal/fdutils/fd_linux.go +++ /dev/null @@ -1,75 +0,0 @@ -//go:build linux - -// SPDX-License-Identifier: MPL-2.0 -/* - * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai - * Copyright (C) 2019-2025 SUSE LLC - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -// Package fdutils contains a few helper methods when dealing with *os.File and -// file descriptors. -package fdutils - -import ( - "fmt" - "os" - - "golang.org/x/sys/unix" - - "cyphar.com/go-pathrs/internal/libpathrs" -) - -// DupFd makes a duplicate of the given fd. -func DupFd(fd uintptr, name string) (*os.File, error) { - newFd, err := unix.FcntlInt(fd, unix.F_DUPFD_CLOEXEC, 0) - if err != nil { - return nil, fmt.Errorf("fcntl(F_DUPFD_CLOEXEC): %w", err) - } - return os.NewFile(uintptr(newFd), name), nil -} - -// WithFileFd is a more ergonomic wrapper around file.SyscallConn().Control(). -func WithFileFd[T any](file *os.File, fn func(fd uintptr) (T, error)) (T, error) { - conn, err := file.SyscallConn() - if err != nil { - return *new(T), err - } - var ( - ret T - innerErr error - ) - if err := conn.Control(func(fd uintptr) { - ret, innerErr = fn(fd) - }); err != nil { - return *new(T), err - } - return ret, innerErr -} - -// DupFile makes a duplicate of the given file. -func DupFile(file *os.File) (*os.File, error) { - return WithFileFd(file, func(fd uintptr) (*os.File, error) { - return DupFd(fd, file.Name()) - }) -} - -// MkFile creates a new *os.File from the provided file descriptor. However, -// unlike os.NewFile, the file's Name is based on the real path (provided by -// /proc/self/fd/$n). -func MkFile(fd uintptr) (*os.File, error) { - fdPath := fmt.Sprintf("fd/%d", fd) - fdName, err := libpathrs.ProcReadlinkat(libpathrs.ProcDefaultRootFd, libpathrs.ProcThreadSelf, fdPath) - if err != nil { - _ = unix.Close(int(fd)) - return nil, fmt.Errorf("failed to fetch real name of fd %d: %w", fd, err) - } - // TODO: Maybe we should prefix this name with something to indicate to - // users that they must not use this path as a "safe" path. Something like - // "//pathrs-handle:/foo/bar"? - return os.NewFile(fd, fdName), nil -} diff --git a/vendor/cyphar.com/go-pathrs/internal/libpathrs/error_unix.go b/vendor/cyphar.com/go-pathrs/internal/libpathrs/error_unix.go deleted file mode 100644 index c9f416de01f8..000000000000 --- a/vendor/cyphar.com/go-pathrs/internal/libpathrs/error_unix.go +++ /dev/null @@ -1,40 +0,0 @@ -//go:build linux - -// TODO: Use "go:build unix" once we bump the minimum Go version 1.19. - -// SPDX-License-Identifier: MPL-2.0 -/* - * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai - * Copyright (C) 2019-2025 SUSE LLC - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package libpathrs - -import ( - "syscall" -) - -// Error represents an underlying libpathrs error. -type Error struct { - description string - errno syscall.Errno -} - -// Error returns a textual description of the error. -func (err *Error) Error() string { - return err.description -} - -// Unwrap returns the underlying error which was wrapped by this error (if -// applicable). -func (err *Error) Unwrap() error { - if err.errno != 0 { - return err.errno - } - return nil -} diff --git a/vendor/cyphar.com/go-pathrs/internal/libpathrs/libpathrs_linux.go b/vendor/cyphar.com/go-pathrs/internal/libpathrs/libpathrs_linux.go deleted file mode 100644 index c07b80e30719..000000000000 --- a/vendor/cyphar.com/go-pathrs/internal/libpathrs/libpathrs_linux.go +++ /dev/null @@ -1,337 +0,0 @@ -//go:build linux - -// SPDX-License-Identifier: MPL-2.0 -/* - * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai - * Copyright (C) 2019-2025 SUSE LLC - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -// Package libpathrs is an internal thin wrapper around the libpathrs C API. -package libpathrs - -import ( - "fmt" - "syscall" - "unsafe" -) - -/* -// TODO: Figure out if we need to add support for linking against libpathrs -// statically even if in dynamically linked builds in order to make -// packaging a bit easier (using "-Wl,-Bstatic -lpathrs -Wl,-Bdynamic" or -// "-l:pathrs.a"). -#cgo pkg-config: pathrs -#include - -// This is a workaround for unsafe.Pointer() not working for non-void pointers. -char *cast_ptr(void *ptr) { return ptr; } -*/ -import "C" - -func fetchError(errID C.int) error { - if errID >= C.__PATHRS_MAX_ERR_VALUE { - return nil - } - cErr := C.pathrs_errorinfo(errID) - defer C.pathrs_errorinfo_free(cErr) - - var err error - if cErr != nil { - err = &Error{ - errno: syscall.Errno(cErr.saved_errno), - description: C.GoString(cErr.description), - } - } - return err -} - -// OpenRoot wraps pathrs_open_root. -func OpenRoot(path string) (uintptr, error) { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - fd := C.pathrs_open_root(cPath) - return uintptr(fd), fetchError(fd) -} - -// Reopen wraps pathrs_reopen. -func Reopen(fd uintptr, flags int) (uintptr, error) { - newFd := C.pathrs_reopen(C.int(fd), C.int(flags)) - return uintptr(newFd), fetchError(newFd) -} - -// InRootResolve wraps pathrs_inroot_resolve. -func InRootResolve(rootFd uintptr, path string) (uintptr, error) { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - fd := C.pathrs_inroot_resolve(C.int(rootFd), cPath) - return uintptr(fd), fetchError(fd) -} - -// InRootResolveNoFollow wraps pathrs_inroot_resolve_nofollow. -func InRootResolveNoFollow(rootFd uintptr, path string) (uintptr, error) { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - fd := C.pathrs_inroot_resolve_nofollow(C.int(rootFd), cPath) - return uintptr(fd), fetchError(fd) -} - -// InRootOpen wraps pathrs_inroot_open. -func InRootOpen(rootFd uintptr, path string, flags int) (uintptr, error) { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - fd := C.pathrs_inroot_open(C.int(rootFd), cPath, C.int(flags)) - return uintptr(fd), fetchError(fd) -} - -// InRootReadlink wraps pathrs_inroot_readlink. -func InRootReadlink(rootFd uintptr, path string) (string, error) { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - size := 128 - for { - linkBuf := make([]byte, size) - n := C.pathrs_inroot_readlink(C.int(rootFd), cPath, C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.ulong(len(linkBuf))) - switch { - case int(n) < C.__PATHRS_MAX_ERR_VALUE: - return "", fetchError(n) - case int(n) <= len(linkBuf): - return string(linkBuf[:int(n)]), nil - default: - // The contents were truncated. Unlike readlinkat, pathrs returns - // the size of the link when it checked. So use the returned size - // as a basis for the reallocated size (but in order to avoid a DoS - // where a magic-link is growing by a single byte each iteration, - // make sure we are a fair bit larger). - size += int(n) - } - } -} - -// InRootRmdir wraps pathrs_inroot_rmdir. -func InRootRmdir(rootFd uintptr, path string) error { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - err := C.pathrs_inroot_rmdir(C.int(rootFd), cPath) - return fetchError(err) -} - -// InRootUnlink wraps pathrs_inroot_unlink. -func InRootUnlink(rootFd uintptr, path string) error { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - err := C.pathrs_inroot_unlink(C.int(rootFd), cPath) - return fetchError(err) -} - -// InRootRemoveAll wraps pathrs_inroot_remove_all. -func InRootRemoveAll(rootFd uintptr, path string) error { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - err := C.pathrs_inroot_remove_all(C.int(rootFd), cPath) - return fetchError(err) -} - -// InRootCreat wraps pathrs_inroot_creat. -func InRootCreat(rootFd uintptr, path string, flags int, mode uint32) (uintptr, error) { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - fd := C.pathrs_inroot_creat(C.int(rootFd), cPath, C.int(flags), C.uint(mode)) - return uintptr(fd), fetchError(fd) -} - -// InRootRename wraps pathrs_inroot_rename. -func InRootRename(rootFd uintptr, src, dst string, flags uint) error { - cSrc := C.CString(src) - defer C.free(unsafe.Pointer(cSrc)) - - cDst := C.CString(dst) - defer C.free(unsafe.Pointer(cDst)) - - err := C.pathrs_inroot_rename(C.int(rootFd), cSrc, cDst, C.uint(flags)) - return fetchError(err) -} - -// InRootMkdir wraps pathrs_inroot_mkdir. -func InRootMkdir(rootFd uintptr, path string, mode uint32) error { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - err := C.pathrs_inroot_mkdir(C.int(rootFd), cPath, C.uint(mode)) - return fetchError(err) -} - -// InRootMkdirAll wraps pathrs_inroot_mkdir_all. -func InRootMkdirAll(rootFd uintptr, path string, mode uint32) (uintptr, error) { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - fd := C.pathrs_inroot_mkdir_all(C.int(rootFd), cPath, C.uint(mode)) - return uintptr(fd), fetchError(fd) -} - -// InRootMknod wraps pathrs_inroot_mknod. -func InRootMknod(rootFd uintptr, path string, mode uint32, dev uint64) error { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - err := C.pathrs_inroot_mknod(C.int(rootFd), cPath, C.uint(mode), C.dev_t(dev)) - return fetchError(err) -} - -// InRootSymlink wraps pathrs_inroot_symlink. -func InRootSymlink(rootFd uintptr, path, target string) error { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - cTarget := C.CString(target) - defer C.free(unsafe.Pointer(cTarget)) - - err := C.pathrs_inroot_symlink(C.int(rootFd), cPath, cTarget) - return fetchError(err) -} - -// InRootHardlink wraps pathrs_inroot_hardlink. -func InRootHardlink(rootFd uintptr, path, target string) error { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - cTarget := C.CString(target) - defer C.free(unsafe.Pointer(cTarget)) - - err := C.pathrs_inroot_hardlink(C.int(rootFd), cPath, cTarget) - return fetchError(err) -} - -// ProcBase is pathrs_proc_base_t (uint64_t). -type ProcBase C.pathrs_proc_base_t - -// FIXME: We need to open-code the constants because CGo unfortunately will -// implicitly convert any non-literal constants (i.e. those resolved using gcc) -// to signed integers. See for some -// more information on the underlying issue (though. -const ( - // ProcRoot is PATHRS_PROC_ROOT. - ProcRoot ProcBase = 0xFFFF_FFFE_7072_6F63 // C.PATHRS_PROC_ROOT - // ProcSelf is PATHRS_PROC_SELF. - ProcSelf ProcBase = 0xFFFF_FFFE_091D_5E1F // C.PATHRS_PROC_SELF - // ProcThreadSelf is PATHRS_PROC_THREAD_SELF. - ProcThreadSelf ProcBase = 0xFFFF_FFFE_3EAD_5E1F // C.PATHRS_PROC_THREAD_SELF - - // ProcBaseTypeMask is __PATHRS_PROC_TYPE_MASK. - ProcBaseTypeMask ProcBase = 0xFFFF_FFFF_0000_0000 // C.__PATHRS_PROC_TYPE_MASK - // ProcBaseTypePid is __PATHRS_PROC_TYPE_PID. - ProcBaseTypePid ProcBase = 0x8000_0000_0000_0000 // C.__PATHRS_PROC_TYPE_PID - - // ProcDefaultRootFd is PATHRS_PROC_DEFAULT_ROOTFD. - ProcDefaultRootFd = -int(syscall.EBADF) // C.PATHRS_PROC_DEFAULT_ROOTFD -) - -func assertEqual[T comparable](a, b T, msg string) { - if a != b { - panic(fmt.Sprintf("%s ((%T) %#v != (%T) %#v)", msg, a, a, b, b)) - } -} - -// Verify that the values above match the actual C values. Unfortunately, Go -// only allows us to forcefully cast int64 to uint64 if you use a temporary -// variable, which means we cannot do it in a const context and thus need to do -// it at runtime (even though it is a check that fundamentally could be done at -// compile-time)... -func init() { - var ( - actualProcRoot int64 = C.PATHRS_PROC_ROOT - actualProcSelf int64 = C.PATHRS_PROC_SELF - actualProcThreadSelf int64 = C.PATHRS_PROC_THREAD_SELF - ) - - assertEqual(ProcRoot, ProcBase(actualProcRoot), "PATHRS_PROC_ROOT") - assertEqual(ProcSelf, ProcBase(actualProcSelf), "PATHRS_PROC_SELF") - assertEqual(ProcThreadSelf, ProcBase(actualProcThreadSelf), "PATHRS_PROC_THREAD_SELF") - - var ( - actualProcBaseTypeMask uint64 = C.__PATHRS_PROC_TYPE_MASK - actualProcBaseTypePid uint64 = C.__PATHRS_PROC_TYPE_PID - ) - - assertEqual(ProcBaseTypeMask, ProcBase(actualProcBaseTypeMask), "__PATHRS_PROC_TYPE_MASK") - assertEqual(ProcBaseTypePid, ProcBase(actualProcBaseTypePid), "__PATHRS_PROC_TYPE_PID") - - assertEqual(ProcDefaultRootFd, int(C.PATHRS_PROC_DEFAULT_ROOTFD), "PATHRS_PROC_DEFAULT_ROOTFD") -} - -// ProcPid reimplements the PROC_PID(x) conversion. -func ProcPid(pid uint32) ProcBase { return ProcBaseTypePid | ProcBase(pid) } - -// ProcOpenat wraps pathrs_proc_openat. -func ProcOpenat(procRootFd int, base ProcBase, path string, flags int) (uintptr, error) { - cBase := C.pathrs_proc_base_t(base) - - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - fd := C.pathrs_proc_openat(C.int(procRootFd), cBase, cPath, C.int(flags)) - return uintptr(fd), fetchError(fd) -} - -// ProcReadlinkat wraps pathrs_proc_readlinkat. -func ProcReadlinkat(procRootFd int, base ProcBase, path string) (string, error) { - // TODO: See if we can unify this code with InRootReadlink. - - cBase := C.pathrs_proc_base_t(base) - - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) - - size := 128 - for { - linkBuf := make([]byte, size) - n := C.pathrs_proc_readlinkat( - C.int(procRootFd), cBase, cPath, - C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.ulong(len(linkBuf))) - switch { - case int(n) < C.__PATHRS_MAX_ERR_VALUE: - return "", fetchError(n) - case int(n) <= len(linkBuf): - return string(linkBuf[:int(n)]), nil - default: - // The contents were truncated. Unlike readlinkat, pathrs returns - // the size of the link when it checked. So use the returned size - // as a basis for the reallocated size (but in order to avoid a DoS - // where a magic-link is growing by a single byte each iteration, - // make sure we are a fair bit larger). - size += int(n) - } - } -} - -// ProcfsOpenHow is pathrs_procfs_open_how (struct). -type ProcfsOpenHow C.pathrs_procfs_open_how - -const ( - // ProcfsNewUnmasked is PATHRS_PROCFS_NEW_UNMASKED. - ProcfsNewUnmasked = C.PATHRS_PROCFS_NEW_UNMASKED -) - -// Flags returns a pointer to the internal flags field to allow other packages -// to modify structure fields that are internal due to Go's visibility model. -func (how *ProcfsOpenHow) Flags() *C.uint64_t { return &how.flags } - -// ProcfsOpen is pathrs_procfs_open (sizeof(*how) is passed automatically). -func ProcfsOpen(how *ProcfsOpenHow) (uintptr, error) { - fd := C.pathrs_procfs_open((*C.pathrs_procfs_open_how)(how), C.size_t(unsafe.Sizeof(*how))) - return uintptr(fd), fetchError(fd) -} diff --git a/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go b/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go deleted file mode 100644 index 5533c427cb74..000000000000 --- a/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go +++ /dev/null @@ -1,246 +0,0 @@ -//go:build linux - -// SPDX-License-Identifier: MPL-2.0 -/* - * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai - * Copyright (C) 2019-2025 SUSE LLC - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -// Package procfs provides a safe API for operating on /proc on Linux. -package procfs - -import ( - "os" - "runtime" - - "cyphar.com/go-pathrs/internal/fdutils" - "cyphar.com/go-pathrs/internal/libpathrs" -) - -// ProcBase is used with [ProcReadlink] and related functions to indicate what -// /proc subpath path operations should be done relative to. -type ProcBase struct { - inner libpathrs.ProcBase -} - -var ( - // ProcRoot indicates to use /proc. Note that this mode may be more - // expensive because we have to take steps to try to avoid leaking unmasked - // procfs handles, so you should use [ProcBaseSelf] if you can. - ProcRoot = ProcBase{inner: libpathrs.ProcRoot} - // ProcSelf indicates to use /proc/self. For most programs, this is the - // standard choice. - ProcSelf = ProcBase{inner: libpathrs.ProcSelf} - // ProcThreadSelf indicates to use /proc/thread-self. In multi-threaded - // programs where one thread has a different CLONE_FS, it is possible for - // /proc/self to point the wrong thread and so /proc/thread-self may be - // necessary. - ProcThreadSelf = ProcBase{inner: libpathrs.ProcThreadSelf} -) - -// ProcPid returns a ProcBase which indicates to use /proc/$pid for the given -// PID (or TID). Be aware that due to PID recycling, using this is generally -// not safe except in certain circumstances. Namely: -// -// - PID 1 (the init process), as that PID cannot ever get recycled. -// - Your current PID (though you should just use [ProcBaseSelf]). -// - Your current TID if you have used [runtime.LockOSThread] (though you -// should just use [ProcBaseThreadSelf]). -// - PIDs of child processes (as long as you are sure that no other part of -// your program incorrectly catches or ignores SIGCHLD, and that you do it -// *before* you call wait(2)or any equivalent method that could reap -// zombies). -func ProcPid(pid int) ProcBase { - if pid < 0 || pid >= 1<<31 { - panic("invalid ProcBasePid value") // TODO: should this be an error? - } - return ProcBase{inner: libpathrs.ProcPid(uint32(pid))} -} - -// ThreadCloser is a callback that needs to be called when you are done -// operating on an [os.File] fetched using [Handle.OpenThreadSelf]. -// -// [os.File]: https://pkg.go.dev/os#File -type ThreadCloser func() - -// Handle is a wrapper around an *os.File handle to "/proc", which can be -// used to do further procfs-related operations in a safe way. -type Handle struct { - inner *os.File -} - -// Close releases all internal resources for this [Handle]. -// -// Note that if the handle is actually the global cached handle, this operation -// is a no-op. -func (proc *Handle) Close() error { - var err error - if proc.inner != nil { - err = proc.inner.Close() - } - return err -} - -// OpenOption is a configuration function passed as an argument to [Open]. -type OpenOption func(*libpathrs.ProcfsOpenHow) error - -// UnmaskedProcRoot can be passed to [Open] to request an unmasked procfs -// handle be created. -// -// procfs, err := procfs.OpenRoot(procfs.UnmaskedProcRoot) -func UnmaskedProcRoot(how *libpathrs.ProcfsOpenHow) error { - *how.Flags() |= libpathrs.ProcfsNewUnmasked - return nil -} - -// Open creates a new [Handle] to a safe "/proc", based on the passed -// configuration options (in the form of a series of [OpenOption]s). -func Open(opts ...OpenOption) (*Handle, error) { - var how libpathrs.ProcfsOpenHow - for _, opt := range opts { - if err := opt(&how); err != nil { - return nil, err - } - } - fd, err := libpathrs.ProcfsOpen(&how) - if err != nil { - return nil, err - } - var procFile *os.File - if int(fd) >= 0 { - procFile = os.NewFile(fd, "/proc") - } - // TODO: Check that fd == PATHRS_PROC_DEFAULT_ROOTFD in the <0 case? - return &Handle{inner: procFile}, nil -} - -// TODO: Switch to something fdutils.WithFileFd-like. -func (proc *Handle) fd() int { - if proc.inner != nil { - return int(proc.inner.Fd()) - } - return libpathrs.ProcDefaultRootFd -} - -// TODO: Should we expose open? -func (proc *Handle) open(base ProcBase, path string, flags int) (_ *os.File, Closer ThreadCloser, Err error) { - var closer ThreadCloser - if base == ProcThreadSelf { - runtime.LockOSThread() - closer = runtime.UnlockOSThread - } - defer func() { - if closer != nil && Err != nil { - closer() - Closer = nil - } - }() - - fd, err := libpathrs.ProcOpenat(proc.fd(), base.inner, path, flags) - if err != nil { - return nil, nil, err - } - file, err := fdutils.MkFile(fd) - return file, closer, err -} - -// OpenRoot safely opens a given path from inside /proc/. -// -// This function must only be used for accessing global information from procfs -// (such as /proc/cpuinfo) or information about other processes (such as -// /proc/1). Accessing your own process information should be done using -// [Handle.OpenSelf] or [Handle.OpenThreadSelf]. -func (proc *Handle) OpenRoot(path string, flags int) (*os.File, error) { - file, closer, err := proc.open(ProcRoot, path, flags) - if closer != nil { - // should not happen - panic("non-zero closer returned from procOpen(ProcRoot)") - } - return file, err -} - -// OpenSelf safely opens a given path from inside /proc/self/. -// -// This method is recommend for getting process information about the current -// process for almost all Go processes *except* for cases where there are -// [runtime.LockOSThread] threads that have changed some aspect of their state -// (such as through unshare(CLONE_FS) or changing namespaces). -// -// For such non-heterogeneous processes, /proc/self may reference to a task -// that has different state from the current goroutine and so it may be -// preferable to use [Handle.OpenThreadSelf]. The same is true if a user -// really wants to inspect the current OS thread's information (such as -// /proc/thread-self/stack or /proc/thread-self/status which is always uniquely -// per-thread). -// -// Unlike [Handle.OpenThreadSelf], this method does not involve locking -// the goroutine to the current OS thread and so is simpler to use and -// theoretically has slightly less overhead. -// -// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread -func (proc *Handle) OpenSelf(path string, flags int) (*os.File, error) { - file, closer, err := proc.open(ProcSelf, path, flags) - if closer != nil { - // should not happen - panic("non-zero closer returned from procOpen(ProcSelf)") - } - return file, err -} - -// OpenPid safely opens a given path from inside /proc/$pid/, where pid can be -// either a PID or TID. -// -// This is effectively equivalent to calling [Handle.OpenRoot] with the -// pid prefixed to the subpath. -// -// Be aware that due to PID recycling, using this is generally not safe except -// in certain circumstances. See the documentation of [ProcPid] for more -// details. -func (proc *Handle) OpenPid(pid int, path string, flags int) (*os.File, error) { - file, closer, err := proc.open(ProcPid(pid), path, flags) - if closer != nil { - // should not happen - panic("non-zero closer returned from procOpen(ProcPidOpen)") - } - return file, err -} - -// OpenThreadSelf safely opens a given path from inside /proc/thread-self/. -// -// Most Go processes have heterogeneous threads (all threads have most of the -// same kernel state such as CLONE_FS) and so [Handle.OpenSelf] is -// preferable for most users. -// -// For non-heterogeneous threads, or users that actually want thread-specific -// information (such as /proc/thread-self/stack or /proc/thread-self/status), -// this method is necessary. -// -// Because Go can change the running OS thread of your goroutine without notice -// (and then subsequently kill the old thread), this method will lock the -// current goroutine to the OS thread (with [runtime.LockOSThread]) and the -// caller is responsible for unlocking the the OS thread with the -// [ThreadCloser] callback once they are done using the returned file. This -// callback MUST be called AFTER you have finished using the returned -// [os.File]. This callback is completely separate to [os.File.Close], so it -// must be called regardless of how you close the handle. -// -// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread -// [os.File]: https://pkg.go.dev/os#File -// [os.File.Close]: https://pkg.go.dev/os#File.Close -func (proc *Handle) OpenThreadSelf(path string, flags int) (*os.File, ThreadCloser, error) { - return proc.open(ProcThreadSelf, path, flags) -} - -// Readlink safely reads the contents of a symlink from the given procfs base. -// -// This is effectively equivalent to doing an Open*(O_PATH|O_NOFOLLOW) of the -// path and then doing unix.Readlinkat(fd, ""), but with the benefit that -// thread locking is not necessary for [ProcThreadSelf]. -func (proc *Handle) Readlink(base ProcBase, path string) (string, error) { - return libpathrs.ProcReadlinkat(proc.fd(), base.inner, path) -} diff --git a/vendor/cyphar.com/go-pathrs/root_linux.go b/vendor/cyphar.com/go-pathrs/root_linux.go deleted file mode 100644 index edc9e4c87f98..000000000000 --- a/vendor/cyphar.com/go-pathrs/root_linux.go +++ /dev/null @@ -1,367 +0,0 @@ -//go:build linux - -// SPDX-License-Identifier: MPL-2.0 -/* - * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai - * Copyright (C) 2019-2025 SUSE LLC - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package pathrs - -import ( - "errors" - "fmt" - "os" - "syscall" - - "cyphar.com/go-pathrs/internal/fdutils" - "cyphar.com/go-pathrs/internal/libpathrs" -) - -// Root is a handle to the root of a directory tree to resolve within. The only -// purpose of this "root handle" is to perform operations within the directory -// tree, or to get a [Handle] to inodes within the directory tree. -// -// At time of writing, it is considered a *VERY BAD IDEA* to open a [Root] -// inside a possibly-attacker-controlled directory tree. While we do have -// protections that should defend against it, it's far more dangerous than just -// opening a directory tree which is not inside a potentially-untrusted -// directory. -type Root struct { - inner *os.File -} - -// OpenRoot creates a new [Root] handle to the directory at the given path. -func OpenRoot(path string) (*Root, error) { - fd, err := libpathrs.OpenRoot(path) - if err != nil { - return nil, err - } - file, err := fdutils.MkFile(fd) - if err != nil { - return nil, err - } - return &Root{inner: file}, nil -} - -// RootFromFile creates a new [Root] handle from an [os.File] referencing a -// directory. The provided file will be duplicated, so the original file should -// still be closed by the caller. -// -// This is effectively the inverse operation of [Root.IntoFile]. -// -// [os.File]: https://pkg.go.dev/os#File -func RootFromFile(file *os.File) (*Root, error) { - newFile, err := fdutils.DupFile(file) - if err != nil { - return nil, fmt.Errorf("duplicate root fd: %w", err) - } - return &Root{inner: newFile}, nil -} - -// Resolve resolves the given path within the [Root]'s directory tree, and -// returns a [Handle] to the resolved path. The path must already exist, -// otherwise an error will occur. -// -// All symlinks (including trailing symlinks) are followed, but they are -// resolved within the rootfs. If you wish to open a handle to the symlink -// itself, use [ResolveNoFollow]. -func (r *Root) Resolve(path string) (*Handle, error) { - return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*Handle, error) { - handleFd, err := libpathrs.InRootResolve(rootFd, path) - if err != nil { - return nil, err - } - handleFile, err := fdutils.MkFile(handleFd) - if err != nil { - return nil, err - } - return &Handle{inner: handleFile}, nil - }) -} - -// ResolveNoFollow is effectively an O_NOFOLLOW version of [Resolve]. Their -// behaviour is identical, except that *trailing* symlinks will not be -// followed. If the final component is a trailing symlink, an O_PATH|O_NOFOLLOW -// handle to the symlink itself is returned. -func (r *Root) ResolveNoFollow(path string) (*Handle, error) { - return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*Handle, error) { - handleFd, err := libpathrs.InRootResolveNoFollow(rootFd, path) - if err != nil { - return nil, err - } - handleFile, err := fdutils.MkFile(handleFd) - if err != nil { - return nil, err - } - return &Handle{inner: handleFile}, nil - }) -} - -// Open is effectively shorthand for [Resolve] followed by [Handle.Open], but -// can be slightly more efficient (it reduces CGo overhead and the number of -// syscalls used when using the openat2-based resolver) and is arguably more -// ergonomic to use. -// -// This is effectively equivalent to [os.Open]. -// -// [os.Open]: https://pkg.go.dev/os#Open -func (r *Root) Open(path string) (*os.File, error) { - return r.OpenFile(path, os.O_RDONLY) -} - -// OpenFile is effectively shorthand for [Resolve] followed by -// [Handle.OpenFile], but can be slightly more efficient (it reduces CGo -// overhead and the number of syscalls used when using the openat2-based -// resolver) and is arguably more ergonomic to use. -// -// However, if flags contains os.O_NOFOLLOW and the path is a symlink, then -// OpenFile's behaviour will match that of openat2. In most cases an error will -// be returned, but if os.O_PATH is provided along with os.O_NOFOLLOW then a -// file equivalent to [ResolveNoFollow] will be returned instead. -// -// This is effectively equivalent to [os.OpenFile], except that os.O_CREAT is -// not supported. -// -// [os.OpenFile]: https://pkg.go.dev/os#OpenFile -func (r *Root) OpenFile(path string, flags int) (*os.File, error) { - return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*os.File, error) { - fd, err := libpathrs.InRootOpen(rootFd, path, flags) - if err != nil { - return nil, err - } - return fdutils.MkFile(fd) - }) -} - -// Create creates a file within the [Root]'s directory tree at the given path, -// and returns a handle to the file. The provided mode is used for the new file -// (the process's umask applies). -// -// Unlike [os.Create], if the file already exists an error is created rather -// than the file being opened and truncated. -// -// [os.Create]: https://pkg.go.dev/os#Create -func (r *Root) Create(path string, flags int, mode os.FileMode) (*os.File, error) { - unixMode, err := toUnixMode(mode, false) - if err != nil { - return nil, err - } - return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*os.File, error) { - handleFd, err := libpathrs.InRootCreat(rootFd, path, flags, unixMode) - if err != nil { - return nil, err - } - return fdutils.MkFile(handleFd) - }) -} - -// Rename two paths within a [Root]'s directory tree. The flags argument is -// identical to the RENAME_* flags to the renameat2(2) system call. -func (r *Root) Rename(src, dst string, flags uint) error { - _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { - err := libpathrs.InRootRename(rootFd, src, dst, flags) - return struct{}{}, err - }) - return err -} - -// RemoveDir removes the named empty directory within a [Root]'s directory -// tree. -func (r *Root) RemoveDir(path string) error { - _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { - err := libpathrs.InRootRmdir(rootFd, path) - return struct{}{}, err - }) - return err -} - -// RemoveFile removes the named file within a [Root]'s directory tree. -func (r *Root) RemoveFile(path string) error { - _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { - err := libpathrs.InRootUnlink(rootFd, path) - return struct{}{}, err - }) - return err -} - -// Remove removes the named file or (empty) directory within a [Root]'s -// directory tree. -// -// This is effectively equivalent to [os.Remove]. -// -// [os.Remove]: https://pkg.go.dev/os#Remove -func (r *Root) Remove(path string) error { - // In order to match os.Remove's implementation we need to also do both - // syscalls unconditionally and adjust the error based on whether - // pathrs_inroot_rmdir() returned ENOTDIR. - unlinkErr := r.RemoveFile(path) - if unlinkErr == nil { - return nil - } - rmdirErr := r.RemoveDir(path) - if rmdirErr == nil { - return nil - } - // Both failed, adjust the error in the same way that os.Remove does. - err := rmdirErr - if errors.Is(err, syscall.ENOTDIR) { - err = unlinkErr - } - return err -} - -// RemoveAll recursively deletes a path and all of its children. -// -// This is effectively equivalent to [os.RemoveAll]. -// -// [os.RemoveAll]: https://pkg.go.dev/os#RemoveAll -func (r *Root) RemoveAll(path string) error { - _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { - err := libpathrs.InRootRemoveAll(rootFd, path) - return struct{}{}, err - }) - return err -} - -// Mkdir creates a directory within a [Root]'s directory tree. The provided -// mode is used for the new directory (the process's umask applies). -// -// This is effectively equivalent to [os.Mkdir]. -// -// [os.Mkdir]: https://pkg.go.dev/os#Mkdir -func (r *Root) Mkdir(path string, mode os.FileMode) error { - unixMode, err := toUnixMode(mode, false) - if err != nil { - return err - } - - _, err = fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { - err := libpathrs.InRootMkdir(rootFd, path, unixMode) - return struct{}{}, err - }) - return err -} - -// MkdirAll creates a directory (and any parent path components if they don't -// exist) within a [Root]'s directory tree. The provided mode is used for any -// directories created by this function (the process's umask applies). -// -// This is effectively equivalent to [os.MkdirAll]. -// -// [os.MkdirAll]: https://pkg.go.dev/os#MkdirAll -func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) { - unixMode, err := toUnixMode(mode, false) - if err != nil { - return nil, err - } - - return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*Handle, error) { - handleFd, err := libpathrs.InRootMkdirAll(rootFd, path, unixMode) - if err != nil { - return nil, err - } - handleFile, err := fdutils.MkFile(handleFd) - if err != nil { - return nil, err - } - return &Handle{inner: handleFile}, err - }) -} - -// Mknod creates a new device inode of the given type within a [Root]'s -// directory tree. The provided mode is used for the new directory (the -// process's umask applies). -// -// This is effectively equivalent to [unix.Mknod]. -// -// [unix.Mknod]: https://pkg.go.dev/golang.org/x/sys/unix#Mknod -func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error { - unixMode, err := toUnixMode(mode, true) - if err != nil { - return err - } - - _, err = fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { - err := libpathrs.InRootMknod(rootFd, path, unixMode, dev) - return struct{}{}, err - }) - return err -} - -// Symlink creates a symlink within a [Root]'s directory tree. The symlink is -// created at path and is a link to target. -// -// This is effectively equivalent to [os.Symlink]. -// -// [os.Symlink]: https://pkg.go.dev/os#Symlink -func (r *Root) Symlink(path, target string) error { - _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { - err := libpathrs.InRootSymlink(rootFd, path, target) - return struct{}{}, err - }) - return err -} - -// Hardlink creates a hardlink within a [Root]'s directory tree. The hardlink -// is created at path and is a link to target. Both paths are within the -// [Root]'s directory tree (you cannot hardlink to a different [Root] or the -// host). -// -// This is effectively equivalent to [os.Link]. -// -// [os.Link]: https://pkg.go.dev/os#Link -func (r *Root) Hardlink(path, target string) error { - _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { - err := libpathrs.InRootHardlink(rootFd, path, target) - return struct{}{}, err - }) - return err -} - -// Readlink returns the target of a symlink with a [Root]'s directory tree. -// -// This is effectively equivalent to [os.Readlink]. -// -// [os.Readlink]: https://pkg.go.dev/os#Readlink -func (r *Root) Readlink(path string) (string, error) { - return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (string, error) { - return libpathrs.InRootReadlink(rootFd, path) - }) -} - -// IntoFile unwraps the [Root] into its underlying [os.File]. -// -// It is critical that you do not operate on this file descriptor yourself, -// because the security properties of libpathrs depend on users doing all -// relevant filesystem operations through libpathrs. -// -// This operation returns the internal [os.File] of the [Root] directly, so -// calling [Root.Close] will also close any copies of the returned [os.File]. -// If you want to get an independent copy, use [Root.Clone] followed by -// [Root.IntoFile] on the cloned [Root]. -// -// [os.File]: https://pkg.go.dev/os#File -func (r *Root) IntoFile() *os.File { - // TODO: Figure out if we really don't want to make a copy. - // TODO: We almost certainly want to clear r.inner here, but we can't do - // that easily atomically (we could use atomic.Value but that'll make - // things quite a bit uglier). - return r.inner -} - -// Clone creates a copy of a [Root] handle, such that it has a separate -// lifetime to the original (while referring to the same underlying directory). -func (r *Root) Clone() (*Root, error) { - return RootFromFile(r.inner) -} - -// Close frees all of the resources used by the [Root] handle. -func (r *Root) Close() error { - return r.inner.Close() -} diff --git a/vendor/cyphar.com/go-pathrs/utils_linux.go b/vendor/cyphar.com/go-pathrs/utils_linux.go deleted file mode 100644 index 2208d608f8df..000000000000 --- a/vendor/cyphar.com/go-pathrs/utils_linux.go +++ /dev/null @@ -1,56 +0,0 @@ -//go:build linux - -// SPDX-License-Identifier: MPL-2.0 -/* - * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai - * Copyright (C) 2019-2025 SUSE LLC - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package pathrs - -import ( - "fmt" - "os" - - "golang.org/x/sys/unix" -) - -//nolint:cyclop // this function needs to handle a lot of cases -func toUnixMode(mode os.FileMode, needsType bool) (uint32, error) { - sysMode := uint32(mode.Perm()) - switch mode & os.ModeType { //nolint:exhaustive // we only care about ModeType bits - case 0: - if needsType { - sysMode |= unix.S_IFREG - } - case os.ModeDir: - sysMode |= unix.S_IFDIR - case os.ModeSymlink: - sysMode |= unix.S_IFLNK - case os.ModeCharDevice | os.ModeDevice: - sysMode |= unix.S_IFCHR - case os.ModeDevice: - sysMode |= unix.S_IFBLK - case os.ModeNamedPipe: - sysMode |= unix.S_IFIFO - case os.ModeSocket: - sysMode |= unix.S_IFSOCK - default: - return 0, fmt.Errorf("invalid mode filetype %+o", mode) - } - if mode&os.ModeSetuid != 0 { - sysMode |= unix.S_ISUID - } - if mode&os.ModeSetgid != 0 { - sysMode |= unix.S_ISGID - } - if mode&os.ModeSticky != 0 { - sysMode |= unix.S_ISVTX - } - return sysMode, nil -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/.golangci.yml b/vendor/github.com/cyphar/filepath-securejoin/.golangci.yml deleted file mode 100644 index 3e8dd99bd7f8..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/.golangci.yml +++ /dev/null @@ -1,60 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 - -# Copyright (C) 2025 Aleksa Sarai -# Copyright (C) 2025 SUSE LLC -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -version: "2" - -run: - build-tags: - - libpathrs - -linters: - enable: - - asasalint - - asciicheck - - containedctx - - contextcheck - - errcheck - - errorlint - - exhaustive - - forcetypeassert - - godot - - goprintffuncname - - govet - - importas - - ineffassign - - makezero - - misspell - - musttag - - nilerr - - nilnesserr - - nilnil - - noctx - - prealloc - - revive - - staticcheck - - testifylint - - unconvert - - unparam - - unused - - usetesting - settings: - govet: - enable: - - nilness - testifylint: - enable-all: true - -formatters: - enable: - - gofumpt - - goimports - settings: - goimports: - local-prefixes: - - github.com/cyphar/filepath-securejoin diff --git a/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md b/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md index 6d016d05c00e..ca0e3c62c76e 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md +++ b/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md @@ -6,198 +6,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ## -## [0.6.1] - 2025-11-19 ## - -> At last up jumped the cunning spider, and fiercely held her fast. - -### Fixed ### -- Our logic for deciding whether to use `openat2(2)` or fallback to an `O_PATH` - resolver would cache the result to avoid doing needless test runs of - `openat2(2)`. However, this causes issues when `pathrs-lite` is being used by - a program that applies new seccomp-bpf filters onto itself -- if the filter - denies `openat2(2)` then we would return that error rather than falling back - to the `O_PATH` resolver. To resolve this issue, we no longer cache the - result if `openat2(2)` was successful, only if there was an error. -- A file descriptor leak in our `openat2` wrapper (when doing the necessary - `dup` for `RESOLVE_IN_ROOT`) has been removed. - -## [0.5.2] - 2025-11-19 ## - -> "Will you walk into my parlour?" said a spider to a fly. - -### Fixed ### -- Our logic for deciding whether to use `openat2(2)` or fallback to an `O_PATH` - resolver would cache the result to avoid doing needless test runs of - `openat2(2)`. However, this causes issues when `pathrs-lite` is being used by - a program that applies new seccomp-bpf filters onto itself -- if the filter - denies `openat2(2)` then we would return that error rather than falling back - to the `O_PATH` resolver. To resolve this issue, we no longer cache the - result if `openat2(2)` was successful, only if there was an error. -- A file descriptor leak in our `openat2` wrapper (when doing the necessary - `dup` for `RESOLVE_IN_ROOT`) has been removed. - -## [0.6.0] - 2025-11-03 ## - -> By the Power of Greyskull! - -### Breaking ### -- The deprecated `MkdirAll`, `MkdirAllHandle`, `OpenInRoot`, `OpenatInRoot` and - `Reopen` wrappers have been removed. Please switch to using `pathrs-lite` - directly. - -### Added ### -- `pathrs-lite` now has support for using libpathrs as a backend. This is - opt-in and can be enabled at build time with the `libpathrs` build tag. The - intention is to allow for downstream libraries and other projects to make use - of the pure-Go `github.com/cyphar/filepath-securejoin/pathrs-lite` package - and distributors can then opt-in to using `libpathrs` for the entire binary - if they wish. - -## [0.5.1] - 2025-10-31 ## - -> Spooky scary skeletons send shivers down your spine! - -### Changed ### -- `openat2` can return `-EAGAIN` if it detects a possible attack in certain - scenarios (namely if there was a rename or mount while walking a path with a - `..` component). While this is necessary to avoid a denial-of-service in the - kernel, it does require retry loops in userspace. - - In previous versions, `pathrs-lite` would retry `openat2` 32 times before - returning an error, but we've received user reports that this limit can be - hit on systems with very heavy load. In some synthetic benchmarks (testing - the worst-case of an attacker doing renames in a tight loop on every core of - a 16-core machine) we managed to get a ~3% failure rate in runc. We have - improved this situation in two ways: - - * We have now increased this limit to 128, which should be good enough for - most use-cases without becoming a denial-of-service vector (the number of - syscalls called by the `O_PATH` resolver in a typical case is within the - same ballpark). The same benchmarks show a failure rate of ~0.12% which - (while not zero) is probably sufficient for most users. - - * In addition, we now return a `unix.EAGAIN` error that is bubbled up and can - be detected by callers. This means that callers with stricter requirements - to avoid spurious errors can choose to do their own infinite `EAGAIN` retry - loop (though we would strongly recommend users use time-based deadlines in - such retry loops to avoid potentially unbounded denials-of-service). - -## [0.5.0] - 2025-09-26 ## - -> Let the past die. Kill it if you have to. - -> **NOTE**: With this release, some parts of -> `github.com/cyphar/filepath-securejoin` are now licensed under the Mozilla -> Public License (version 2). Please see [COPYING.md][] as well as the the -> license header in each file for more details. - -[COPYING.md]: ./COPYING.md - -### Breaking ### -- The new API introduced in the [0.3.0][] release has been moved to a new - subpackage called `pathrs-lite`. This was primarily done to better indicate - the split between the new and old APIs, as well as indicate to users the - purpose of this subpackage (it is a less complete version of [libpathrs][]). - - We have added some wrappers to the top-level package to ease the transition, - but those are deprecated and will be removed in the next minor release of - filepath-securejoin. Users should update their import paths. - - This new subpackage has also been relicensed under the Mozilla Public License - (version 2), please see [COPYING.md][] for more details. - -### Added ### -- Most of the key bits the safe `procfs` API have now been exported and are - available in `github.com/cyphar/filepath-securejoin/pathrs-lite/procfs`. At - the moment this primarily consists of a new `procfs.Handle` API: - - * `OpenProcRoot` returns a new handle to `/proc`, endeavouring to make it - safe if possible (`subset=pid` to protect against mistaken write attacks - and leaks, as well as using `fsopen(2)` to avoid racing mount attacks). - - `OpenUnsafeProcRoot` returns a handle without attempting to create one - with `subset=pid`, which makes it more dangerous to leak. Most users - should use `OpenProcRoot` (even if you need to use `ProcRoot` as the base - of an operation, as filepath-securejoin will internally open a handle when - necessary). - - * The `(*procfs.Handle).Open*` family of methods lets you get a safe - `O_PATH` handle to subpaths within `/proc` for certain subpaths. - - For `OpenThreadSelf`, the returned `ProcThreadSelfCloser` needs to be - called after you completely finish using the handle (this is necessary - because Go is multi-threaded and `ProcThreadSelf` references - `/proc/thread-self` which may disappear if we do not - `runtime.LockOSThread` -- `ProcThreadSelfCloser` is currently equivalent - to `runtime.UnlockOSThread`). - - Note that you cannot open any `procfs` symlinks (most notably magic-links) - using this API. At the moment, filepath-securejoin does not support this - feature (but [libpathrs][] does). - - * `ProcSelfFdReadlink` lets you get the in-kernel path representation of a - file descriptor (think `readlink("/proc/self/fd/...")`), except that we - verify that there aren't any tricky overmounts that could fool the - process. - - Please be aware that the returned string is simply a snapshot at that - particular moment, and an attacker could move the file being pointed to. - In addition, complex namespace configurations could result in non-sensical - or confusing paths to be returned. The value received from this function - should only be used as secondary verification of some security property, - not as proof that a particular handle has a particular path. - - The procfs handle used internally by the API is the same as the rest of - `filepath-securejoin` (for privileged programs this is usually a private - in-process `procfs` instance created with `fsopen(2)`). - - As before, this is intended as a stop-gap before users migrate to - [libpathrs][], which provides a far more extensive safe `procfs` API and is - generally more robust. - -- Previously, the hardened procfs implementation (used internally within - `Reopen` and `Open(at)InRoot`) only protected against overmount attacks on - systems with `openat2(2)` (Linux 5.6) or systems with `fsopen(2)` or - `open_tree(2)` (Linux 5.2) and programs with privileges to use them (with - some caveats about locked mounts that probably affect very few users). For - other users, an attacker with the ability to create malicious mounts (on most - systems, a sysadmin) could trick you into operating on files you didn't - expect. This attack only really makes sense in the context of container - runtime implementations. - - This was considered a reasonable trade-off, as the long-term intention was to - get all users to just switch to [libpathrs][] if they wanted to use the safe - `procfs` API (which had more extensive protections, and is what these new - protections in `filepath-securejoin` are based on). However, as the API - is now being exported it seems unwise to advertise the API as "safe" if we do - not protect against known attacks. - - The procfs API is now more protected against attackers on systems lacking the - aforementioned protections. However, the most comprehensive of these - protections effectively rely on [`statx(STATX_MNT_ID)`][statx.2] (Linux 5.8). - On older kernel versions, there is no effective protection (there is some - minimal protection against non-`procfs` filesystem components but a - sufficiently clever attacker can work around those). In addition, - `STATX_MNT_ID` is vulnerable to mount ID reuse attacks by sufficiently - motivated and privileged attackers -- this problem is mitigated with - `STATX_MNT_ID_UNIQUE` (Linux 6.8) but that raises the minimum kernel version - for more protection. - - The fact that these protections are quite limited despite needing a fair bit - of extra code to handle was one of the primary reasons we did not initially - implement this in `filepath-securejoin` ([libpathrs][] supports all of this, - of course). - -### Fixed ### -- RHEL 8 kernels have backports of `fsopen(2)` but in some testing we've found - that it has very bad (and very difficult to debug) performance issues, and so - we will explicitly refuse to use `fsopen(2)` if the running kernel version is - pre-5.2 and will instead fallback to `open("/proc")`. - -[CVE-2024-21626]: https://github.com/opencontainers/runc/security/advisories/GHSA-xr7r-f8xq-vfvv -[libpathrs]: https://github.com/cyphar/libpathrs -[statx.2]: https://www.man7.org/linux/man-pages/man2/statx.2.html - ## [0.4.1] - 2025-01-28 ## ### Fixed ### @@ -365,7 +173,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). safe to start migrating to as we have extensive tests ensuring they behave correctly and are safe against various races and other attacks. -[libpathrs]: https://github.com/cyphar/libpathrs +[libpathrs]: https://github.com/openSUSE/libpathrs [open.2]: https://www.man7.org/linux/man-pages/man2/open.2.html ## [0.2.5] - 2024-05-03 ## @@ -430,12 +238,7 @@ This is our first release of `github.com/cyphar/filepath-securejoin`, containing a full implementation with a coverage of 93.5% (the only missing cases are the error cases, which are hard to mocktest at the moment). -[Unreleased]: https://github.com/cyphar/filepath-securejoin/compare/v0.6.1...HEAD -[0.6.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.6.0...v0.6.1 -[0.6.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.5.0...v0.6.0 -[0.5.2]: https://github.com/cyphar/filepath-securejoin/compare/v0.5.1...v0.5.2 -[0.5.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.5.0...v0.5.1 -[0.5.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.4.1...v0.5.0 +[Unreleased]: https://github.com/cyphar/filepath-securejoin/compare/v0.4.1...HEAD [0.4.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.4.0...v0.4.1 [0.4.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.6...v0.4.0 [0.3.6]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.5...v0.3.6 diff --git a/vendor/github.com/cyphar/filepath-securejoin/COPYING.md b/vendor/github.com/cyphar/filepath-securejoin/COPYING.md deleted file mode 100644 index 520e822b1849..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/COPYING.md +++ /dev/null @@ -1,447 +0,0 @@ -## COPYING ## - -`SPDX-License-Identifier: BSD-3-Clause AND MPL-2.0` - -This project is made up of code licensed under different licenses. Which code -you use will have an impact on whether only one or both licenses apply to your -usage of this library. - -Note that **each file** in this project individually has a code comment at the -start describing the license of that particular file -- this is the most -accurate license information of this project; in case there is any conflict -between this document and the comment at the start of a file, the comment shall -take precedence. The only purpose of this document is to work around [a known -technical limitation of pkg.go.dev's license checking tool when dealing with -non-trivial project licenses][go75067]. - -[go75067]: https://go.dev/issue/75067 - -### `BSD-3-Clause` ### - -At time of writing, the following files and directories are licensed under the -BSD-3-Clause license: - - * `doc.go` - * `join*.go` - * `vfs.go` - * `internal/consts/*.go` - * `pathrs-lite/internal/gocompat/*.go` - * `pathrs-lite/internal/kernelversion/*.go` - -The text of the BSD-3-Clause license used by this project is the following (the -text is also available from the [`LICENSE.BSD`](./LICENSE.BSD) file): - -``` -Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. -Copyright (C) 2017-2024 SUSE LLC. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -``` - -### `MPL-2.0` ### - -All other files (unless otherwise marked) are licensed under the Mozilla Public -License (version 2.0). - -The text of the Mozilla Public License (version 2.0) is the following (the text -is also available from the [`LICENSE.MPL-2.0`](./LICENSE.MPL-2.0) file): - -``` -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at https://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. -``` diff --git a/vendor/github.com/cyphar/filepath-securejoin/LICENSE.BSD b/vendor/github.com/cyphar/filepath-securejoin/LICENSE similarity index 100% rename from vendor/github.com/cyphar/filepath-securejoin/LICENSE.BSD rename to vendor/github.com/cyphar/filepath-securejoin/LICENSE diff --git a/vendor/github.com/cyphar/filepath-securejoin/LICENSE.MPL-2.0 b/vendor/github.com/cyphar/filepath-securejoin/LICENSE.MPL-2.0 deleted file mode 100644 index d0a1fa1482ee..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/LICENSE.MPL-2.0 +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at https://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/cyphar/filepath-securejoin/README.md b/vendor/github.com/cyphar/filepath-securejoin/README.md index 6673abfc842a..eaeb53fcd0ab 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/README.md +++ b/vendor/github.com/cyphar/filepath-securejoin/README.md @@ -67,8 +67,7 @@ func SecureJoin(root, unsafePath string) (string, error) { [libpathrs]: https://github.com/openSUSE/libpathrs [go#20126]: https://github.com/golang/go/issues/20126 -### New API ### -[#new-api]: #new-api +### New API ### While we recommend users switch to [libpathrs][libpathrs] as soon as it has a stable release, some methods implemented by libpathrs have been ported to this @@ -166,19 +165,5 @@ after `MkdirAll`). ### License ### -`SPDX-License-Identifier: BSD-3-Clause AND MPL-2.0` - -Some of the code in this project is derived from Go, and is licensed under a -BSD 3-clause license (available in `LICENSE.BSD`). Other files (many of which -are derived from [libpathrs][libpathrs]) are licensed under the Mozilla Public -License version 2.0 (available in `LICENSE.MPL-2.0`). If you are using the -["New API" described above][#new-api], you are probably using code from files -released under this license. - -Every source file in this project has a copyright header describing its -license. Please check the license headers of each file to see what license -applies to it. - -See [COPYING.md](./COPYING.md) for some more details. - -[umoci]: https://github.com/opencontainers/umoci +The license of this project is the same as Go, which is a BSD 3-clause license +available in the `LICENSE` file. diff --git a/vendor/github.com/cyphar/filepath-securejoin/VERSION b/vendor/github.com/cyphar/filepath-securejoin/VERSION index ee6cdce3c290..267577d47e49 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/VERSION +++ b/vendor/github.com/cyphar/filepath-securejoin/VERSION @@ -1 +1 @@ -0.6.1 +0.4.1 diff --git a/vendor/github.com/cyphar/filepath-securejoin/codecov.yml b/vendor/github.com/cyphar/filepath-securejoin/codecov.yml deleted file mode 100644 index ff284dbfaf95..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/codecov.yml +++ /dev/null @@ -1,29 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 - -# Copyright (C) 2025 Aleksa Sarai -# Copyright (C) 2025 SUSE LLC -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -comment: - layout: "condensed_header, reach, diff, components, condensed_files, condensed_footer" - require_changes: true - branches: - - main - -coverage: - range: 60..100 - status: - project: - default: - target: 85% - threshold: 0% - patch: - default: - target: auto - informational: true - -github_checks: - annotations: false diff --git a/vendor/github.com/cyphar/filepath-securejoin/doc.go b/vendor/github.com/cyphar/filepath-securejoin/doc.go index 1438fc9c09c9..1ec7d065ef41 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/doc.go +++ b/vendor/github.com/cyphar/filepath-securejoin/doc.go @@ -1,5 +1,3 @@ -// SPDX-License-Identifier: BSD-3-Clause - // Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. // Copyright (C) 2017-2024 SUSE LLC. All rights reserved. // Use of this source code is governed by a BSD-style @@ -16,13 +14,14 @@ // **not** safe against race conditions where an attacker changes the // filesystem after (or during) the [SecureJoin] operation. // -// The new API is available in the [pathrs-lite] subpackage, and provide -// protections against racing attackers as well as several other key -// protections against attacks often seen by container runtimes. As the name -// suggests, [pathrs-lite] is a stripped down (pure Go) reimplementation of -// [libpathrs]. The main APIs provided are [OpenInRoot], [MkdirAll], and -// [procfs.Handle] -- other APIs are not planned to be ported. The long-term -// goal is for users to migrate to [libpathrs] which is more fully-featured. +// The new API is made up of [OpenInRoot] and [MkdirAll] (and derived +// functions). These are safe against racing attackers and have several other +// protections that are not provided by the legacy API. There are many more +// operations that most programs expect to be able to do safely, but we do not +// provide explicit support for them because we want to encourage users to +// switch to [libpathrs](https://github.com/openSUSE/libpathrs) which is a +// cross-language next-generation library that is entirely designed around +// operating on paths safely. // // securejoin has been used by several container runtimes (Docker, runc, // Kubernetes, etc) for quite a few years as a de-facto standard for operating @@ -32,16 +31,9 @@ // API as soon as possible (or even better, switch to libpathrs). // // This project was initially intended to be included in the Go standard -// library, but it was rejected (see https://go.dev/issue/20126). Much later, -// [os.Root] was added to the Go stdlib that shares some of the goals of -// filepath-securejoin. However, its design is intended to work like -// openat2(RESOLVE_BENEATH) which does not fit the usecase of container -// runtimes and most system tools. -// -// [pathrs-lite]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin/pathrs-lite -// [libpathrs]: https://github.com/openSUSE/libpathrs -// [OpenInRoot]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin/pathrs-lite#OpenInRoot -// [MkdirAll]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin/pathrs-lite#MkdirAll -// [procfs.Handle]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs#Handle -// [os.Root]: https:///pkg.go.dev/os#Root +// library, but [it was rejected](https://go.dev/issue/20126). There is now a +// [new Go proposal](https://go.dev/issue/67002) for a safe path resolution API +// that shares some of the goals of filepath-securejoin. However, that design +// is intended to work like `openat2(RESOLVE_BENEATH)` which does not fit the +// usecase of container runtimes and most system tools. package securejoin diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_errors_go120.go b/vendor/github.com/cyphar/filepath-securejoin/gocompat_errors_go120.go similarity index 69% rename from vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_errors_go120.go rename to vendor/github.com/cyphar/filepath-securejoin/gocompat_errors_go120.go index 4a114bd3da97..42452bbf9b0b 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_errors_go120.go +++ b/vendor/github.com/cyphar/filepath-securejoin/gocompat_errors_go120.go @@ -1,19 +1,18 @@ -// SPDX-License-Identifier: BSD-3-Clause //go:build linux && go1.20 // Copyright (C) 2024 SUSE LLC. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package gocompat +package securejoin import ( "fmt" ) -// WrapBaseError is a helper that is equivalent to fmt.Errorf("%w: %w"), except +// wrapBaseError is a helper that is equivalent to fmt.Errorf("%w: %w"), except // that on pre-1.20 Go versions only errors.Is() works properly (errors.Unwrap) // is only guaranteed to give you baseErr. -func WrapBaseError(baseErr, extraErr error) error { +func wrapBaseError(baseErr, extraErr error) error { return fmt.Errorf("%w: %w", extraErr, baseErr) } diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_errors_unsupported.go b/vendor/github.com/cyphar/filepath-securejoin/gocompat_errors_unsupported.go similarity index 80% rename from vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_errors_unsupported.go rename to vendor/github.com/cyphar/filepath-securejoin/gocompat_errors_unsupported.go index 3061016a6a69..e7adca3fd121 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_errors_unsupported.go +++ b/vendor/github.com/cyphar/filepath-securejoin/gocompat_errors_unsupported.go @@ -1,12 +1,10 @@ -// SPDX-License-Identifier: BSD-3-Clause - //go:build linux && !go1.20 // Copyright (C) 2024 SUSE LLC. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package gocompat +package securejoin import ( "fmt" @@ -29,10 +27,10 @@ func (err wrappedError) Error() string { return fmt.Sprintf("%v: %v", err.isError, err.inner) } -// WrapBaseError is a helper that is equivalent to fmt.Errorf("%w: %w"), except +// wrapBaseError is a helper that is equivalent to fmt.Errorf("%w: %w"), except // that on pre-1.20 Go versions only errors.Is() works properly (errors.Unwrap) // is only guaranteed to give you baseErr. -func WrapBaseError(baseErr, extraErr error) error { +func wrapBaseError(baseErr, extraErr error) error { return wrappedError{ inner: baseErr, isError: extraErr, diff --git a/vendor/github.com/cyphar/filepath-securejoin/gocompat_generics_go121.go b/vendor/github.com/cyphar/filepath-securejoin/gocompat_generics_go121.go new file mode 100644 index 000000000000..ddd6fa9a41c5 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/gocompat_generics_go121.go @@ -0,0 +1,32 @@ +//go:build linux && go1.21 + +// Copyright (C) 2024 SUSE LLC. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package securejoin + +import ( + "slices" + "sync" +) + +func slices_DeleteFunc[S ~[]E, E any](slice S, delFn func(E) bool) S { + return slices.DeleteFunc(slice, delFn) +} + +func slices_Contains[S ~[]E, E comparable](slice S, val E) bool { + return slices.Contains(slice, val) +} + +func slices_Clone[S ~[]E, E any](slice S) S { + return slices.Clone(slice) +} + +func sync_OnceValue[T any](f func() T) func() T { + return sync.OnceValue(f) +} + +func sync_OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) { + return sync.OnceValues(f) +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/gocompat_generics_unsupported.go b/vendor/github.com/cyphar/filepath-securejoin/gocompat_generics_unsupported.go new file mode 100644 index 000000000000..f1e6fe7e717b --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/gocompat_generics_unsupported.go @@ -0,0 +1,124 @@ +//go:build linux && !go1.21 + +// Copyright (C) 2024 SUSE LLC. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package securejoin + +import ( + "sync" +) + +// These are very minimal implementations of functions that appear in Go 1.21's +// stdlib, included so that we can build on older Go versions. Most are +// borrowed directly from the stdlib, and a few are modified to be "obviously +// correct" without needing to copy too many other helpers. + +// clearSlice is equivalent to the builtin clear from Go 1.21. +// Copied from the Go 1.24 stdlib implementation. +func clearSlice[S ~[]E, E any](slice S) { + var zero E + for i := range slice { + slice[i] = zero + } +} + +// Copied from the Go 1.24 stdlib implementation. +func slices_IndexFunc[S ~[]E, E any](s S, f func(E) bool) int { + for i := range s { + if f(s[i]) { + return i + } + } + return -1 +} + +// Copied from the Go 1.24 stdlib implementation. +func slices_DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S { + i := slices_IndexFunc(s, del) + if i == -1 { + return s + } + // Don't start copying elements until we find one to delete. + for j := i + 1; j < len(s); j++ { + if v := s[j]; !del(v) { + s[i] = v + i++ + } + } + clearSlice(s[i:]) // zero/nil out the obsolete elements, for GC + return s[:i] +} + +// Similar to the stdlib slices.Contains, except that we don't have +// slices.Index so we need to use slices.IndexFunc for this non-Func helper. +func slices_Contains[S ~[]E, E comparable](s S, v E) bool { + return slices_IndexFunc(s, func(e E) bool { return e == v }) >= 0 +} + +// Copied from the Go 1.24 stdlib implementation. +func slices_Clone[S ~[]E, E any](s S) S { + // Preserve nil in case it matters. + if s == nil { + return nil + } + return append(S([]E{}), s...) +} + +// Copied from the Go 1.24 stdlib implementation. +func sync_OnceValue[T any](f func() T) func() T { + var ( + once sync.Once + valid bool + p any + result T + ) + g := func() { + defer func() { + p = recover() + if !valid { + panic(p) + } + }() + result = f() + f = nil + valid = true + } + return func() T { + once.Do(g) + if !valid { + panic(p) + } + return result + } +} + +// Copied from the Go 1.24 stdlib implementation. +func sync_OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) { + var ( + once sync.Once + valid bool + p any + r1 T1 + r2 T2 + ) + g := func() { + defer func() { + p = recover() + if !valid { + panic(p) + } + }() + r1, r2 = f() + f = nil + valid = true + } + return func() (T1, T2) { + once.Do(g) + if !valid { + panic(p) + } + return r1, r2 + } +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/internal/consts/consts.go b/vendor/github.com/cyphar/filepath-securejoin/internal/consts/consts.go deleted file mode 100644 index c69c4da91eea..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/internal/consts/consts.go +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause - -// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. -// Copyright (C) 2017-2025 SUSE LLC. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package consts contains the definitions of internal constants used -// throughout filepath-securejoin. -package consts - -// MaxSymlinkLimit is the maximum number of symlinks that can be encountered -// during a single lookup before returning -ELOOP. At time of writing, Linux -// has an internal limit of 40. -const MaxSymlinkLimit = 255 diff --git a/vendor/github.com/cyphar/filepath-securejoin/join.go b/vendor/github.com/cyphar/filepath-securejoin/join.go index 199c1d839247..e6634d4778f8 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/join.go +++ b/vendor/github.com/cyphar/filepath-securejoin/join.go @@ -1,5 +1,3 @@ -// SPDX-License-Identifier: BSD-3-Clause - // Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. // Copyright (C) 2017-2025 SUSE LLC. All rights reserved. // Use of this source code is governed by a BSD-style @@ -13,10 +11,10 @@ import ( "path/filepath" "strings" "syscall" - - "github.com/cyphar/filepath-securejoin/internal/consts" ) +const maxSymlinkLimit = 255 + // IsNotExist tells you if err is an error that implies that either the path // accessed does not exist (or path components don't exist). This is // effectively a more broad version of [os.IsNotExist]. @@ -51,13 +49,12 @@ func hasDotDot(path string) bool { return strings.Contains("/"+path+"/", "/../") } -// SecureJoinVFS joins the two given path components (similar to -// [filepath.Join]) except that the returned path is guaranteed to be scoped -// inside the provided root path (when evaluated). Any symbolic links in the -// path are evaluated with the given root treated as the root of the -// filesystem, similar to a chroot. The filesystem state is evaluated through -// the given [VFS] interface (if nil, the standard [os].* family of functions -// are used). +// SecureJoinVFS joins the two given path components (similar to [filepath.Join]) except +// that the returned path is guaranteed to be scoped inside the provided root +// path (when evaluated). Any symbolic links in the path are evaluated with the +// given root treated as the root of the filesystem, similar to a chroot. The +// filesystem state is evaluated through the given [VFS] interface (if nil, the +// standard [os].* family of functions are used). // // Note that the guarantees provided by this function only apply if the path // components in the returned string are not modified (in other words are not @@ -81,7 +78,7 @@ func hasDotDot(path string) bool { // fully resolved using [filepath.EvalSymlinks] or otherwise constructed to // avoid containing symlink components. Of course, the root also *must not* be // attacker-controlled. -func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) { //nolint:revive // name is part of public API +func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) { // The root path must not contain ".." components, otherwise when we join // the subpath we will end up with a weird path. We could work around this // in other ways but users shouldn't be giving us non-lexical root paths in @@ -141,7 +138,7 @@ func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) { //nolint: // It's a symlink, so get its contents and expand it by prepending it // to the yet-unparsed path. linksWalked++ - if linksWalked > consts.MaxSymlinkLimit { + if linksWalked > maxSymlinkLimit { return "", &os.PathError{Op: "SecureJoin", Path: root + string(filepath.Separator) + unsafePath, Err: syscall.ELOOP} } diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/lookup_linux.go b/vendor/github.com/cyphar/filepath-securejoin/lookup_linux.go similarity index 83% rename from vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/lookup_linux.go rename to vendor/github.com/cyphar/filepath-securejoin/lookup_linux.go index ad233f140536..be81e498d724 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/lookup_linux.go +++ b/vendor/github.com/cyphar/filepath-securejoin/lookup_linux.go @@ -1,15 +1,10 @@ -// SPDX-License-Identifier: MPL-2.0 - //go:build linux -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// Copyright (C) 2024 SUSE LLC. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. -package gopathrs +package securejoin import ( "errors" @@ -20,12 +15,6 @@ import ( "strings" "golang.org/x/sys/unix" - - "github.com/cyphar/filepath-securejoin/internal/consts" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs" ) type symlinkStackEntry struct { @@ -123,12 +112,12 @@ func (s *symlinkStack) push(dir *os.File, remainingPath, linkTarget string) erro return nil } // Split the link target and clean up any "" parts. - linkTargetParts := gocompat.SlicesDeleteFunc( + linkTargetParts := slices_DeleteFunc( strings.Split(linkTarget, "/"), func(part string) bool { return part == "" || part == "." }) // Copy the directory so the caller doesn't close our copy. - dirCopy, err := fd.Dup(dir) + dirCopy, err := dupFile(dir) if err != nil { return err } @@ -166,15 +155,15 @@ func (s *symlinkStack) PopTopSymlink() (*os.File, string, bool) { return tailEntry.dir, tailEntry.remainingPath, true } -// PartialLookupInRoot tries to lookup as much of the request path as possible +// partialLookupInRoot tries to lookup as much of the request path as possible // within the provided root (a-la RESOLVE_IN_ROOT) and opens the final existing // component of the requested path, returning a file handle to the final // existing component and a string containing the remaining path components. -func PartialLookupInRoot(root fd.Fd, unsafePath string) (*os.File, string, error) { +func partialLookupInRoot(root *os.File, unsafePath string) (*os.File, string, error) { return lookupInRoot(root, unsafePath, true) } -func completeLookupInRoot(root fd.Fd, unsafePath string) (*os.File, error) { +func completeLookupInRoot(root *os.File, unsafePath string) (*os.File, error) { handle, remainingPath, err := lookupInRoot(root, unsafePath, false) if remainingPath != "" && err == nil { // should never happen @@ -185,7 +174,7 @@ func completeLookupInRoot(root fd.Fd, unsafePath string) (*os.File, error) { return handle, err } -func lookupInRoot(root fd.Fd, unsafePath string, partial bool) (Handle *os.File, _ string, _ error) { +func lookupInRoot(root *os.File, unsafePath string, partial bool) (Handle *os.File, _ string, _ error) { unsafePath = filepath.ToSlash(unsafePath) // noop // This is very similar to SecureJoin, except that we operate on the @@ -193,25 +182,20 @@ func lookupInRoot(root fd.Fd, unsafePath string, partial bool) (Handle *os.File, // managed open, along with the remaining path components not opened. // Try to use openat2 if possible. - // - // NOTE: If openat2(2) works normally but fails for this lookup, it is - // probably not a good idea to fall-back to the O_PATH resolver. An - // attacker could find a bug in the O_PATH resolver and uncontionally - // falling back to the O_PATH resolver would form a downgrade attack. - if handle, remainingPath, err := lookupOpenat2(root, unsafePath, partial); err == nil || linux.HasOpenat2() { - return handle, remainingPath, err + if hasOpenat2() { + return lookupOpenat2(root, unsafePath, partial) } // Get the "actual" root path from /proc/self/fd. This is necessary if the // root is some magic-link like /proc/$pid/root, in which case we want to - // make sure when we do procfs.CheckProcSelfFdPath that we are using the - // correct root path. - logicalRootPath, err := procfs.ProcSelfFdReadlink(root) + // make sure when we do checkProcSelfFdPath that we are using the correct + // root path. + logicalRootPath, err := procSelfFdReadlink(root) if err != nil { return nil, "", fmt.Errorf("get real root path: %w", err) } - currentDir, err := fd.Dup(root) + currentDir, err := dupFile(root) if err != nil { return nil, "", fmt.Errorf("clone root fd: %w", err) } @@ -276,7 +260,7 @@ func lookupInRoot(root fd.Fd, unsafePath string, partial bool) (Handle *os.File, return nil, "", fmt.Errorf("walking into root with part %q failed: %w", part, err) } // Jump to root. - rootClone, err := fd.Dup(root) + rootClone, err := dupFile(root) if err != nil { return nil, "", fmt.Errorf("clone root fd: %w", err) } @@ -287,21 +271,21 @@ func lookupInRoot(root fd.Fd, unsafePath string, partial bool) (Handle *os.File, } // Try to open the next component. - nextDir, err := fd.Openat(currentDir, part, unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) - switch err { - case nil: + nextDir, err := openatFile(currentDir, part, unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) + switch { + case err == nil: st, err := nextDir.Stat() if err != nil { _ = nextDir.Close() return nil, "", fmt.Errorf("stat component %q: %w", part, err) } - switch st.Mode() & os.ModeType { //nolint:exhaustive // just a glorified if statement + switch st.Mode() & os.ModeType { case os.ModeSymlink: // readlinkat implies AT_EMPTY_PATH since Linux 2.6.39. See // Linux commit 65cfc6722361 ("readlinkat(), fchownat() and // fstatat() with empty relative pathnames"). - linkDest, err := fd.Readlinkat(nextDir, "") + linkDest, err := readlinkatFile(nextDir, "") // We don't need the handle anymore. _ = nextDir.Close() if err != nil { @@ -309,7 +293,7 @@ func lookupInRoot(root fd.Fd, unsafePath string, partial bool) (Handle *os.File, } linksWalked++ - if linksWalked > consts.MaxSymlinkLimit { + if linksWalked > maxSymlinkLimit { return nil, "", &os.PathError{Op: "securejoin.lookupInRoot", Path: logicalRootPath + "/" + unsafePath, Err: unix.ELOOP} } @@ -323,7 +307,7 @@ func lookupInRoot(root fd.Fd, unsafePath string, partial bool) (Handle *os.File, // Absolute symlinks reset any work we've already done. if path.IsAbs(linkDest) { // Jump to root. - rootClone, err := fd.Dup(root) + rootClone, err := dupFile(root) if err != nil { return nil, "", fmt.Errorf("clone root fd: %w", err) } @@ -351,12 +335,12 @@ func lookupInRoot(root fd.Fd, unsafePath string, partial bool) (Handle *os.File, // rename or mount on the system. if part == ".." { // Make sure the root hasn't moved. - if err := procfs.CheckProcSelfFdPath(logicalRootPath, root); err != nil { + if err := checkProcSelfFdPath(logicalRootPath, root); err != nil { return nil, "", fmt.Errorf("root path moved during lookup: %w", err) } // Make sure the path is what we expect. fullPath := logicalRootPath + nextPath - if err := procfs.CheckProcSelfFdPath(fullPath, currentDir); err != nil { + if err := checkProcSelfFdPath(fullPath, currentDir); err != nil { return nil, "", fmt.Errorf("walking into %q had unexpected result: %w", part, err) } } @@ -387,7 +371,7 @@ func lookupInRoot(root fd.Fd, unsafePath string, partial bool) (Handle *os.File, // context of openat2, a trailing slash and a trailing "/." are completely // equivalent. if strings.HasSuffix(unsafePath, "/") { - nextDir, err := fd.Openat(currentDir, ".", unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) + nextDir, err := openatFile(currentDir, ".", unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) if err != nil { if !partial { _ = currentDir.Close() diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/mkdir_linux.go b/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go similarity index 74% rename from vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/mkdir_linux.go rename to vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go index 21a5593f44fd..a17ae3b0387e 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/mkdir_linux.go +++ b/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go @@ -1,15 +1,10 @@ -// SPDX-License-Identifier: MPL-2.0 - //go:build linux -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// Copyright (C) 2024 SUSE LLC. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. -package gopathrs +package securejoin import ( "errors" @@ -19,16 +14,12 @@ import ( "strings" "golang.org/x/sys/unix" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs" ) -// ErrInvalidMode is returned from [MkdirAll] when the requested mode is -// invalid. -var ErrInvalidMode = errors.New("invalid permission mode") +var ( + errInvalidMode = errors.New("invalid permission mode") + errPossibleAttack = errors.New("possible attack detected") +) // modePermExt is like os.ModePerm except that it also includes the set[ug]id // and sticky bits. @@ -48,11 +39,11 @@ func toUnixMode(mode os.FileMode) (uint32, error) { } // We don't allow file type bits. if mode&os.ModeType != 0 { - return 0, fmt.Errorf("%w %+.3o (%s): type bits not permitted", ErrInvalidMode, mode, mode) + return 0, fmt.Errorf("%w %+.3o (%s): type bits not permitted", errInvalidMode, mode, mode) } // We don't allow other unknown modes. if mode&^modePermExt != 0 || sysMode&unix.S_IFMT != 0 { - return 0, fmt.Errorf("%w %+.3o (%s): unknown mode bits", ErrInvalidMode, mode, mode) + return 0, fmt.Errorf("%w %+.3o (%s): unknown mode bits", errInvalidMode, mode, mode) } return sysMode, nil } @@ -75,8 +66,6 @@ func toUnixMode(mode os.FileMode) (uint32, error) { // a brand new lookup of unsafePath (such as with [SecureJoin] or openat2) after // doing [MkdirAll]. If you intend to open the directory after creating it, you // should use MkdirAllHandle. -// -// [SecureJoin]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin#SecureJoin func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.File, Err error) { unixMode, err := toUnixMode(mode) if err != nil { @@ -87,11 +76,11 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F // users it seems more prudent to return an error so users notice that // these bits will not be set. if unixMode&^0o1777 != 0 { - return nil, fmt.Errorf("%w for mkdir %+.3o: suid and sgid are ignored by mkdir", ErrInvalidMode, mode) + return nil, fmt.Errorf("%w for mkdir %+.3o: suid and sgid are ignored by mkdir", errInvalidMode, mode) } // Try to open as much of the path as possible. - currentDir, remainingPath, err := PartialLookupInRoot(root, unsafePath) + currentDir, remainingPath, err := partialLookupInRoot(root, unsafePath) defer func() { if Err != nil { _ = currentDir.Close() @@ -113,24 +102,24 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F // // This is mostly a quality-of-life check, because mkdir will simply fail // later if the attacker deletes the tree after this check. - if err := fd.IsDeadInode(currentDir); err != nil { + if err := isDeadInode(currentDir); err != nil { return nil, fmt.Errorf("finding existing subpath of %q: %w", unsafePath, err) } // Re-open the path to match the O_DIRECTORY reopen loop later (so that we // always return a non-O_PATH handle). We also check that we actually got a // directory. - if reopenDir, err := procfs.ReopenFd(currentDir, unix.O_DIRECTORY|unix.O_CLOEXEC); errors.Is(err, unix.ENOTDIR) { + if reopenDir, err := Reopen(currentDir, unix.O_DIRECTORY|unix.O_CLOEXEC); errors.Is(err, unix.ENOTDIR) { return nil, fmt.Errorf("cannot create subdirectories in %q: %w", currentDir.Name(), unix.ENOTDIR) } else if err != nil { return nil, fmt.Errorf("re-opening handle to %q: %w", currentDir.Name(), err) - } else { //nolint:revive // indent-error-flow lint doesn't make sense here + } else { _ = currentDir.Close() currentDir = reopenDir } remainingParts := strings.Split(remainingPath, string(filepath.Separator)) - if gocompat.SlicesContains(remainingParts, "..") { + if slices_Contains(remainingParts, "..") { // The path contained ".." components after the end of the "real" // components. We could try to safely resolve ".." here but that would // add a bunch of extra logic for something that it's not clear even @@ -161,12 +150,12 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F if err := unix.Mkdirat(int(currentDir.Fd()), part, unixMode); err != nil && !errors.Is(err, unix.EEXIST) { err = &os.PathError{Op: "mkdirat", Path: currentDir.Name() + "/" + part, Err: err} // Make the error a bit nicer if the directory is dead. - if deadErr := fd.IsDeadInode(currentDir); deadErr != nil { + if deadErr := isDeadInode(currentDir); deadErr != nil { // TODO: Once we bump the minimum Go version to 1.20, we can use // multiple %w verbs for this wrapping. For now we need to use a // compatibility shim for older Go versions. - // err = fmt.Errorf("%w (%w)", err, deadErr) - err = gocompat.WrapBaseError(err, deadErr) + //err = fmt.Errorf("%w (%w)", err, deadErr) + err = wrapBaseError(err, deadErr) } return nil, err } @@ -174,13 +163,13 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F // Get a handle to the next component. O_DIRECTORY means we don't need // to use O_PATH. var nextDir *os.File - if linux.HasOpenat2() { - nextDir, err = openat2(currentDir, part, &unix.OpenHow{ + if hasOpenat2() { + nextDir, err = openat2File(currentDir, part, &unix.OpenHow{ Flags: unix.O_NOFOLLOW | unix.O_DIRECTORY | unix.O_CLOEXEC, Resolve: unix.RESOLVE_BENEATH | unix.RESOLVE_NO_SYMLINKS | unix.RESOLVE_NO_XDEV, }) } else { - nextDir, err = fd.Openat(currentDir, part, unix.O_NOFOLLOW|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) + nextDir, err = openatFile(currentDir, part, unix.O_NOFOLLOW|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) } if err != nil { return nil, err @@ -210,3 +199,38 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F } return currentDir, nil } + +// MkdirAll is a race-safe alternative to the [os.MkdirAll] function, +// where the new directory is guaranteed to be within the root directory (if an +// attacker can move directories from inside the root to outside the root, the +// created directory tree might be outside of the root but the key constraint +// is that at no point will we walk outside of the directory tree we are +// creating). +// +// Effectively, MkdirAll(root, unsafePath, mode) is equivalent to +// +// path, _ := securejoin.SecureJoin(root, unsafePath) +// err := os.MkdirAll(path, mode) +// +// But is much safer. The above implementation is unsafe because if an attacker +// can modify the filesystem tree between [SecureJoin] and [os.MkdirAll], it is +// possible for MkdirAll to resolve unsafe symlink components and create +// directories outside of the root. +// +// If you plan to open the directory after you have created it or want to use +// an open directory handle as the root, you should use [MkdirAllHandle] instead. +// This function is a wrapper around [MkdirAllHandle]. +func MkdirAll(root, unsafePath string, mode os.FileMode) error { + rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) + if err != nil { + return err + } + defer rootDir.Close() + + f, err := MkdirAllHandle(rootDir, unsafePath, mode) + if err != nil { + return err + } + _ = f.Close() + return nil +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/mkdirall_compat_linux.go b/vendor/github.com/cyphar/filepath-securejoin/mkdirall_compat_linux.go deleted file mode 100644 index 795428f5abaf..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/mkdirall_compat_linux.go +++ /dev/null @@ -1,20 +0,0 @@ -// This file provides backward compatibility for callers that still reference -// MkdirAllHandle from the root package (e.g., opencontainers/runc v1.2.5). -// MkdirAllHandle moved to the pathrs-lite sub-package in v0.6.0. -// TODO: Remove once opencontainers/runc is updated. - -package securejoin - -import ( - "os" - - securejoinpathrs "github.com/cyphar/filepath-securejoin/pathrs-lite" -) - -// MkdirAllHandle is a compatibility shim for callers that import MkdirAllHandle -// from the root package. It delegates to pathrs-lite.MkdirAllHandle. -// -// Deprecated: Use github.com/cyphar/filepath-securejoin/pathrs-lite.MkdirAllHandle directly. -func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (*os.File, error) { - return securejoinpathrs.MkdirAllHandle(root, unsafePath, mode) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/open_linux.go b/vendor/github.com/cyphar/filepath-securejoin/open_linux.go new file mode 100644 index 000000000000..230be73f0eb3 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/open_linux.go @@ -0,0 +1,103 @@ +//go:build linux + +// Copyright (C) 2024 SUSE LLC. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package securejoin + +import ( + "fmt" + "os" + "strconv" + + "golang.org/x/sys/unix" +) + +// OpenatInRoot is equivalent to [OpenInRoot], except that the root is provided +// using an *[os.File] handle, to ensure that the correct root directory is used. +func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error) { + handle, err := completeLookupInRoot(root, unsafePath) + if err != nil { + return nil, &os.PathError{Op: "securejoin.OpenInRoot", Path: unsafePath, Err: err} + } + return handle, nil +} + +// OpenInRoot safely opens the provided unsafePath within the root. +// Effectively, OpenInRoot(root, unsafePath) is equivalent to +// +// path, _ := securejoin.SecureJoin(root, unsafePath) +// handle, err := os.OpenFile(path, unix.O_PATH|unix.O_CLOEXEC) +// +// But is much safer. The above implementation is unsafe because if an attacker +// can modify the filesystem tree between [SecureJoin] and [os.OpenFile], it is +// possible for the returned file to be outside of the root. +// +// Note that the returned handle is an O_PATH handle, meaning that only a very +// limited set of operations will work on the handle. This is done to avoid +// accidentally opening an untrusted file that could cause issues (such as a +// disconnected TTY that could cause a DoS, or some other issue). In order to +// use the returned handle, you can "upgrade" it to a proper handle using +// [Reopen]. +func OpenInRoot(root, unsafePath string) (*os.File, error) { + rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) + if err != nil { + return nil, err + } + defer rootDir.Close() + return OpenatInRoot(rootDir, unsafePath) +} + +// Reopen takes an *[os.File] handle and re-opens it through /proc/self/fd. +// Reopen(file, flags) is effectively equivalent to +// +// fdPath := fmt.Sprintf("/proc/self/fd/%d", file.Fd()) +// os.OpenFile(fdPath, flags|unix.O_CLOEXEC) +// +// But with some extra hardenings to ensure that we are not tricked by a +// maliciously-configured /proc mount. While this attack scenario is not +// common, in container runtimes it is possible for higher-level runtimes to be +// tricked into configuring an unsafe /proc that can be used to attack file +// operations. See [CVE-2019-19921] for more details. +// +// [CVE-2019-19921]: https://github.com/advisories/GHSA-fh74-hm69-rqjw +func Reopen(handle *os.File, flags int) (*os.File, error) { + procRoot, err := getProcRoot() + if err != nil { + return nil, err + } + + // We can't operate on /proc/thread-self/fd/$n directly when doing a + // re-open, so we need to open /proc/thread-self/fd and then open a single + // final component. + procFdDir, closer, err := procThreadSelf(procRoot, "fd/") + if err != nil { + return nil, fmt.Errorf("get safe /proc/thread-self/fd handle: %w", err) + } + defer procFdDir.Close() + defer closer() + + // Try to detect if there is a mount on top of the magic-link we are about + // to open. If we are using unsafeHostProcRoot(), this could change after + // we check it (and there's nothing we can do about that) but for + // privateProcRoot() this should be guaranteed to be safe (at least since + // Linux 5.12[1], when anonymous mount namespaces were completely isolated + // from external mounts including mount propagation events). + // + // [1]: Linux commit ee2e3f50629f ("mount: fix mounting of detached mounts + // onto targets that reside on shared mounts"). + fdStr := strconv.Itoa(int(handle.Fd())) + if err := checkSymlinkOvermount(procRoot, procFdDir, fdStr); err != nil { + return nil, fmt.Errorf("check safety of /proc/thread-self/fd/%s magiclink: %w", fdStr, err) + } + + flags |= unix.O_CLOEXEC + // Rather than just wrapping openatFile, open-code it so we can copy + // handle.Name(). + reopenFd, err := unix.Openat(int(procFdDir.Fd()), fdStr, flags, 0) + if err != nil { + return nil, fmt.Errorf("reopen fd %d: %w", handle.Fd(), err) + } + return os.NewFile(uintptr(reopenFd), handle.Name()), nil +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/openat2_linux.go b/vendor/github.com/cyphar/filepath-securejoin/openat2_linux.go new file mode 100644 index 000000000000..f7a13e69ce8b --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/openat2_linux.go @@ -0,0 +1,127 @@ +//go:build linux + +// Copyright (C) 2024 SUSE LLC. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package securejoin + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "strings" + + "golang.org/x/sys/unix" +) + +var hasOpenat2 = sync_OnceValue(func() bool { + fd, err := unix.Openat2(unix.AT_FDCWD, ".", &unix.OpenHow{ + Flags: unix.O_PATH | unix.O_CLOEXEC, + Resolve: unix.RESOLVE_NO_SYMLINKS | unix.RESOLVE_IN_ROOT, + }) + if err != nil { + return false + } + _ = unix.Close(fd) + return true +}) + +func scopedLookupShouldRetry(how *unix.OpenHow, err error) bool { + // RESOLVE_IN_ROOT (and RESOLVE_BENEATH) can return -EAGAIN if we resolve + // ".." while a mount or rename occurs anywhere on the system. This could + // happen spuriously, or as the result of an attacker trying to mess with + // us during lookup. + // + // In addition, scoped lookups have a "safety check" at the end of + // complete_walk which will return -EXDEV if the final path is not in the + // root. + return how.Resolve&(unix.RESOLVE_IN_ROOT|unix.RESOLVE_BENEATH) != 0 && + (errors.Is(err, unix.EAGAIN) || errors.Is(err, unix.EXDEV)) +} + +const scopedLookupMaxRetries = 10 + +func openat2File(dir *os.File, path string, how *unix.OpenHow) (*os.File, error) { + fullPath := dir.Name() + "/" + path + // Make sure we always set O_CLOEXEC. + how.Flags |= unix.O_CLOEXEC + var tries int + for tries < scopedLookupMaxRetries { + fd, err := unix.Openat2(int(dir.Fd()), path, how) + if err != nil { + if scopedLookupShouldRetry(how, err) { + // We retry a couple of times to avoid the spurious errors, and + // if we are being attacked then returning -EAGAIN is the best + // we can do. + tries++ + continue + } + return nil, &os.PathError{Op: "openat2", Path: fullPath, Err: err} + } + // If we are using RESOLVE_IN_ROOT, the name we generated may be wrong. + // NOTE: The procRoot code MUST NOT use RESOLVE_IN_ROOT, otherwise + // you'll get infinite recursion here. + if how.Resolve&unix.RESOLVE_IN_ROOT == unix.RESOLVE_IN_ROOT { + if actualPath, err := rawProcSelfFdReadlink(fd); err == nil { + fullPath = actualPath + } + } + return os.NewFile(uintptr(fd), fullPath), nil + } + return nil, &os.PathError{Op: "openat2", Path: fullPath, Err: errPossibleAttack} +} + +func lookupOpenat2(root *os.File, unsafePath string, partial bool) (*os.File, string, error) { + if !partial { + file, err := openat2File(root, unsafePath, &unix.OpenHow{ + Flags: unix.O_PATH | unix.O_CLOEXEC, + Resolve: unix.RESOLVE_IN_ROOT | unix.RESOLVE_NO_MAGICLINKS, + }) + return file, "", err + } + return partialLookupOpenat2(root, unsafePath) +} + +// partialLookupOpenat2 is an alternative implementation of +// partialLookupInRoot, using openat2(RESOLVE_IN_ROOT) to more safely get a +// handle to the deepest existing child of the requested path within the root. +func partialLookupOpenat2(root *os.File, unsafePath string) (*os.File, string, error) { + // TODO: Implement this as a git-bisect-like binary search. + + unsafePath = filepath.ToSlash(unsafePath) // noop + endIdx := len(unsafePath) + var lastError error + for endIdx > 0 { + subpath := unsafePath[:endIdx] + + handle, err := openat2File(root, subpath, &unix.OpenHow{ + Flags: unix.O_PATH | unix.O_CLOEXEC, + Resolve: unix.RESOLVE_IN_ROOT | unix.RESOLVE_NO_MAGICLINKS, + }) + if err == nil { + // Jump over the slash if we have a non-"" remainingPath. + if endIdx < len(unsafePath) { + endIdx += 1 + } + // We found a subpath! + return handle, unsafePath[endIdx:], lastError + } + if errors.Is(err, unix.ENOENT) || errors.Is(err, unix.ENOTDIR) { + // That path doesn't exist, let's try the next directory up. + endIdx = strings.LastIndexByte(subpath, '/') + lastError = err + continue + } + return nil, "", fmt.Errorf("open subpath: %w", err) + } + // If we couldn't open anything, the whole subpath is missing. Return a + // copy of the root fd so that the caller doesn't close this one by + // accident. + rootClone, err := dupFile(root) + if err != nil { + return nil, "", err + } + return rootClone, unsafePath, lastError +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go b/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go new file mode 100644 index 000000000000..949fb5f2d82d --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go @@ -0,0 +1,59 @@ +//go:build linux + +// Copyright (C) 2024 SUSE LLC. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package securejoin + +import ( + "os" + "path/filepath" + + "golang.org/x/sys/unix" +) + +func dupFile(f *os.File) (*os.File, error) { + fd, err := unix.FcntlInt(f.Fd(), unix.F_DUPFD_CLOEXEC, 0) + if err != nil { + return nil, os.NewSyscallError("fcntl(F_DUPFD_CLOEXEC)", err) + } + return os.NewFile(uintptr(fd), f.Name()), nil +} + +func openatFile(dir *os.File, path string, flags int, mode int) (*os.File, error) { + // Make sure we always set O_CLOEXEC. + flags |= unix.O_CLOEXEC + fd, err := unix.Openat(int(dir.Fd()), path, flags, uint32(mode)) + if err != nil { + return nil, &os.PathError{Op: "openat", Path: dir.Name() + "/" + path, Err: err} + } + // All of the paths we use with openatFile(2) are guaranteed to be + // lexically safe, so we can use path.Join here. + fullPath := filepath.Join(dir.Name(), path) + return os.NewFile(uintptr(fd), fullPath), nil +} + +func fstatatFile(dir *os.File, path string, flags int) (unix.Stat_t, error) { + var stat unix.Stat_t + if err := unix.Fstatat(int(dir.Fd()), path, &stat, flags); err != nil { + return stat, &os.PathError{Op: "fstatat", Path: dir.Name() + "/" + path, Err: err} + } + return stat, nil +} + +func readlinkatFile(dir *os.File, path string) (string, error) { + size := 4096 + for { + linkBuf := make([]byte, size) + n, err := unix.Readlinkat(int(dir.Fd()), path, linkBuf) + if err != nil { + return "", &os.PathError{Op: "readlinkat", Path: dir.Name() + "/" + path, Err: err} + } + if n != size { + return string(linkBuf[:n]), nil + } + // Possible truncation, resize the buffer. + size *= 2 + } +} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/README.md b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/README.md deleted file mode 100644 index bb95b028c67a..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/README.md +++ /dev/null @@ -1,35 +0,0 @@ -## `pathrs-lite` ## - -`github.com/cyphar/filepath-securejoin/pathrs-lite` provides a minimal **pure -Go** implementation of the core bits of [libpathrs][]. This is not intended to -be a complete replacement for libpathrs, instead it is mainly intended to be -useful as a transition tool for existing Go projects. - -`pathrs-lite` also provides a very easy way to switch to `libpathrs` (even for -downstreams where `pathrs-lite` is being used in a third-party package and is -not interested in using CGo). At build time, if you use the `libpathrs` build -tag then `pathrs-lite` will use `libpathrs` directly instead of the pure Go -implementation. The two backends are functionally equivalent (and we have -integration tests to verify this), so this migration should be very easy with -no user-visible impact. - -[libpathrs]: https://github.com/cyphar/libpathrs - -### License ### - -Most of this subpackage is licensed under the Mozilla Public License (version -2.0). For more information, see the top-level [COPYING.md][] and -[LICENSE.MPL-2.0][] files, as well as the individual license headers for each -file. - -``` -Copyright (C) 2024-2025 Aleksa Sarai -Copyright (C) 2024-2025 SUSE LLC - -This Source Code Form is subject to the terms of the Mozilla Public -License, v. 2.0. If a copy of the MPL was not distributed with this -file, You can obtain one at https://mozilla.org/MPL/2.0/. -``` - -[COPYING.md]: ../COPYING.md -[LICENSE.MPL-2.0]: ../LICENSE.MPL-2.0 diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/doc.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/doc.go deleted file mode 100644 index 61411da37afe..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/doc.go +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// Package pathrs (pathrs-lite) is a less complete pure Go implementation of -// some of the APIs provided by [libpathrs]. -// -// [libpathrs]: https://github.com/cyphar/libpathrs -package pathrs diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/assert/assert.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/assert/assert.go deleted file mode 100644 index 595dfbf1acf6..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/assert/assert.go +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -// Copyright (C) 2025 Aleksa Sarai -// Copyright (C) 2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// Package assert provides some basic assertion helpers for Go. -package assert - -import ( - "fmt" -) - -// Assert panics if the predicate is false with the provided argument. -func Assert(predicate bool, msg any) { - if !predicate { - panic(msg) - } -} - -// Assertf panics if the predicate is false and formats the message using the -// same formatting as [fmt.Printf]. -// -// [fmt.Printf]: https://pkg.go.dev/fmt#Printf -func Assertf(predicate bool, fmtMsg string, args ...any) { - Assert(predicate, fmt.Sprintf(fmtMsg, args...)) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/errors_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/errors_linux.go deleted file mode 100644 index d0b200f4f9a1..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/errors_linux.go +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// Package internal contains unexported common code for filepath-securejoin. -package internal - -import ( - "errors" - - "golang.org/x/sys/unix" -) - -type xdevErrorish struct { - description string -} - -func (err xdevErrorish) Error() string { return err.description } -func (err xdevErrorish) Is(target error) bool { return target == unix.EXDEV } - -var ( - // ErrPossibleAttack indicates that some attack was detected. - ErrPossibleAttack error = xdevErrorish{"possible attack detected"} - - // ErrPossibleBreakout indicates that during an operation we ended up in a - // state that could be a breakout but we detected it. - ErrPossibleBreakout error = xdevErrorish{"possible breakout detected"} - - // ErrInvalidDirectory indicates an unlinked directory. - ErrInvalidDirectory = errors.New("wandered into deleted directory") - - // ErrDeletedInode indicates an unlinked file (non-directory). - ErrDeletedInode = errors.New("cannot verify path of deleted inode") -) diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/at_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/at_linux.go deleted file mode 100644 index 091054913046..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/at_linux.go +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package fd - -import ( - "fmt" - "os" - "path/filepath" - "runtime" - - "golang.org/x/sys/unix" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat" -) - -// prepareAtWith returns -EBADF (an invalid fd) if dir is nil, otherwise using -// the dir.Fd(). We use -EBADF because in filepath-securejoin we generally -// don't want to allow relative-to-cwd paths. The returned path is an -// *informational* string that describes a reasonable pathname for the given -// *at(2) arguments. You must not use the full path for any actual filesystem -// operations. -func prepareAt(dir Fd, path string) (dirFd int, unsafeUnmaskedPath string) { - dirFd, dirPath := -int(unix.EBADF), "." - if dir != nil { - dirFd, dirPath = int(dir.Fd()), dir.Name() - } - if !filepath.IsAbs(path) { - // only prepend the dirfd path for relative paths - path = dirPath + "/" + path - } - // NOTE: If path is "." or "", the returned path won't be filepath.Clean, - // but that's okay since this path is either used for errors (in which case - // a trailing "/" or "/." is important information) or will be - // filepath.Clean'd later (in the case of fd.Openat). - return dirFd, path -} - -// Openat is an [Fd]-based wrapper around unix.Openat. -func Openat(dir Fd, path string, flags int, mode int) (*os.File, error) { //nolint:unparam // wrapper func - dirFd, fullPath := prepareAt(dir, path) - // Make sure we always set O_CLOEXEC. - flags |= unix.O_CLOEXEC - fd, err := unix.Openat(dirFd, path, flags, uint32(mode)) - if err != nil { - return nil, &os.PathError{Op: "openat", Path: fullPath, Err: err} - } - runtime.KeepAlive(dir) - // openat is only used with lexically-safe paths so we can use - // filepath.Clean here, and also the path itself is not going to be used - // for actual path operations. - fullPath = filepath.Clean(fullPath) - return os.NewFile(uintptr(fd), fullPath), nil -} - -// Fstatat is an [Fd]-based wrapper around unix.Fstatat. -func Fstatat(dir Fd, path string, flags int) (unix.Stat_t, error) { - dirFd, fullPath := prepareAt(dir, path) - var stat unix.Stat_t - if err := unix.Fstatat(dirFd, path, &stat, flags); err != nil { - return stat, &os.PathError{Op: "fstatat", Path: fullPath, Err: err} - } - runtime.KeepAlive(dir) - return stat, nil -} - -// Faccessat is an [Fd]-based wrapper around unix.Faccessat. -func Faccessat(dir Fd, path string, mode uint32, flags int) error { - dirFd, fullPath := prepareAt(dir, path) - err := unix.Faccessat(dirFd, path, mode, flags) - if err != nil { - err = &os.PathError{Op: "faccessat", Path: fullPath, Err: err} - } - runtime.KeepAlive(dir) - return err -} - -// Readlinkat is an [Fd]-based wrapper around unix.Readlinkat. -func Readlinkat(dir Fd, path string) (string, error) { - dirFd, fullPath := prepareAt(dir, path) - size := 4096 - for { - linkBuf := make([]byte, size) - n, err := unix.Readlinkat(dirFd, path, linkBuf) - if err != nil { - return "", &os.PathError{Op: "readlinkat", Path: fullPath, Err: err} - } - runtime.KeepAlive(dir) - if n != size { - return string(linkBuf[:n]), nil - } - // Possible truncation, resize the buffer. - size *= 2 - } -} - -const ( - // STATX_MNT_ID_UNIQUE is provided in golang.org/x/sys@v0.20.0, but in order to - // avoid bumping the requirement for a single constant we can just define it - // ourselves. - _STATX_MNT_ID_UNIQUE = 0x4000 //nolint:revive // unix.* name - - // We don't care which mount ID we get. The kernel will give us the unique - // one if it is supported. If the kernel doesn't support - // STATX_MNT_ID_UNIQUE, the bit is ignored and the returned request mask - // will only contain STATX_MNT_ID (if supported). - wantStatxMntMask = _STATX_MNT_ID_UNIQUE | unix.STATX_MNT_ID -) - -var hasStatxMountID = gocompat.SyncOnceValue(func() bool { - var stx unix.Statx_t - err := unix.Statx(-int(unix.EBADF), "/", 0, wantStatxMntMask, &stx) - return err == nil && stx.Mask&wantStatxMntMask != 0 -}) - -// GetMountID gets the mount identifier associated with the fd and path -// combination. It is effectively a wrapper around fetching -// STATX_MNT_ID{,_UNIQUE} with unix.Statx, but with a fallback to 0 if the -// kernel doesn't support the feature. -func GetMountID(dir Fd, path string) (uint64, error) { - // If we don't have statx(STATX_MNT_ID*) support, we can't do anything. - if !hasStatxMountID() { - return 0, nil - } - - dirFd, fullPath := prepareAt(dir, path) - - var stx unix.Statx_t - err := unix.Statx(dirFd, path, unix.AT_EMPTY_PATH|unix.AT_SYMLINK_NOFOLLOW, wantStatxMntMask, &stx) - if stx.Mask&wantStatxMntMask == 0 { - // It's not a kernel limitation, for some reason we couldn't get a - // mount ID. Assume it's some kind of attack. - err = fmt.Errorf("could not get mount id: %w", err) - } - if err != nil { - return 0, &os.PathError{Op: "statx(STATX_MNT_ID_...)", Path: fullPath, Err: err} - } - runtime.KeepAlive(dir) - return stx.Mnt_id, nil -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/fd.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/fd.go deleted file mode 100644 index d2206a386f91..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/fd.go +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -// Copyright (C) 2025 Aleksa Sarai -// Copyright (C) 2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// Package fd provides a drop-in interface-based replacement of [*os.File] that -// allows for things like noop-Close wrappers to be used. -// -// [*os.File]: https://pkg.go.dev/os#File -package fd - -import ( - "io" - "os" -) - -// Fd is an interface that mirrors most of the API of [*os.File], allowing you -// to create wrappers that can be used in place of [*os.File]. -// -// [*os.File]: https://pkg.go.dev/os#File -type Fd interface { - io.Closer - Name() string - Fd() uintptr -} - -// Compile-time interface checks. -var ( - _ Fd = (*os.File)(nil) - _ Fd = noClose{} -) - -type noClose struct{ inner Fd } - -func (f noClose) Name() string { return f.inner.Name() } -func (f noClose) Fd() uintptr { return f.inner.Fd() } - -func (f noClose) Close() error { return nil } - -// NopCloser returns an [*os.File]-like object where the [Close] method is now -// a no-op. -// -// Note that for [*os.File] and similar objects, the Go garbage collector will -// still call [Close] on the underlying file unless you use -// [runtime.SetFinalizer] to disable this behaviour. This is up to the caller -// to do (if necessary). -// -// [*os.File]: https://pkg.go.dev/os#File -// [Close]: https://pkg.go.dev/io#Closer -// [runtime.SetFinalizer]: https://pkg.go.dev/runtime#SetFinalizer -func NopCloser(f Fd) Fd { return noClose{inner: f} } diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/fd_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/fd_linux.go deleted file mode 100644 index e1ec3c0b8e42..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/fd_linux.go +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package fd - -import ( - "fmt" - "os" - "runtime" - - "golang.org/x/sys/unix" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal" -) - -// DupWithName creates a new file descriptor referencing the same underlying -// file, but with the provided name instead of fd.Name(). -func DupWithName(fd Fd, name string) (*os.File, error) { - fd2, err := unix.FcntlInt(fd.Fd(), unix.F_DUPFD_CLOEXEC, 0) - if err != nil { - return nil, os.NewSyscallError("fcntl(F_DUPFD_CLOEXEC)", err) - } - runtime.KeepAlive(fd) - return os.NewFile(uintptr(fd2), name), nil -} - -// Dup creates a new file description referencing the same underlying file. -func Dup(fd Fd) (*os.File, error) { - return DupWithName(fd, fd.Name()) -} - -// Fstat is an [Fd]-based wrapper around unix.Fstat. -func Fstat(fd Fd) (unix.Stat_t, error) { - var stat unix.Stat_t - if err := unix.Fstat(int(fd.Fd()), &stat); err != nil { - return stat, &os.PathError{Op: "fstat", Path: fd.Name(), Err: err} - } - runtime.KeepAlive(fd) - return stat, nil -} - -// Fstatfs is an [Fd]-based wrapper around unix.Fstatfs. -func Fstatfs(fd Fd) (unix.Statfs_t, error) { - var statfs unix.Statfs_t - if err := unix.Fstatfs(int(fd.Fd()), &statfs); err != nil { - return statfs, &os.PathError{Op: "fstatfs", Path: fd.Name(), Err: err} - } - runtime.KeepAlive(fd) - return statfs, nil -} - -// IsDeadInode detects whether the file has been unlinked from a filesystem and -// is thus a "dead inode" from the kernel's perspective. -func IsDeadInode(file Fd) error { - // If the nlink of a file drops to 0, there is an attacker deleting - // directories during our walk, which could result in weird /proc values. - // It's better to error out in this case. - stat, err := Fstat(file) - if err != nil { - return fmt.Errorf("check for dead inode: %w", err) - } - if stat.Nlink == 0 { - err := internal.ErrDeletedInode - if stat.Mode&unix.S_IFMT == unix.S_IFDIR { - err = internal.ErrInvalidDirectory - } - return fmt.Errorf("%w %q", err, file.Name()) - } - return nil -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/mount_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/mount_linux.go deleted file mode 100644 index 77549c7a993c..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/mount_linux.go +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package fd - -import ( - "os" - "runtime" - - "golang.org/x/sys/unix" -) - -// Fsopen is an [Fd]-based wrapper around unix.Fsopen. -func Fsopen(fsName string, flags int) (*os.File, error) { - // Make sure we always set O_CLOEXEC. - flags |= unix.FSOPEN_CLOEXEC - fd, err := unix.Fsopen(fsName, flags) - if err != nil { - return nil, os.NewSyscallError("fsopen "+fsName, err) - } - return os.NewFile(uintptr(fd), "fscontext:"+fsName), nil -} - -// Fsmount is an [Fd]-based wrapper around unix.Fsmount. -func Fsmount(ctx Fd, flags, mountAttrs int) (*os.File, error) { - // Make sure we always set O_CLOEXEC. - flags |= unix.FSMOUNT_CLOEXEC - fd, err := unix.Fsmount(int(ctx.Fd()), flags, mountAttrs) - if err != nil { - return nil, os.NewSyscallError("fsmount "+ctx.Name(), err) - } - return os.NewFile(uintptr(fd), "fsmount:"+ctx.Name()), nil -} - -// OpenTree is an [Fd]-based wrapper around unix.OpenTree. -func OpenTree(dir Fd, path string, flags uint) (*os.File, error) { - dirFd, fullPath := prepareAt(dir, path) - // Make sure we always set O_CLOEXEC. - flags |= unix.OPEN_TREE_CLOEXEC - fd, err := unix.OpenTree(dirFd, path, flags) - if err != nil { - return nil, &os.PathError{Op: "open_tree", Path: fullPath, Err: err} - } - runtime.KeepAlive(dir) - return os.NewFile(uintptr(fd), fullPath), nil -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/openat2_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/openat2_linux.go deleted file mode 100644 index 63863647d5b1..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/openat2_linux.go +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package fd - -import ( - "errors" - "os" - "runtime" - - "golang.org/x/sys/unix" -) - -func scopedLookupShouldRetry(how *unix.OpenHow, err error) bool { - // RESOLVE_IN_ROOT (and RESOLVE_BENEATH) can return -EAGAIN if we resolve - // ".." while a mount or rename occurs anywhere on the system. This could - // happen spuriously, or as the result of an attacker trying to mess with - // us during lookup. - // - // In addition, scoped lookups have a "safety check" at the end of - // complete_walk which will return -EXDEV if the final path is not in the - // root. - return how.Resolve&(unix.RESOLVE_IN_ROOT|unix.RESOLVE_BENEATH) != 0 && - (errors.Is(err, unix.EAGAIN) || errors.Is(err, unix.EXDEV)) -} - -// This is a fairly arbitrary limit we have just to avoid an attacker being -// able to make us spin in an infinite retry loop -- callers can choose to -// retry on EAGAIN if they prefer. -const scopedLookupMaxRetries = 128 - -// Openat2 is an [Fd]-based wrapper around unix.Openat2, but with some retry -// logic in case of EAGAIN errors. -// -// NOTE: This is a variable so that the lookup tests can force openat2 to fail. -var Openat2 = func(dir Fd, path string, how *unix.OpenHow) (*os.File, error) { - dirFd, fullPath := prepareAt(dir, path) - // Make sure we always set O_CLOEXEC. - how.Flags |= unix.O_CLOEXEC - var tries int - for { - fd, err := unix.Openat2(dirFd, path, how) - if err != nil { - if scopedLookupShouldRetry(how, err) && tries < scopedLookupMaxRetries { - // We retry a couple of times to avoid the spurious errors, and - // if we are being attacked then returning -EAGAIN is the best - // we can do. - tries++ - continue - } - return nil, &os.PathError{Op: "openat2", Path: fullPath, Err: err} - } - runtime.KeepAlive(dir) - return os.NewFile(uintptr(fd), fullPath), nil - } -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/README.md b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/README.md deleted file mode 100644 index 5dcb6ae00702..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## gocompat ## - -This directory contains backports of stdlib functions from later Go versions so -the filepath-securejoin can continue to be used by projects that are stuck with -Go 1.18 support. Note that often filepath-securejoin is added in security -patches for old releases, so avoiding the need to bump Go compiler requirements -is a huge plus to downstreams. - -The source code is licensed under the same license as the Go stdlib. See the -source files for the precise license information. diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/doc.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/doc.go deleted file mode 100644 index 4b1803f580ad..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/doc.go +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -//go:build linux && go1.20 - -// Copyright (C) 2025 SUSE LLC. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package gocompat includes compatibility shims (backported from future Go -// stdlib versions) to permit filepath-securejoin to be used with older Go -// versions (often filepath-securejoin is added in security patches for old -// releases, so avoiding the need to bump Go compiler requirements is a huge -// plus to downstreams). -package gocompat diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_go119.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_go119.go deleted file mode 100644 index ac93cb045e16..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_go119.go +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux && go1.19 - -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gocompat - -import ( - "sync/atomic" -) - -// A Bool is an atomic boolean value. -// The zero value is false. -// -// Bool must not be copied after first use. -type Bool = atomic.Bool diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_unsupported.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_unsupported.go deleted file mode 100644 index 21b5b29ada9f..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_unsupported.go +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux && !go1.19 - -// Copyright (C) 2024-2025 SUSE LLC. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gocompat - -import ( - "sync/atomic" -) - -// noCopy may be added to structs which must not be copied -// after the first use. -// -// See https://golang.org/issues/8005#issuecomment-190753527 -// for details. -// -// Note that it must not be embedded, due to the Lock and Unlock methods. -type noCopy struct{} - -// Lock is a no-op used by -copylocks checker from `go vet`. -func (*noCopy) Lock() {} - -// b32 returns a uint32 0 or 1 representing b. -func b32(b bool) uint32 { - if b { - return 1 - } - return 0 -} - -// A Bool is an atomic boolean value. -// The zero value is false. -// -// Bool must not be copied after first use. -type Bool struct { - _ noCopy - v uint32 -} - -// Load atomically loads and returns the value stored in x. -func (x *Bool) Load() bool { return atomic.LoadUint32(&x.v) != 0 } - -// Store atomically stores val into x. -func (x *Bool) Store(val bool) { atomic.StoreUint32(&x.v, b32(val)) } diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_generics_go121.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_generics_go121.go deleted file mode 100644 index d4a938186e48..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_generics_go121.go +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux && go1.21 - -// Copyright (C) 2024-2025 SUSE LLC. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gocompat - -import ( - "cmp" - "slices" - "sync" -) - -// SlicesDeleteFunc is equivalent to Go 1.21's slices.DeleteFunc. -func SlicesDeleteFunc[S ~[]E, E any](slice S, delFn func(E) bool) S { - return slices.DeleteFunc(slice, delFn) -} - -// SlicesContains is equivalent to Go 1.21's slices.Contains. -func SlicesContains[S ~[]E, E comparable](slice S, val E) bool { - return slices.Contains(slice, val) -} - -// SlicesClone is equivalent to Go 1.21's slices.Clone. -func SlicesClone[S ~[]E, E any](slice S) S { - return slices.Clone(slice) -} - -// SyncOnceValue is equivalent to Go 1.21's sync.OnceValue. -func SyncOnceValue[T any](f func() T) func() T { - return sync.OnceValue(f) -} - -// SyncOnceValues is equivalent to Go 1.21's sync.OnceValues. -func SyncOnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) { - return sync.OnceValues(f) -} - -// CmpOrdered is equivalent to Go 1.21's cmp.Ordered generic type definition. -type CmpOrdered = cmp.Ordered - -// CmpCompare is equivalent to Go 1.21's cmp.Compare. -func CmpCompare[T CmpOrdered](x, y T) int { - return cmp.Compare(x, y) -} - -// Max2 is equivalent to Go 1.21's max builtin (but only for two parameters). -func Max2[T CmpOrdered](x, y T) T { - return max(x, y) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_generics_unsupported.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_generics_unsupported.go deleted file mode 100644 index 0ea6218aa6c8..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_generics_unsupported.go +++ /dev/null @@ -1,187 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux && !go1.21 - -// Copyright (C) 2021, 2022 The Go Authors. All rights reserved. -// Copyright (C) 2024-2025 SUSE LLC. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE.BSD file. - -package gocompat - -import ( - "sync" -) - -// These are very minimal implementations of functions that appear in Go 1.21's -// stdlib, included so that we can build on older Go versions. Most are -// borrowed directly from the stdlib, and a few are modified to be "obviously -// correct" without needing to copy too many other helpers. - -// clearSlice is equivalent to Go 1.21's builtin clear. -// Copied from the Go 1.24 stdlib implementation. -func clearSlice[S ~[]E, E any](slice S) { - var zero E - for i := range slice { - slice[i] = zero - } -} - -// slicesIndexFunc is equivalent to Go 1.21's slices.IndexFunc. -// Copied from the Go 1.24 stdlib implementation. -func slicesIndexFunc[S ~[]E, E any](s S, f func(E) bool) int { - for i := range s { - if f(s[i]) { - return i - } - } - return -1 -} - -// SlicesDeleteFunc is equivalent to Go 1.21's slices.DeleteFunc. -// Copied from the Go 1.24 stdlib implementation. -func SlicesDeleteFunc[S ~[]E, E any](s S, del func(E) bool) S { - i := slicesIndexFunc(s, del) - if i == -1 { - return s - } - // Don't start copying elements until we find one to delete. - for j := i + 1; j < len(s); j++ { - if v := s[j]; !del(v) { - s[i] = v - i++ - } - } - clearSlice(s[i:]) // zero/nil out the obsolete elements, for GC - return s[:i] -} - -// SlicesContains is equivalent to Go 1.21's slices.Contains. -// Similar to the stdlib slices.Contains, except that we don't have -// slices.Index so we need to use slices.IndexFunc for this non-Func helper. -func SlicesContains[S ~[]E, E comparable](s S, v E) bool { - return slicesIndexFunc(s, func(e E) bool { return e == v }) >= 0 -} - -// SlicesClone is equivalent to Go 1.21's slices.Clone. -// Copied from the Go 1.24 stdlib implementation. -func SlicesClone[S ~[]E, E any](s S) S { - // Preserve nil in case it matters. - if s == nil { - return nil - } - return append(S([]E{}), s...) -} - -// SyncOnceValue is equivalent to Go 1.21's sync.OnceValue. -// Copied from the Go 1.25 stdlib implementation. -func SyncOnceValue[T any](f func() T) func() T { - // Use a struct so that there's a single heap allocation. - d := struct { - f func() T - once sync.Once - valid bool - p any - result T - }{ - f: f, - } - return func() T { - d.once.Do(func() { - defer func() { - d.f = nil - d.p = recover() - if !d.valid { - panic(d.p) - } - }() - d.result = d.f() - d.valid = true - }) - if !d.valid { - panic(d.p) - } - return d.result - } -} - -// SyncOnceValues is equivalent to Go 1.21's sync.OnceValues. -// Copied from the Go 1.25 stdlib implementation. -func SyncOnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) { - // Use a struct so that there's a single heap allocation. - d := struct { - f func() (T1, T2) - once sync.Once - valid bool - p any - r1 T1 - r2 T2 - }{ - f: f, - } - return func() (T1, T2) { - d.once.Do(func() { - defer func() { - d.f = nil - d.p = recover() - if !d.valid { - panic(d.p) - } - }() - d.r1, d.r2 = d.f() - d.valid = true - }) - if !d.valid { - panic(d.p) - } - return d.r1, d.r2 - } -} - -// CmpOrdered is equivalent to Go 1.21's cmp.Ordered generic type definition. -// Copied from the Go 1.25 stdlib implementation. -type CmpOrdered interface { - ~int | ~int8 | ~int16 | ~int32 | ~int64 | - ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | - ~float32 | ~float64 | - ~string -} - -// isNaN reports whether x is a NaN without requiring the math package. -// This will always return false if T is not floating-point. -// Copied from the Go 1.25 stdlib implementation. -func isNaN[T CmpOrdered](x T) bool { - return x != x -} - -// CmpCompare is equivalent to Go 1.21's cmp.Compare. -// Copied from the Go 1.25 stdlib implementation. -func CmpCompare[T CmpOrdered](x, y T) int { - xNaN := isNaN(x) - yNaN := isNaN(y) - if xNaN { - if yNaN { - return 0 - } - return -1 - } - if yNaN { - return +1 - } - if x < y { - return -1 - } - if x > y { - return +1 - } - return 0 -} - -// Max2 is equivalent to Go 1.21's max builtin for two parameters. -func Max2[T CmpOrdered](x, y T) T { - m := x - if y > m { - m = y - } - return m -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/doc.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/doc.go deleted file mode 100644 index 2ddb71e84452..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/doc.go +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// Package gopathrs is a less complete pure Go implementation of some of the -// APIs provided by [libpathrs]. -// -// [libpathrs]: https://github.com/cyphar/libpathrs -package gopathrs diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/open_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/open_linux.go deleted file mode 100644 index cd9632a9588b..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/open_linux.go +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package gopathrs - -import ( - "os" -) - -// OpenatInRoot is equivalent to [OpenInRoot], except that the root is provided -// using an *[os.File] handle, to ensure that the correct root directory is used. -func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error) { - handle, err := completeLookupInRoot(root, unsafePath) - if err != nil { - return nil, &os.PathError{Op: "securejoin.OpenInRoot", Path: unsafePath, Err: err} - } - return handle, nil -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/openat2_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/openat2_linux.go deleted file mode 100644 index 9c5c268f6654..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/openat2_linux.go +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package gopathrs - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "strings" - - "golang.org/x/sys/unix" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd" - "github.com/cyphar/filepath-securejoin/pathrs-lite/procfs" -) - -func openat2(dir fd.Fd, path string, how *unix.OpenHow) (*os.File, error) { - file, err := fd.Openat2(dir, path, how) - if err != nil { - return nil, err - } - // If we are using RESOLVE_IN_ROOT, the name we generated may be wrong. - if how.Resolve&unix.RESOLVE_IN_ROOT == unix.RESOLVE_IN_ROOT { - if actualPath, err := procfs.ProcSelfFdReadlink(file); err == nil { - // TODO: Ideally we would not need to dup the fd, but you cannot - // easily just swap an *os.File with one from the same fd - // (the GC will close the old one, and you cannot clear the - // finaliser easily because it is associated with an internal - // field of *os.File not *os.File itself). - newFile, err := fd.DupWithName(file, actualPath) - if err != nil { - return nil, err - } - _ = file.Close() - file = newFile - } - } - return file, nil -} - -func lookupOpenat2(root fd.Fd, unsafePath string, partial bool) (*os.File, string, error) { - if !partial { - file, err := openat2(root, unsafePath, &unix.OpenHow{ - Flags: unix.O_PATH | unix.O_CLOEXEC, - Resolve: unix.RESOLVE_IN_ROOT | unix.RESOLVE_NO_MAGICLINKS, - }) - return file, "", err - } - return partialLookupOpenat2(root, unsafePath) -} - -// partialLookupOpenat2 is an alternative implementation of -// partialLookupInRoot, using openat2(RESOLVE_IN_ROOT) to more safely get a -// handle to the deepest existing child of the requested path within the root. -func partialLookupOpenat2(root fd.Fd, unsafePath string) (*os.File, string, error) { - // TODO: Implement this as a git-bisect-like binary search. - - unsafePath = filepath.ToSlash(unsafePath) // noop - endIdx := len(unsafePath) - var lastError error - for endIdx > 0 { - subpath := unsafePath[:endIdx] - - handle, err := openat2(root, subpath, &unix.OpenHow{ - Flags: unix.O_PATH | unix.O_CLOEXEC, - Resolve: unix.RESOLVE_IN_ROOT | unix.RESOLVE_NO_MAGICLINKS, - }) - if err == nil { - // Jump over the slash if we have a non-"" remainingPath. - if endIdx < len(unsafePath) { - endIdx++ - } - // We found a subpath! - return handle, unsafePath[endIdx:], lastError - } - if errors.Is(err, unix.ENOENT) || errors.Is(err, unix.ENOTDIR) { - // That path doesn't exist, let's try the next directory up. - endIdx = strings.LastIndexByte(subpath, '/') - lastError = err - continue - } - return nil, "", fmt.Errorf("open subpath: %w", err) - } - // If we couldn't open anything, the whole subpath is missing. Return a - // copy of the root fd so that the caller doesn't close this one by - // accident. - rootClone, err := fd.Dup(root) - if err != nil { - return nil, "", err - } - return rootClone, unsafePath, lastError -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/kernelversion/kernel_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/kernelversion/kernel_linux.go deleted file mode 100644 index cb6de41861fe..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/kernelversion/kernel_linux.go +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause - -// Copyright (C) 2022 The Go Authors. All rights reserved. -// Copyright (C) 2025 SUSE LLC. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE.BSD file. - -// The parsing logic is very loosely based on the Go stdlib's -// src/internal/syscall/unix/kernel_version_linux.go but with an API that looks -// a bit like runc's libcontainer/system/kernelversion. -// -// TODO(cyphar): This API has been copied around to a lot of different projects -// (Docker, containerd, runc, and now filepath-securejoin) -- maybe we should -// put it in a separate project? - -// Package kernelversion provides a simple mechanism for checking whether the -// running kernel is at least as new as some baseline kernel version. This is -// often useful when checking for features that would be too complicated to -// test support for (or in cases where we know that some kernel features in -// backport-heavy kernels are broken and need to be avoided). -package kernelversion - -import ( - "bytes" - "errors" - "fmt" - "strconv" - "strings" - - "golang.org/x/sys/unix" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat" -) - -// KernelVersion is a numeric representation of the key numerical elements of a -// kernel version (for instance, "4.1.2-default-1" would be represented as -// KernelVersion{4, 1, 2}). -type KernelVersion []uint64 - -func (kver KernelVersion) String() string { - var str strings.Builder - for idx, elem := range kver { - if idx != 0 { - _, _ = str.WriteRune('.') - } - _, _ = str.WriteString(strconv.FormatUint(elem, 10)) - } - return str.String() -} - -var errInvalidKernelVersion = errors.New("invalid kernel version") - -// parseKernelVersion parses a string and creates a KernelVersion based on it. -func parseKernelVersion(kverStr string) (KernelVersion, error) { - kver := make(KernelVersion, 1, 3) - for idx, ch := range kverStr { - if '0' <= ch && ch <= '9' { - v := &kver[len(kver)-1] - *v = (*v * 10) + uint64(ch-'0') - } else { - if idx == 0 || kverStr[idx-1] < '0' || '9' < kverStr[idx-1] { - // "." must be preceded by a digit while in version section - return nil, fmt.Errorf("%w %q: kernel version has dot(s) followed by non-digit in version section", errInvalidKernelVersion, kverStr) - } - if ch != '.' { - break - } - kver = append(kver, 0) - } - } - if len(kver) < 2 { - return nil, fmt.Errorf("%w %q: kernel versions must contain at least two components", errInvalidKernelVersion, kverStr) - } - return kver, nil -} - -// getKernelVersion gets the current kernel version. -var getKernelVersion = gocompat.SyncOnceValues(func() (KernelVersion, error) { - var uts unix.Utsname - if err := unix.Uname(&uts); err != nil { - return nil, err - } - // Remove the \x00 from the release. - release := uts.Release[:] - return parseKernelVersion(string(release[:bytes.IndexByte(release, 0)])) -}) - -// GreaterEqualThan returns true if the the host kernel version is greater than -// or equal to the provided [KernelVersion]. When doing this comparison, any -// non-numerical suffixes of the host kernel version are ignored. -// -// If the number of components provided is not equal to the number of numerical -// components of the host kernel version, any missing components are treated as -// 0. This means that GreaterEqualThan(KernelVersion{4}) will be treated the -// same as GreaterEqualThan(KernelVersion{4, 0, 0, ..., 0, 0}), and that if the -// host kernel version is "4" then GreaterEqualThan(KernelVersion{4, 1}) will -// return false (because the host version will be treated as "4.0"). -func GreaterEqualThan(wantKver KernelVersion) (bool, error) { - hostKver, err := getKernelVersion() - if err != nil { - return false, err - } - - // Pad out the kernel version lengths to match one another. - cmpLen := gocompat.Max2(len(hostKver), len(wantKver)) - hostKver = append(hostKver, make(KernelVersion, cmpLen-len(hostKver))...) - wantKver = append(wantKver, make(KernelVersion, cmpLen-len(wantKver))...) - - for i := 0; i < cmpLen; i++ { - switch gocompat.CmpCompare(hostKver[i], wantKver[i]) { - case -1: - // host < want - return false, nil - case +1: - // host > want - return true, nil - case 0: - continue - } - } - // equal version values - return true, nil -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/doc.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/doc.go deleted file mode 100644 index 4635714f626c..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/doc.go +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// Package linux returns information about what features are supported on the -// running kernel. -package linux diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/mount_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/mount_linux.go deleted file mode 100644 index b29905bff66f..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/mount_linux.go +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package linux - -import ( - "golang.org/x/sys/unix" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/kernelversion" -) - -// HasNewMountAPI returns whether the new fsopen(2) mount API is supported on -// the running kernel. -var HasNewMountAPI = gocompat.SyncOnceValue(func() bool { - // All of the pieces of the new mount API we use (fsopen, fsconfig, - // fsmount, open_tree) were added together in Linux 5.2[1,2], so we can - // just check for one of the syscalls and the others should also be - // available. - // - // Just try to use open_tree(2) to open a file without OPEN_TREE_CLONE. - // This is equivalent to openat(2), but tells us if open_tree is - // available (and thus all of the other basic new mount API syscalls). - // open_tree(2) is most light-weight syscall to test here. - // - // [1]: merge commit 400913252d09 - // [2]: - fd, err := unix.OpenTree(-int(unix.EBADF), "/", unix.OPEN_TREE_CLOEXEC) - if err != nil { - return false - } - _ = unix.Close(fd) - - // RHEL 8 has a backport of fsopen(2) that appears to have some very - // difficult to debug performance pathology. As such, it seems prudent to - // simply reject pre-5.2 kernels. - isNotBackport, _ := kernelversion.GreaterEqualThan(kernelversion.KernelVersion{5, 2}) - return isNotBackport -}) diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/openat2_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/openat2_linux.go deleted file mode 100644 index dc5f65cef7f1..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/openat2_linux.go +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package linux - -import ( - "golang.org/x/sys/unix" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat" -) - -// sawOpenat2Error stores whether we have seen an error from HasOpenat2. This -// is a one-way toggle, so as soon as we see an error we "lock" into that mode. -// We cannot use sync.OnceValue to store the success/fail state once because it -// is possible for the program we are running in to apply a seccomp-bpf filter -// and thus disable openat2 during execution. -var sawOpenat2Error gocompat.Bool - -// HasOpenat2 returns whether openat2(2) is supported on the running kernel. -var HasOpenat2 = func() bool { - if sawOpenat2Error.Load() { - return false - } - - fd, err := unix.Openat2(unix.AT_FDCWD, ".", &unix.OpenHow{ - Flags: unix.O_PATH | unix.O_CLOEXEC, - Resolve: unix.RESOLVE_NO_SYMLINKS | unix.RESOLVE_IN_ROOT, - }) - if err != nil { - sawOpenat2Error.Store(true) // doesn't matter if we race here - return false - } - _ = unix.Close(fd) - return true -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs/procfs_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs/procfs_linux.go deleted file mode 100644 index 21e0a62e8eca..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs/procfs_linux.go +++ /dev/null @@ -1,544 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// Package procfs provides a safe API for operating on /proc on Linux. Note -// that this is the *internal* procfs API, mainy needed due to Go's -// restrictions on cyclic dependencies and its incredibly minimal visibility -// system without making a separate internal/ package. -package procfs - -import ( - "errors" - "fmt" - "io" - "os" - "runtime" - "strconv" - - "golang.org/x/sys/unix" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/assert" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux" -) - -// The kernel guarantees that the root inode of a procfs mount has an -// f_type of PROC_SUPER_MAGIC and st_ino of PROC_ROOT_INO. -const ( - procSuperMagic = 0x9fa0 // PROC_SUPER_MAGIC - procRootIno = 1 // PROC_ROOT_INO -) - -// verifyProcHandle checks that the handle is from a procfs filesystem. -// Contrast this to [verifyProcRoot], which also verifies that the handle is -// the root of a procfs mount. -func verifyProcHandle(procHandle fd.Fd) error { - if statfs, err := fd.Fstatfs(procHandle); err != nil { - return err - } else if statfs.Type != procSuperMagic { - return fmt.Errorf("%w: incorrect procfs root filesystem type 0x%x", errUnsafeProcfs, statfs.Type) - } - return nil -} - -// verifyProcRoot verifies that the handle is the root of a procfs filesystem. -// Contrast this to [verifyProcHandle], which only verifies if the handle is -// some file on procfs (regardless of what file it is). -func verifyProcRoot(procRoot fd.Fd) error { - if err := verifyProcHandle(procRoot); err != nil { - return err - } - if stat, err := fd.Fstat(procRoot); err != nil { - return err - } else if stat.Ino != procRootIno { - return fmt.Errorf("%w: incorrect procfs root inode number %d", errUnsafeProcfs, stat.Ino) - } - return nil -} - -type procfsFeatures struct { - // hasSubsetPid was added in Linux 5.8, along with hidepid=ptraceable (and - // string-based hidepid= values). Before this patchset, it was not really - // safe to try to modify procfs superblock flags because the superblock was - // shared -- so if this feature is not available, **you should not set any - // superblock flags**. - // - // 6814ef2d992a ("proc: add option to mount only a pids subset") - // fa10fed30f25 ("proc: allow to mount many instances of proc in one pid namespace") - // 24a71ce5c47f ("proc: instantiate only pids that we can ptrace on 'hidepid=4' mount option") - // 1c6c4d112e81 ("proc: use human-readable values for hidepid") - // 9ff7258575d5 ("Merge branch 'proc-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace") - hasSubsetPid bool -} - -var getProcfsFeatures = gocompat.SyncOnceValue(func() procfsFeatures { - if !linux.HasNewMountAPI() { - return procfsFeatures{} - } - procfsCtx, err := fd.Fsopen("proc", unix.FSOPEN_CLOEXEC) - if err != nil { - return procfsFeatures{} - } - defer procfsCtx.Close() //nolint:errcheck // close failures aren't critical here - - return procfsFeatures{ - hasSubsetPid: unix.FsconfigSetString(int(procfsCtx.Fd()), "subset", "pid") == nil, - } -}) - -func newPrivateProcMount(subset bool) (_ *Handle, Err error) { - procfsCtx, err := fd.Fsopen("proc", unix.FSOPEN_CLOEXEC) - if err != nil { - return nil, err - } - defer procfsCtx.Close() //nolint:errcheck // close failures aren't critical here - - if subset && getProcfsFeatures().hasSubsetPid { - // Try to configure hidepid=ptraceable,subset=pid if possible, but - // ignore errors. - _ = unix.FsconfigSetString(int(procfsCtx.Fd()), "hidepid", "ptraceable") - _ = unix.FsconfigSetString(int(procfsCtx.Fd()), "subset", "pid") - } - - // Get an actual handle. - if err := unix.FsconfigCreate(int(procfsCtx.Fd())); err != nil { - return nil, os.NewSyscallError("fsconfig create procfs", err) - } - // TODO: Output any information from the fscontext log to debug logs. - procRoot, err := fd.Fsmount(procfsCtx, unix.FSMOUNT_CLOEXEC, unix.MS_NODEV|unix.MS_NOEXEC|unix.MS_NOSUID) - if err != nil { - return nil, err - } - defer func() { - if Err != nil { - _ = procRoot.Close() - } - }() - return newHandle(procRoot) -} - -func clonePrivateProcMount() (_ *Handle, Err error) { - // Try to make a clone without using AT_RECURSIVE if we can. If this works, - // we can be sure there are no over-mounts and so if the root is valid then - // we're golden. Otherwise, we have to deal with over-mounts. - procRoot, err := fd.OpenTree(nil, "/proc", unix.OPEN_TREE_CLONE) - if err != nil || hookForcePrivateProcRootOpenTreeAtRecursive(procRoot) { - procRoot, err = fd.OpenTree(nil, "/proc", unix.OPEN_TREE_CLONE|unix.AT_RECURSIVE) - } - if err != nil { - return nil, fmt.Errorf("creating a detached procfs clone: %w", err) - } - defer func() { - if Err != nil { - _ = procRoot.Close() - } - }() - return newHandle(procRoot) -} - -func privateProcRoot(subset bool) (*Handle, error) { - if !linux.HasNewMountAPI() || hookForceGetProcRootUnsafe() { - return nil, fmt.Errorf("new mount api: %w", unix.ENOTSUP) - } - // Try to create a new procfs mount from scratch if we can. This ensures we - // can get a procfs mount even if /proc is fake (for whatever reason). - procRoot, err := newPrivateProcMount(subset) - if err != nil || hookForcePrivateProcRootOpenTree(procRoot) { - // Try to clone /proc then... - procRoot, err = clonePrivateProcMount() - } - return procRoot, err -} - -func unsafeHostProcRoot() (_ *Handle, Err error) { - procRoot, err := os.OpenFile("/proc", unix.O_PATH|unix.O_NOFOLLOW|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) - if err != nil { - return nil, err - } - defer func() { - if Err != nil { - _ = procRoot.Close() - } - }() - return newHandle(procRoot) -} - -// Handle is a wrapper around an *os.File handle to "/proc", which can be used -// to do further procfs-related operations in a safe way. -type Handle struct { - Inner fd.Fd - // Does this handle have subset=pid set? - isSubset bool -} - -func newHandle(procRoot fd.Fd) (*Handle, error) { - if err := verifyProcRoot(procRoot); err != nil { - // This is only used in methods that - _ = procRoot.Close() - return nil, err - } - proc := &Handle{Inner: procRoot} - // With subset=pid we can be sure that /proc/uptime will not exist. - if err := fd.Faccessat(proc.Inner, "uptime", unix.F_OK, unix.AT_SYMLINK_NOFOLLOW); err != nil { - proc.isSubset = errors.Is(err, os.ErrNotExist) - } - return proc, nil -} - -// Close closes the underlying file for the Handle. -func (proc *Handle) Close() error { return proc.Inner.Close() } - -var getCachedProcRoot = gocompat.SyncOnceValue(func() *Handle { - procRoot, err := getProcRoot(true) - if err != nil { - return nil // just don't cache if we see an error - } - if !procRoot.isSubset { - return nil // we only cache verified subset=pid handles - } - - // Disarm (*Handle).Close() to stop someone from accidentally closing - // the global handle. - procRoot.Inner = fd.NopCloser(procRoot.Inner) - return procRoot -}) - -// OpenProcRoot tries to open a "safer" handle to "/proc". -func OpenProcRoot() (*Handle, error) { - if proc := getCachedProcRoot(); proc != nil { - return proc, nil - } - return getProcRoot(true) -} - -// OpenUnsafeProcRoot opens a handle to "/proc" without any overmounts or -// masked paths (but also without "subset=pid"). -func OpenUnsafeProcRoot() (*Handle, error) { return getProcRoot(false) } - -func getProcRoot(subset bool) (*Handle, error) { - proc, err := privateProcRoot(subset) - if err != nil { - // Fall back to using a /proc handle if making a private mount failed. - // If we have openat2, at least we can avoid some kinds of over-mount - // attacks, but without openat2 there's not much we can do. - proc, err = unsafeHostProcRoot() - } - return proc, err -} - -var hasProcThreadSelf = gocompat.SyncOnceValue(func() bool { - return unix.Access("/proc/thread-self/", unix.F_OK) == nil -}) - -var errUnsafeProcfs = errors.New("unsafe procfs detected") - -// lookup is a very minimal wrapper around [procfsLookupInRoot] which is -// intended to be called from the external API. -func (proc *Handle) lookup(subpath string) (*os.File, error) { - handle, err := procfsLookupInRoot(proc.Inner, subpath) - if err != nil { - return nil, err - } - return handle, nil -} - -// procfsBase is an enum indicating the prefix of a subpath in operations -// involving [Handle]s. -type procfsBase string - -const ( - // ProcRoot refers to the root of the procfs (i.e., "/proc/"). - ProcRoot procfsBase = "/proc" - // ProcSelf refers to the current process' subdirectory (i.e., - // "/proc/self/"). - ProcSelf procfsBase = "/proc/self" - // ProcThreadSelf refers to the current thread's subdirectory (i.e., - // "/proc/thread-self/"). In multi-threaded programs (i.e., all Go - // programs) where one thread has a different CLONE_FS, it is possible for - // "/proc/self" to point the wrong thread and so "/proc/thread-self" may be - // necessary. Note that on pre-3.17 kernels, "/proc/thread-self" doesn't - // exist and so a fallback will be used in that case. - ProcThreadSelf procfsBase = "/proc/thread-self" - // TODO: Switch to an interface setup so we can have a more type-safe - // version of ProcPid and remove the need to worry about invalid string - // values. -) - -// prefix returns a prefix that can be used with the given [Handle]. -func (base procfsBase) prefix(proc *Handle) (string, error) { - switch base { - case ProcRoot: - return ".", nil - case ProcSelf: - return "self", nil - case ProcThreadSelf: - threadSelf := "thread-self" - if !hasProcThreadSelf() || hookForceProcSelfTask() { - // Pre-3.17 kernels don't have /proc/thread-self, so do it - // manually. - threadSelf = "self/task/" + strconv.Itoa(unix.Gettid()) - if err := fd.Faccessat(proc.Inner, threadSelf, unix.F_OK, unix.AT_SYMLINK_NOFOLLOW); err != nil || hookForceProcSelf() { - // In this case, we running in a pid namespace that doesn't - // match the /proc mount we have. This can happen inside runc. - // - // Unfortunately, there is no nice way to get the correct TID - // to use here because of the age of the kernel, so we have to - // just use /proc/self and hope that it works. - threadSelf = "self" - } - } - return threadSelf, nil - } - return "", fmt.Errorf("invalid procfs base %q", base) -} - -// ProcThreadSelfCloser is a callback that needs to be called when you are done -// operating on an [os.File] fetched using [ProcThreadSelf]. -// -// [os.File]: https://pkg.go.dev/os#File -type ProcThreadSelfCloser func() - -// open is the core lookup operation for [Handle]. It returns a handle to -// "/proc//". If the returned [ProcThreadSelfCloser] is non-nil, -// you should call it after you are done interacting with the returned handle. -// -// In general you should use prefer to use the other helpers, as they remove -// the need to interact with [procfsBase] and do not return a nil -// [ProcThreadSelfCloser] for [procfsBase] values other than [ProcThreadSelf] -// where it is necessary. -func (proc *Handle) open(base procfsBase, subpath string) (_ *os.File, closer ProcThreadSelfCloser, Err error) { - prefix, err := base.prefix(proc) - if err != nil { - return nil, nil, err - } - subpath = prefix + "/" + subpath - - switch base { - case ProcRoot: - file, err := proc.lookup(subpath) - if errors.Is(err, os.ErrNotExist) { - // The Handle handle in use might be a subset=pid one, which will - // result in spurious errors. In this case, just open a temporary - // unmasked procfs handle for this operation. - proc, err2 := OpenUnsafeProcRoot() // !subset=pid - if err2 != nil { - return nil, nil, err - } - defer proc.Close() //nolint:errcheck // close failures aren't critical here - - file, err = proc.lookup(subpath) - } - return file, nil, err - - case ProcSelf: - file, err := proc.lookup(subpath) - return file, nil, err - - case ProcThreadSelf: - // We need to lock our thread until the caller is done with the handle - // because between getting the handle and using it we could get - // interrupted by the Go runtime and hit the case where the underlying - // thread is swapped out and the original thread is killed, resulting - // in pull-your-hair-out-hard-to-debug issues in the caller. - runtime.LockOSThread() - defer func() { - if Err != nil { - runtime.UnlockOSThread() - closer = nil - } - }() - - file, err := proc.lookup(subpath) - return file, runtime.UnlockOSThread, err - } - // should never be reached - return nil, nil, fmt.Errorf("[internal error] invalid procfs base %q", base) -} - -// OpenThreadSelf returns a handle to "/proc/thread-self/" (or an -// equivalent handle on older kernels where "/proc/thread-self" doesn't exist). -// Once finished with the handle, you must call the returned closer function -// (runtime.UnlockOSThread). You must not pass the returned *os.File to other -// Go threads or use the handle after calling the closer. -func (proc *Handle) OpenThreadSelf(subpath string) (_ *os.File, _ ProcThreadSelfCloser, Err error) { - return proc.open(ProcThreadSelf, subpath) -} - -// OpenSelf returns a handle to /proc/self/. -func (proc *Handle) OpenSelf(subpath string) (*os.File, error) { - file, closer, err := proc.open(ProcSelf, subpath) - assert.Assert(closer == nil, "closer for ProcSelf must be nil") - return file, err -} - -// OpenRoot returns a handle to /proc/. -func (proc *Handle) OpenRoot(subpath string) (*os.File, error) { - file, closer, err := proc.open(ProcRoot, subpath) - assert.Assert(closer == nil, "closer for ProcRoot must be nil") - return file, err -} - -// OpenPid returns a handle to /proc/$pid/ (pid can be a pid or tid). -// This is mainly intended for usage when operating on other processes. -func (proc *Handle) OpenPid(pid int, subpath string) (*os.File, error) { - return proc.OpenRoot(strconv.Itoa(pid) + "/" + subpath) -} - -// checkSubpathOvermount checks if the dirfd and path combination is on the -// same mount as the given root. -func checkSubpathOvermount(root, dir fd.Fd, path string) error { - // Get the mntID of our procfs handle. - expectedMountID, err := fd.GetMountID(root, "") - if err != nil { - return fmt.Errorf("get root mount id: %w", err) - } - // Get the mntID of the target magic-link. - gotMountID, err := fd.GetMountID(dir, path) - if err != nil { - return fmt.Errorf("get subpath mount id: %w", err) - } - // As long as the directory mount is alive, even with wrapping mount IDs, - // we would expect to see a different mount ID here. (Of course, if we're - // using unsafeHostProcRoot() then an attaker could change this after we - // did this check.) - if expectedMountID != gotMountID { - return fmt.Errorf("%w: subpath %s/%s has an overmount obscuring the real path (mount ids do not match %d != %d)", - errUnsafeProcfs, dir.Name(), path, expectedMountID, gotMountID) - } - return nil -} - -// Readlink performs a readlink operation on "/proc//" in a way -// that should be free from race attacks. This is most commonly used to get the -// real path of a file by looking at "/proc/self/fd/$n", with the same safety -// protections as [Open] (as well as some additional checks against -// overmounts). -func (proc *Handle) Readlink(base procfsBase, subpath string) (string, error) { - link, closer, err := proc.open(base, subpath) - if closer != nil { - defer closer() - } - if err != nil { - return "", fmt.Errorf("get safe %s/%s handle: %w", base, subpath, err) - } - defer link.Close() //nolint:errcheck // close failures aren't critical here - - // Try to detect if there is a mount on top of the magic-link. This should - // be safe in general (a mount on top of the path afterwards would not - // affect the handle itself) and will definitely be safe if we are using - // privateProcRoot() (at least since Linux 5.12[1], when anonymous mount - // namespaces were completely isolated from external mounts including mount - // propagation events). - // - // [1]: Linux commit ee2e3f50629f ("mount: fix mounting of detached mounts - // onto targets that reside on shared mounts"). - if err := checkSubpathOvermount(proc.Inner, link, ""); err != nil { - return "", fmt.Errorf("check safety of %s/%s magiclink: %w", base, subpath, err) - } - - // readlinkat implies AT_EMPTY_PATH since Linux 2.6.39. See Linux commit - // 65cfc6722361 ("readlinkat(), fchownat() and fstatat() with empty - // relative pathnames"). - return fd.Readlinkat(link, "") -} - -// ProcSelfFdReadlink gets the real path of the given file by looking at -// readlink(/proc/thread-self/fd/$n). -// -// This is just a wrapper around [Handle.Readlink]. -func ProcSelfFdReadlink(fd fd.Fd) (string, error) { - procRoot, err := OpenProcRoot() // subset=pid - if err != nil { - return "", err - } - defer procRoot.Close() //nolint:errcheck // close failures aren't critical here - - fdPath := "fd/" + strconv.Itoa(int(fd.Fd())) - return procRoot.Readlink(ProcThreadSelf, fdPath) -} - -// CheckProcSelfFdPath returns whether the given file handle matches the -// expected path. (This is inherently racy.) -func CheckProcSelfFdPath(path string, file fd.Fd) error { - if err := fd.IsDeadInode(file); err != nil { - return err - } - actualPath, err := ProcSelfFdReadlink(file) - if err != nil { - return fmt.Errorf("get path of handle: %w", err) - } - if actualPath != path { - return fmt.Errorf("%w: handle path %q doesn't match expected path %q", internal.ErrPossibleBreakout, actualPath, path) - } - return nil -} - -// ReopenFd takes an existing file descriptor and "re-opens" it through -// /proc/thread-self/fd/. This allows for O_PATH file descriptors to be -// upgraded to regular file descriptors, as well as changing the open mode of a -// regular file descriptor. Some filesystems have unique handling of open(2) -// which make this incredibly useful (such as /dev/ptmx). -func ReopenFd(handle fd.Fd, flags int) (*os.File, error) { - procRoot, err := OpenProcRoot() // subset=pid - if err != nil { - return nil, err - } - defer procRoot.Close() //nolint:errcheck // close failures aren't critical here - - // We can't operate on /proc/thread-self/fd/$n directly when doing a - // re-open, so we need to open /proc/thread-self/fd and then open a single - // final component. - procFdDir, closer, err := procRoot.OpenThreadSelf("fd/") - if err != nil { - return nil, fmt.Errorf("get safe /proc/thread-self/fd handle: %w", err) - } - defer procFdDir.Close() //nolint:errcheck // close failures aren't critical here - defer closer() - - // Try to detect if there is a mount on top of the magic-link we are about - // to open. If we are using unsafeHostProcRoot(), this could change after - // we check it (and there's nothing we can do about that) but for - // privateProcRoot() this should be guaranteed to be safe (at least since - // Linux 5.12[1], when anonymous mount namespaces were completely isolated - // from external mounts including mount propagation events). - // - // [1]: Linux commit ee2e3f50629f ("mount: fix mounting of detached mounts - // onto targets that reside on shared mounts"). - fdStr := strconv.Itoa(int(handle.Fd())) - if err := checkSubpathOvermount(procRoot.Inner, procFdDir, fdStr); err != nil { - return nil, fmt.Errorf("check safety of /proc/thread-self/fd/%s magiclink: %w", fdStr, err) - } - - flags |= unix.O_CLOEXEC - // Rather than just wrapping fd.Openat, open-code it so we can copy - // handle.Name(). - reopenFd, err := unix.Openat(int(procFdDir.Fd()), fdStr, flags, 0) - if err != nil { - return nil, fmt.Errorf("reopen fd %d: %w", handle.Fd(), err) - } - return os.NewFile(uintptr(reopenFd), handle.Name()), nil -} - -// Test hooks used in the procfs tests to verify that the fallback logic works. -// See testing_mocks_linux_test.go and procfs_linux_test.go for more details. -var ( - hookForcePrivateProcRootOpenTree = hookDummyFile - hookForcePrivateProcRootOpenTreeAtRecursive = hookDummyFile - hookForceGetProcRootUnsafe = hookDummy - - hookForceProcSelfTask = hookDummy - hookForceProcSelf = hookDummy -) - -func hookDummy() bool { return false } -func hookDummyFile(_ io.Closer) bool { return false } diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs/procfs_lookup_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs/procfs_lookup_linux.go deleted file mode 100644 index 1ad1f18eee6a..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs/procfs_lookup_linux.go +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// This code is adapted to be a minimal version of the libpathrs proc resolver -// . -// As we only need O_PATH|O_NOFOLLOW support, this is not too much to port. - -package procfs - -import ( - "fmt" - "os" - "path" - "path/filepath" - "strings" - - "golang.org/x/sys/unix" - - "github.com/cyphar/filepath-securejoin/internal/consts" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux" -) - -// procfsLookupInRoot is a stripped down version of completeLookupInRoot, -// entirely designed to support the very small set of features necessary to -// make procfs handling work. Unlike completeLookupInRoot, we always have -// O_PATH|O_NOFOLLOW behaviour for trailing symlinks. -// -// The main restrictions are: -// -// - ".." is not supported (as it requires either os.Root-style replays, -// which is more bug-prone; or procfs verification, which is not possible -// due to re-entrancy issues). -// - Absolute symlinks for the same reason (and all absolute symlinks in -// procfs are magic-links, which we want to skip anyway). -// - If statx is supported (checkSymlinkOvermount), any mount-point crossings -// (which is the main attack of concern against /proc). -// - Partial lookups are not supported, so the symlink stack is not needed. -// - Trailing slash special handling is not necessary in most cases (if we -// operating on procfs, it's usually with programmer-controlled strings -// that will then be re-opened), so we skip it since whatever re-opens it -// can deal with it. It's a creature comfort anyway. -// -// If the system supports openat2(), this is implemented using equivalent flags -// (RESOLVE_BENEATH | RESOLVE_NO_XDEV | RESOLVE_NO_MAGICLINKS). -func procfsLookupInRoot(procRoot fd.Fd, unsafePath string) (Handle *os.File, _ error) { - unsafePath = filepath.ToSlash(unsafePath) // noop - - // Make sure that an empty unsafe path still returns something sane, even - // with openat2 (which doesn't have AT_EMPTY_PATH semantics yet). - if unsafePath == "" { - unsafePath = "." - } - - // This is already checked by getProcRoot, but make sure here since the - // core security of this lookup is based on this assumption. - if err := verifyProcRoot(procRoot); err != nil { - return nil, err - } - - if linux.HasOpenat2() { - // We prefer being able to use RESOLVE_NO_XDEV if we can, to be - // absolutely sure we are operating on a clean /proc handle that - // doesn't have any cheeky overmounts that could trick us (including - // symlink mounts on top of /proc/thread-self). RESOLVE_BENEATH isn't - // strictly needed, but just use it since we have it. - // - // NOTE: /proc/self is technically a magic-link (the contents of the - // symlink are generated dynamically), but it doesn't use - // nd_jump_link() so RESOLVE_NO_MAGICLINKS allows it. - // - // TODO: It would be nice to have RESOLVE_NO_DOTDOT, purely for - // self-consistency with the backup O_PATH resolver. - handle, err := fd.Openat2(procRoot, unsafePath, &unix.OpenHow{ - Flags: unix.O_PATH | unix.O_NOFOLLOW | unix.O_CLOEXEC, - Resolve: unix.RESOLVE_BENEATH | unix.RESOLVE_NO_XDEV | unix.RESOLVE_NO_MAGICLINKS, - }) - if err != nil { - // TODO: Once we bump the minimum Go version to 1.20, we can use - // multiple %w verbs for this wrapping. For now we need to use a - // compatibility shim for older Go versions. - // err = fmt.Errorf("%w: %w", errUnsafeProcfs, err) - return nil, gocompat.WrapBaseError(err, errUnsafeProcfs) - } - return handle, nil - } - - // To mirror openat2(RESOLVE_BENEATH), we need to return an error if the - // path is absolute. - if path.IsAbs(unsafePath) { - return nil, fmt.Errorf("%w: cannot resolve absolute paths in procfs resolver", internal.ErrPossibleBreakout) - } - - currentDir, err := fd.Dup(procRoot) - if err != nil { - return nil, fmt.Errorf("clone root fd: %w", err) - } - defer func() { - // If a handle is not returned, close the internal handle. - if Handle == nil { - _ = currentDir.Close() - } - }() - - var ( - linksWalked int - currentPath string - remainingPath = unsafePath - ) - for remainingPath != "" { - // Get the next path component. - var part string - if i := strings.IndexByte(remainingPath, '/'); i == -1 { - part, remainingPath = remainingPath, "" - } else { - part, remainingPath = remainingPath[:i], remainingPath[i+1:] - } - if part == "" { - // no-op component, but treat it the same as "." - part = "." - } - if part == ".." { - // not permitted - return nil, fmt.Errorf("%w: cannot walk into '..' in procfs resolver", internal.ErrPossibleBreakout) - } - - // Apply the component lexically to the path we are building. - // currentPath does not contain any symlinks, and we are lexically - // dealing with a single component, so it's okay to do a filepath.Clean - // here. (Not to mention that ".." isn't allowed.) - nextPath := path.Join("/", currentPath, part) - // If we logically hit the root, just clone the root rather than - // opening the part and doing all of the other checks. - if nextPath == "/" { - // Jump to root. - rootClone, err := fd.Dup(procRoot) - if err != nil { - return nil, fmt.Errorf("clone root fd: %w", err) - } - _ = currentDir.Close() - currentDir = rootClone - currentPath = nextPath - continue - } - - // Try to open the next component. - nextDir, err := fd.Openat(currentDir, part, unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) - if err != nil { - return nil, err - } - - // Make sure we are still on procfs and haven't crossed mounts. - if err := verifyProcHandle(nextDir); err != nil { - _ = nextDir.Close() - return nil, fmt.Errorf("check %q component is on procfs: %w", part, err) - } - if err := checkSubpathOvermount(procRoot, nextDir, ""); err != nil { - _ = nextDir.Close() - return nil, fmt.Errorf("check %q component is not overmounted: %w", part, err) - } - - // We are emulating O_PATH|O_NOFOLLOW, so we only need to traverse into - // trailing symlinks if we are not the final component. Otherwise we - // can just return the currentDir. - if remainingPath != "" { - st, err := nextDir.Stat() - if err != nil { - _ = nextDir.Close() - return nil, fmt.Errorf("stat component %q: %w", part, err) - } - - if st.Mode()&os.ModeType == os.ModeSymlink { - // readlinkat implies AT_EMPTY_PATH since Linux 2.6.39. See - // Linux commit 65cfc6722361 ("readlinkat(), fchownat() and - // fstatat() with empty relative pathnames"). - linkDest, err := fd.Readlinkat(nextDir, "") - // We don't need the handle anymore. - _ = nextDir.Close() - if err != nil { - return nil, err - } - - linksWalked++ - if linksWalked > consts.MaxSymlinkLimit { - return nil, &os.PathError{Op: "securejoin.procfsLookupInRoot", Path: "/proc/" + unsafePath, Err: unix.ELOOP} - } - - // Update our logical remaining path. - remainingPath = linkDest + "/" + remainingPath - // Absolute symlinks are probably magiclinks, we reject them. - if path.IsAbs(linkDest) { - return nil, fmt.Errorf("%w: cannot jump to / in procfs resolver -- possible magiclink", internal.ErrPossibleBreakout) - } - continue - } - } - - // Walk into the next component. - _ = currentDir.Close() - currentDir = nextDir - currentPath = nextPath - } - - // One final sanity-check. - if err := verifyProcHandle(currentDir); err != nil { - return nil, fmt.Errorf("check final handle is on procfs: %w", err) - } - if err := checkSubpathOvermount(procRoot, currentDir, ""); err != nil { - return nil, fmt.Errorf("check final handle is not overmounted: %w", err) - } - return currentDir, nil -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir.go deleted file mode 100644 index b43169564af4..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir.go +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package pathrs - -import ( - "os" - - "golang.org/x/sys/unix" -) - -// MkdirAll is a race-safe alternative to the [os.MkdirAll] function, -// where the new directory is guaranteed to be within the root directory (if an -// attacker can move directories from inside the root to outside the root, the -// created directory tree might be outside of the root but the key constraint -// is that at no point will we walk outside of the directory tree we are -// creating). -// -// Effectively, MkdirAll(root, unsafePath, mode) is equivalent to -// -// path, _ := securejoin.SecureJoin(root, unsafePath) -// err := os.MkdirAll(path, mode) -// -// But is much safer. The above implementation is unsafe because if an attacker -// can modify the filesystem tree between [SecureJoin] and [os.MkdirAll], it is -// possible for MkdirAll to resolve unsafe symlink components and create -// directories outside of the root. -// -// If you plan to open the directory after you have created it or want to use -// an open directory handle as the root, you should use [MkdirAllHandle] instead. -// This function is a wrapper around [MkdirAllHandle]. -// -// [SecureJoin]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin#SecureJoin -func MkdirAll(root, unsafePath string, mode os.FileMode) error { - rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) - if err != nil { - return err - } - defer rootDir.Close() //nolint:errcheck // close failures aren't critical here - - f, err := MkdirAllHandle(rootDir, unsafePath, mode) - if err != nil { - return err - } - _ = f.Close() - return nil -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_libpathrs.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_libpathrs.go deleted file mode 100644 index f864dbc8f383..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_libpathrs.go +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build libpathrs - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package pathrs - -import ( - "os" - - "cyphar.com/go-pathrs" -) - -// MkdirAllHandle is equivalent to [MkdirAll], except that it is safer to use -// in two respects: -// -// - The caller provides the root directory as an *[os.File] (preferably O_PATH) -// handle. This means that the caller can be sure which root directory is -// being used. Note that this can be emulated by using /proc/self/fd/... as -// the root path with [os.MkdirAll]. -// -// - Once all of the directories have been created, an *[os.File] O_PATH handle -// to the directory at unsafePath is returned to the caller. This is done in -// an effectively-race-free way (an attacker would only be able to swap the -// final directory component), which is not possible to emulate with -// [MkdirAll]. -// -// In addition, the returned handle is obtained far more efficiently than doing -// a brand new lookup of unsafePath (such as with [SecureJoin] or openat2) after -// doing [MkdirAll]. If you intend to open the directory after creating it, you -// should use MkdirAllHandle. -// -// [SecureJoin]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin#SecureJoin -func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (*os.File, error) { - rootRef, err := pathrs.RootFromFile(root) - if err != nil { - return nil, err - } - defer rootRef.Close() //nolint:errcheck // close failures aren't critical here - - handle, err := rootRef.MkdirAll(unsafePath, mode) - if err != nil { - return nil, err - } - return handle.IntoFile(), nil -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_purego.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_purego.go deleted file mode 100644 index 0369dfe7e664..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/mkdir_purego.go +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux && !libpathrs - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package pathrs - -import ( - "os" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs" -) - -// MkdirAllHandle is equivalent to [MkdirAll], except that it is safer to use -// in two respects: -// -// - The caller provides the root directory as an *[os.File] (preferably O_PATH) -// handle. This means that the caller can be sure which root directory is -// being used. Note that this can be emulated by using /proc/self/fd/... as -// the root path with [os.MkdirAll]. -// -// - Once all of the directories have been created, an *[os.File] O_PATH handle -// to the directory at unsafePath is returned to the caller. This is done in -// an effectively-race-free way (an attacker would only be able to swap the -// final directory component), which is not possible to emulate with -// [MkdirAll]. -// -// In addition, the returned handle is obtained far more efficiently than doing -// a brand new lookup of unsafePath (such as with [SecureJoin] or openat2) after -// doing [MkdirAll]. If you intend to open the directory after creating it, you -// should use MkdirAllHandle. -// -// [SecureJoin]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin#SecureJoin -func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (*os.File, error) { - return gopathrs.MkdirAllHandle(root, unsafePath, mode) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open.go deleted file mode 100644 index 41b628907e17..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open.go +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package pathrs - -import ( - "os" - - "golang.org/x/sys/unix" -) - -// OpenInRoot safely opens the provided unsafePath within the root. -// Effectively, OpenInRoot(root, unsafePath) is equivalent to -// -// path, _ := securejoin.SecureJoin(root, unsafePath) -// handle, err := os.OpenFile(path, unix.O_PATH|unix.O_CLOEXEC) -// -// But is much safer. The above implementation is unsafe because if an attacker -// can modify the filesystem tree between [SecureJoin] and [os.OpenFile], it is -// possible for the returned file to be outside of the root. -// -// Note that the returned handle is an O_PATH handle, meaning that only a very -// limited set of operations will work on the handle. This is done to avoid -// accidentally opening an untrusted file that could cause issues (such as a -// disconnected TTY that could cause a DoS, or some other issue). In order to -// use the returned handle, you can "upgrade" it to a proper handle using -// [Reopen]. -// -// [SecureJoin]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin#SecureJoin -func OpenInRoot(root, unsafePath string) (*os.File, error) { - rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) - if err != nil { - return nil, err - } - defer rootDir.Close() //nolint:errcheck // close failures aren't critical here - return OpenatInRoot(rootDir, unsafePath) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_libpathrs.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_libpathrs.go deleted file mode 100644 index 53352000e61c..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_libpathrs.go +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build libpathrs - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package pathrs - -import ( - "os" - - "cyphar.com/go-pathrs" -) - -// OpenatInRoot is equivalent to [OpenInRoot], except that the root is provided -// using an *[os.File] handle, to ensure that the correct root directory is used. -func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error) { - rootRef, err := pathrs.RootFromFile(root) - if err != nil { - return nil, err - } - defer rootRef.Close() //nolint:errcheck // close failures aren't critical here - - handle, err := rootRef.Resolve(unsafePath) - if err != nil { - return nil, err - } - return handle.IntoFile(), nil -} - -// Reopen takes an *[os.File] handle and re-opens it through /proc/self/fd. -// Reopen(file, flags) is effectively equivalent to -// -// fdPath := fmt.Sprintf("/proc/self/fd/%d", file.Fd()) -// os.OpenFile(fdPath, flags|unix.O_CLOEXEC) -// -// But with some extra hardenings to ensure that we are not tricked by a -// maliciously-configured /proc mount. While this attack scenario is not -// common, in container runtimes it is possible for higher-level runtimes to be -// tricked into configuring an unsafe /proc that can be used to attack file -// operations. See [CVE-2019-19921] for more details. -// -// [CVE-2019-19921]: https://github.com/advisories/GHSA-fh74-hm69-rqjw -func Reopen(file *os.File, flags int) (*os.File, error) { - handle, err := pathrs.HandleFromFile(file) - if err != nil { - return nil, err - } - defer handle.Close() //nolint:errcheck // close failures aren't critical here - - return handle.OpenFile(flags) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_purego.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_purego.go deleted file mode 100644 index 6d1be12ce5d3..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/open_purego.go +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux && !libpathrs - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -package pathrs - -import ( - "os" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs" - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs" -) - -// OpenatInRoot is equivalent to [OpenInRoot], except that the root is provided -// using an *[os.File] handle, to ensure that the correct root directory is used. -func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error) { - return gopathrs.OpenatInRoot(root, unsafePath) -} - -// Reopen takes an *[os.File] handle and re-opens it through /proc/self/fd. -// Reopen(file, flags) is effectively equivalent to -// -// fdPath := fmt.Sprintf("/proc/self/fd/%d", file.Fd()) -// os.OpenFile(fdPath, flags|unix.O_CLOEXEC) -// -// But with some extra hardenings to ensure that we are not tricked by a -// maliciously-configured /proc mount. While this attack scenario is not -// common, in container runtimes it is possible for higher-level runtimes to be -// tricked into configuring an unsafe /proc that can be used to attack file -// operations. See [CVE-2019-19921] for more details. -// -// [CVE-2019-19921]: https://github.com/advisories/GHSA-fh74-hm69-rqjw -func Reopen(handle *os.File, flags int) (*os.File, error) { - return procfs.ReopenFd(handle, flags) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_libpathrs.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_libpathrs.go deleted file mode 100644 index 6c4df3763bb9..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_libpathrs.go +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build libpathrs - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// Package procfs provides a safe API for operating on /proc on Linux. -package procfs - -import ( - "os" - "strconv" - - "cyphar.com/go-pathrs/procfs" - "golang.org/x/sys/unix" -) - -// ProcThreadSelfCloser is a callback that needs to be called when you are done -// operating on an [os.File] fetched using [Handle.OpenThreadSelf]. -// -// [os.File]: https://pkg.go.dev/os#File -type ProcThreadSelfCloser = procfs.ThreadCloser - -// Handle is a wrapper around an *os.File handle to "/proc", which can be used -// to do further procfs-related operations in a safe way. -type Handle struct { - inner *procfs.Handle -} - -// Close close the resources associated with this [Handle]. Note that if this -// [Handle] was created with [OpenProcRoot], on some kernels the underlying -// procfs handle is cached and so this Close operation may be a no-op. However, -// you should always call Close on [Handle]s once you are done with them. -func (proc *Handle) Close() error { return proc.inner.Close() } - -// OpenProcRoot tries to open a "safer" handle to "/proc" (i.e., one with the -// "subset=pid" mount option applied, available from Linux 5.8). Unless you -// plan to do many [Handle.OpenRoot] operations, users should prefer to use -// this over [OpenUnsafeProcRoot] which is far more dangerous to keep open. -// -// If a safe handle cannot be opened, OpenProcRoot will fall back to opening a -// regular "/proc" handle. -// -// Note that using [Handle.OpenRoot] will still work with handles returned by -// this function. If a subpath cannot be operated on with a safe "/proc" -// handle, then [OpenUnsafeProcRoot] will be called internally and a temporary -// unsafe handle will be used. -func OpenProcRoot() (*Handle, error) { - proc, err := procfs.Open() - if err != nil { - return nil, err - } - return &Handle{inner: proc}, nil -} - -// OpenUnsafeProcRoot opens a handle to "/proc" without any overmounts or -// masked paths. You must be extremely careful to make sure this handle is -// never leaked to a container and that you program cannot be tricked into -// writing to arbitrary paths within it. -// -// This is not necessary if you just wish to use [Handle.OpenRoot], as handles -// returned by [OpenProcRoot] will fall back to using a *temporary* unsafe -// handle in that case. You should only really use this if you need to do many -// operations with [Handle.OpenRoot] and the performance overhead of making -// many procfs handles is an issue. If you do use OpenUnsafeProcRoot, you -// should make sure to close the handle as soon as possible to avoid -// known-fd-number attacks. -func OpenUnsafeProcRoot() (*Handle, error) { - proc, err := procfs.Open(procfs.UnmaskedProcRoot) - if err != nil { - return nil, err - } - return &Handle{inner: proc}, nil -} - -// OpenThreadSelf returns a handle to "/proc/thread-self/" (or an -// equivalent handle on older kernels where "/proc/thread-self" doesn't exist). -// Once finished with the handle, you must call the returned closer function -// ([runtime.UnlockOSThread]). You must not pass the returned *os.File to other -// Go threads or use the handle after calling the closer. -// -// [runtime.UnlockOSThread]: https://pkg.go.dev/runtime#UnlockOSThread -func (proc *Handle) OpenThreadSelf(subpath string) (*os.File, ProcThreadSelfCloser, error) { - return proc.inner.OpenThreadSelf(subpath, unix.O_PATH|unix.O_NOFOLLOW) -} - -// OpenSelf returns a handle to /proc/self/. -// -// Note that in Go programs with non-homogenous threads, this may result in -// spurious errors. If you are monkeying around with APIs that are -// thread-specific, you probably want to use [Handle.OpenThreadSelf] instead -// which will guarantee that the handle refers to the same thread as the caller -// is executing on. -func (proc *Handle) OpenSelf(subpath string) (*os.File, error) { - return proc.inner.OpenSelf(subpath, unix.O_PATH|unix.O_NOFOLLOW) -} - -// OpenRoot returns a handle to /proc/. -// -// You should only use this when you need to operate on global procfs files -// (such as sysctls in /proc/sys). Unlike [Handle.OpenThreadSelf], -// [Handle.OpenSelf], and [Handle.OpenPid], the procfs handle used internally -// for this operation will never use "subset=pid", which makes it a more juicy -// target for [CVE-2024-21626]-style attacks (and doing something like opening -// a directory with OpenRoot effectively leaks [OpenUnsafeProcRoot] as long as -// the file descriptor is open). -// -// [CVE-2024-21626]: https://github.com/opencontainers/runc/security/advisories/GHSA-xr7r-f8xq-vfvv -func (proc *Handle) OpenRoot(subpath string) (*os.File, error) { - return proc.inner.OpenRoot(subpath, unix.O_PATH|unix.O_NOFOLLOW) -} - -// OpenPid returns a handle to /proc/$pid/ (pid can be a pid or tid). -// This is mainly intended for usage when operating on other processes. -// -// You should not use this for the current thread, as special handling is -// needed for /proc/thread-self (or /proc/self/task/) when dealing with -// goroutine scheduling -- use [Handle.OpenThreadSelf] instead. -// -// To refer to the current thread-group, you should use prefer -// [Handle.OpenSelf] to passing os.Getpid as the pid argument. -func (proc *Handle) OpenPid(pid int, subpath string) (*os.File, error) { - return proc.inner.OpenPid(pid, subpath, unix.O_PATH|unix.O_NOFOLLOW) -} - -// ProcSelfFdReadlink gets the real path of the given file by looking at -// /proc/self/fd/ with [readlink]. It is effectively just shorthand for -// something along the lines of: -// -// proc, err := procfs.OpenProcRoot() -// if err != nil { -// return err -// } -// link, err := proc.OpenThreadSelf(fmt.Sprintf("fd/%d", f.Fd())) -// if err != nil { -// return err -// } -// defer link.Close() -// var buf [4096]byte -// n, err := unix.Readlinkat(int(link.Fd()), "", buf[:]) -// if err != nil { -// return err -// } -// pathname := buf[:n] -// -// [readlink]: https://pkg.go.dev/golang.org/x/sys/unix#Readlinkat -func ProcSelfFdReadlink(f *os.File) (string, error) { - proc, err := procfs.Open() - if err != nil { - return "", err - } - defer proc.Close() //nolint:errcheck // close failures aren't critical here - - fdPath := "fd/" + strconv.Itoa(int(f.Fd())) - return proc.Readlink(procfs.ProcThreadSelf, fdPath) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_purego.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_purego.go deleted file mode 100644 index 9383002f9a9a..000000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_purego.go +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -//go:build linux && !libpathrs - -// Copyright (C) 2024-2025 Aleksa Sarai -// Copyright (C) 2024-2025 SUSE LLC -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// Package procfs provides a safe API for operating on /proc on Linux. -package procfs - -import ( - "os" - - "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs" -) - -// This package mostly just wraps internal/procfs APIs. This is necessary -// because we are forced to export some things from internal/procfs in order to -// avoid some dependency cycle issues, but we don't want users to see or use -// them. - -// ProcThreadSelfCloser is a callback that needs to be called when you are done -// operating on an [os.File] fetched using [Handle.OpenThreadSelf]. -// -// [os.File]: https://pkg.go.dev/os#File -type ProcThreadSelfCloser = procfs.ProcThreadSelfCloser - -// Handle is a wrapper around an *os.File handle to "/proc", which can be used -// to do further procfs-related operations in a safe way. -type Handle struct { - inner *procfs.Handle -} - -// Close close the resources associated with this [Handle]. Note that if this -// [Handle] was created with [OpenProcRoot], on some kernels the underlying -// procfs handle is cached and so this Close operation may be a no-op. However, -// you should always call Close on [Handle]s once you are done with them. -func (proc *Handle) Close() error { return proc.inner.Close() } - -// OpenProcRoot tries to open a "safer" handle to "/proc" (i.e., one with the -// "subset=pid" mount option applied, available from Linux 5.8). Unless you -// plan to do many [Handle.OpenRoot] operations, users should prefer to use -// this over [OpenUnsafeProcRoot] which is far more dangerous to keep open. -// -// If a safe handle cannot be opened, OpenProcRoot will fall back to opening a -// regular "/proc" handle. -// -// Note that using [Handle.OpenRoot] will still work with handles returned by -// this function. If a subpath cannot be operated on with a safe "/proc" -// handle, then [OpenUnsafeProcRoot] will be called internally and a temporary -// unsafe handle will be used. -func OpenProcRoot() (*Handle, error) { - proc, err := procfs.OpenProcRoot() - if err != nil { - return nil, err - } - return &Handle{inner: proc}, nil -} - -// OpenUnsafeProcRoot opens a handle to "/proc" without any overmounts or -// masked paths. You must be extremely careful to make sure this handle is -// never leaked to a container and that you program cannot be tricked into -// writing to arbitrary paths within it. -// -// This is not necessary if you just wish to use [Handle.OpenRoot], as handles -// returned by [OpenProcRoot] will fall back to using a *temporary* unsafe -// handle in that case. You should only really use this if you need to do many -// operations with [Handle.OpenRoot] and the performance overhead of making -// many procfs handles is an issue. If you do use OpenUnsafeProcRoot, you -// should make sure to close the handle as soon as possible to avoid -// known-fd-number attacks. -func OpenUnsafeProcRoot() (*Handle, error) { - proc, err := procfs.OpenUnsafeProcRoot() - if err != nil { - return nil, err - } - return &Handle{inner: proc}, nil -} - -// OpenThreadSelf returns a handle to "/proc/thread-self/" (or an -// equivalent handle on older kernels where "/proc/thread-self" doesn't exist). -// Once finished with the handle, you must call the returned closer function -// ([runtime.UnlockOSThread]). You must not pass the returned *os.File to other -// Go threads or use the handle after calling the closer. -// -// [runtime.UnlockOSThread]: https://pkg.go.dev/runtime#UnlockOSThread -func (proc *Handle) OpenThreadSelf(subpath string) (*os.File, ProcThreadSelfCloser, error) { - return proc.inner.OpenThreadSelf(subpath) -} - -// OpenSelf returns a handle to /proc/self/. -// -// Note that in Go programs with non-homogenous threads, this may result in -// spurious errors. If you are monkeying around with APIs that are -// thread-specific, you probably want to use [Handle.OpenThreadSelf] instead -// which will guarantee that the handle refers to the same thread as the caller -// is executing on. -func (proc *Handle) OpenSelf(subpath string) (*os.File, error) { - return proc.inner.OpenSelf(subpath) -} - -// OpenRoot returns a handle to /proc/. -// -// You should only use this when you need to operate on global procfs files -// (such as sysctls in /proc/sys). Unlike [Handle.OpenThreadSelf], -// [Handle.OpenSelf], and [Handle.OpenPid], the procfs handle used internally -// for this operation will never use "subset=pid", which makes it a more juicy -// target for [CVE-2024-21626]-style attacks (and doing something like opening -// a directory with OpenRoot effectively leaks [OpenUnsafeProcRoot] as long as -// the file descriptor is open). -// -// [CVE-2024-21626]: https://github.com/opencontainers/runc/security/advisories/GHSA-xr7r-f8xq-vfvv -func (proc *Handle) OpenRoot(subpath string) (*os.File, error) { - return proc.inner.OpenRoot(subpath) -} - -// OpenPid returns a handle to /proc/$pid/ (pid can be a pid or tid). -// This is mainly intended for usage when operating on other processes. -// -// You should not use this for the current thread, as special handling is -// needed for /proc/thread-self (or /proc/self/task/) when dealing with -// goroutine scheduling -- use [Handle.OpenThreadSelf] instead. -// -// To refer to the current thread-group, you should use prefer -// [Handle.OpenSelf] to passing os.Getpid as the pid argument. -func (proc *Handle) OpenPid(pid int, subpath string) (*os.File, error) { - return proc.inner.OpenPid(pid, subpath) -} - -// ProcSelfFdReadlink gets the real path of the given file by looking at -// /proc/self/fd/ with [readlink]. It is effectively just shorthand for -// something along the lines of: -// -// proc, err := procfs.OpenProcRoot() -// if err != nil { -// return err -// } -// link, err := proc.OpenThreadSelf(fmt.Sprintf("fd/%d", f.Fd())) -// if err != nil { -// return err -// } -// defer link.Close() -// var buf [4096]byte -// n, err := unix.Readlinkat(int(link.Fd()), "", buf[:]) -// if err != nil { -// return err -// } -// pathname := buf[:n] -// -// [readlink]: https://pkg.go.dev/golang.org/x/sys/unix#Readlinkat -func ProcSelfFdReadlink(f *os.File) (string, error) { - return procfs.ProcSelfFdReadlink(f) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go b/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go new file mode 100644 index 000000000000..809a579cbdbb --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go @@ -0,0 +1,452 @@ +//go:build linux + +// Copyright (C) 2024 SUSE LLC. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package securejoin + +import ( + "errors" + "fmt" + "os" + "runtime" + "strconv" + + "golang.org/x/sys/unix" +) + +func fstat(f *os.File) (unix.Stat_t, error) { + var stat unix.Stat_t + if err := unix.Fstat(int(f.Fd()), &stat); err != nil { + return stat, &os.PathError{Op: "fstat", Path: f.Name(), Err: err} + } + return stat, nil +} + +func fstatfs(f *os.File) (unix.Statfs_t, error) { + var statfs unix.Statfs_t + if err := unix.Fstatfs(int(f.Fd()), &statfs); err != nil { + return statfs, &os.PathError{Op: "fstatfs", Path: f.Name(), Err: err} + } + return statfs, nil +} + +// The kernel guarantees that the root inode of a procfs mount has an +// f_type of PROC_SUPER_MAGIC and st_ino of PROC_ROOT_INO. +const ( + procSuperMagic = 0x9fa0 // PROC_SUPER_MAGIC + procRootIno = 1 // PROC_ROOT_INO +) + +func verifyProcRoot(procRoot *os.File) error { + if statfs, err := fstatfs(procRoot); err != nil { + return err + } else if statfs.Type != procSuperMagic { + return fmt.Errorf("%w: incorrect procfs root filesystem type 0x%x", errUnsafeProcfs, statfs.Type) + } + if stat, err := fstat(procRoot); err != nil { + return err + } else if stat.Ino != procRootIno { + return fmt.Errorf("%w: incorrect procfs root inode number %d", errUnsafeProcfs, stat.Ino) + } + return nil +} + +var hasNewMountApi = sync_OnceValue(func() bool { + // All of the pieces of the new mount API we use (fsopen, fsconfig, + // fsmount, open_tree) were added together in Linux 5.1[1,2], so we can + // just check for one of the syscalls and the others should also be + // available. + // + // Just try to use open_tree(2) to open a file without OPEN_TREE_CLONE. + // This is equivalent to openat(2), but tells us if open_tree is + // available (and thus all of the other basic new mount API syscalls). + // open_tree(2) is most light-weight syscall to test here. + // + // [1]: merge commit 400913252d09 + // [2]: + fd, err := unix.OpenTree(-int(unix.EBADF), "/", unix.OPEN_TREE_CLOEXEC) + if err != nil { + return false + } + _ = unix.Close(fd) + return true +}) + +func fsopen(fsName string, flags int) (*os.File, error) { + // Make sure we always set O_CLOEXEC. + flags |= unix.FSOPEN_CLOEXEC + fd, err := unix.Fsopen(fsName, flags) + if err != nil { + return nil, os.NewSyscallError("fsopen "+fsName, err) + } + return os.NewFile(uintptr(fd), "fscontext:"+fsName), nil +} + +func fsmount(ctx *os.File, flags, mountAttrs int) (*os.File, error) { + // Make sure we always set O_CLOEXEC. + flags |= unix.FSMOUNT_CLOEXEC + fd, err := unix.Fsmount(int(ctx.Fd()), flags, mountAttrs) + if err != nil { + return nil, os.NewSyscallError("fsmount "+ctx.Name(), err) + } + return os.NewFile(uintptr(fd), "fsmount:"+ctx.Name()), nil +} + +func newPrivateProcMount() (*os.File, error) { + procfsCtx, err := fsopen("proc", unix.FSOPEN_CLOEXEC) + if err != nil { + return nil, err + } + defer procfsCtx.Close() + + // Try to configure hidepid=ptraceable,subset=pid if possible, but ignore errors. + _ = unix.FsconfigSetString(int(procfsCtx.Fd()), "hidepid", "ptraceable") + _ = unix.FsconfigSetString(int(procfsCtx.Fd()), "subset", "pid") + + // Get an actual handle. + if err := unix.FsconfigCreate(int(procfsCtx.Fd())); err != nil { + return nil, os.NewSyscallError("fsconfig create procfs", err) + } + return fsmount(procfsCtx, unix.FSMOUNT_CLOEXEC, unix.MS_RDONLY|unix.MS_NODEV|unix.MS_NOEXEC|unix.MS_NOSUID) +} + +func openTree(dir *os.File, path string, flags uint) (*os.File, error) { + dirFd := -int(unix.EBADF) + dirName := "." + if dir != nil { + dirFd = int(dir.Fd()) + dirName = dir.Name() + } + // Make sure we always set O_CLOEXEC. + flags |= unix.OPEN_TREE_CLOEXEC + fd, err := unix.OpenTree(dirFd, path, flags) + if err != nil { + return nil, &os.PathError{Op: "open_tree", Path: path, Err: err} + } + return os.NewFile(uintptr(fd), dirName+"/"+path), nil +} + +func clonePrivateProcMount() (_ *os.File, Err error) { + // Try to make a clone without using AT_RECURSIVE if we can. If this works, + // we can be sure there are no over-mounts and so if the root is valid then + // we're golden. Otherwise, we have to deal with over-mounts. + procfsHandle, err := openTree(nil, "/proc", unix.OPEN_TREE_CLONE) + if err != nil || hookForcePrivateProcRootOpenTreeAtRecursive(procfsHandle) { + procfsHandle, err = openTree(nil, "/proc", unix.OPEN_TREE_CLONE|unix.AT_RECURSIVE) + } + if err != nil { + return nil, fmt.Errorf("creating a detached procfs clone: %w", err) + } + defer func() { + if Err != nil { + _ = procfsHandle.Close() + } + }() + if err := verifyProcRoot(procfsHandle); err != nil { + return nil, err + } + return procfsHandle, nil +} + +func privateProcRoot() (*os.File, error) { + if !hasNewMountApi() || hookForceGetProcRootUnsafe() { + return nil, fmt.Errorf("new mount api: %w", unix.ENOTSUP) + } + // Try to create a new procfs mount from scratch if we can. This ensures we + // can get a procfs mount even if /proc is fake (for whatever reason). + procRoot, err := newPrivateProcMount() + if err != nil || hookForcePrivateProcRootOpenTree(procRoot) { + // Try to clone /proc then... + procRoot, err = clonePrivateProcMount() + } + return procRoot, err +} + +func unsafeHostProcRoot() (_ *os.File, Err error) { + procRoot, err := os.OpenFile("/proc", unix.O_PATH|unix.O_NOFOLLOW|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) + if err != nil { + return nil, err + } + defer func() { + if Err != nil { + _ = procRoot.Close() + } + }() + if err := verifyProcRoot(procRoot); err != nil { + return nil, err + } + return procRoot, nil +} + +func doGetProcRoot() (*os.File, error) { + procRoot, err := privateProcRoot() + if err != nil { + // Fall back to using a /proc handle if making a private mount failed. + // If we have openat2, at least we can avoid some kinds of over-mount + // attacks, but without openat2 there's not much we can do. + procRoot, err = unsafeHostProcRoot() + } + return procRoot, err +} + +var getProcRoot = sync_OnceValues(func() (*os.File, error) { + return doGetProcRoot() +}) + +var hasProcThreadSelf = sync_OnceValue(func() bool { + return unix.Access("/proc/thread-self/", unix.F_OK) == nil +}) + +var errUnsafeProcfs = errors.New("unsafe procfs detected") + +type procThreadSelfCloser func() + +// procThreadSelf returns a handle to /proc/thread-self/ (or an +// equivalent handle on older kernels where /proc/thread-self doesn't exist). +// Once finished with the handle, you must call the returned closer function +// (runtime.UnlockOSThread). You must not pass the returned *os.File to other +// Go threads or use the handle after calling the closer. +// +// This is similar to ProcThreadSelf from runc, but with extra hardening +// applied and using *os.File. +func procThreadSelf(procRoot *os.File, subpath string) (_ *os.File, _ procThreadSelfCloser, Err error) { + // We need to lock our thread until the caller is done with the handle + // because between getting the handle and using it we could get interrupted + // by the Go runtime and hit the case where the underlying thread is + // swapped out and the original thread is killed, resulting in + // pull-your-hair-out-hard-to-debug issues in the caller. + runtime.LockOSThread() + defer func() { + if Err != nil { + runtime.UnlockOSThread() + } + }() + + // Figure out what prefix we want to use. + threadSelf := "thread-self/" + if !hasProcThreadSelf() || hookForceProcSelfTask() { + /// Pre-3.17 kernels don't have /proc/thread-self, so do it manually. + threadSelf = "self/task/" + strconv.Itoa(unix.Gettid()) + "/" + if _, err := fstatatFile(procRoot, threadSelf, unix.AT_SYMLINK_NOFOLLOW); err != nil || hookForceProcSelf() { + // In this case, we running in a pid namespace that doesn't match + // the /proc mount we have. This can happen inside runc. + // + // Unfortunately, there is no nice way to get the correct TID to + // use here because of the age of the kernel, so we have to just + // use /proc/self and hope that it works. + threadSelf = "self/" + } + } + + // Grab the handle. + var ( + handle *os.File + err error + ) + if hasOpenat2() { + // We prefer being able to use RESOLVE_NO_XDEV if we can, to be + // absolutely sure we are operating on a clean /proc handle that + // doesn't have any cheeky overmounts that could trick us (including + // symlink mounts on top of /proc/thread-self). RESOLVE_BENEATH isn't + // strictly needed, but just use it since we have it. + // + // NOTE: /proc/self is technically a magic-link (the contents of the + // symlink are generated dynamically), but it doesn't use + // nd_jump_link() so RESOLVE_NO_MAGICLINKS allows it. + // + // NOTE: We MUST NOT use RESOLVE_IN_ROOT here, as openat2File uses + // procSelfFdReadlink to clean up the returned f.Name() if we use + // RESOLVE_IN_ROOT (which would lead to an infinite recursion). + handle, err = openat2File(procRoot, threadSelf+subpath, &unix.OpenHow{ + Flags: unix.O_PATH | unix.O_NOFOLLOW | unix.O_CLOEXEC, + Resolve: unix.RESOLVE_BENEATH | unix.RESOLVE_NO_XDEV | unix.RESOLVE_NO_MAGICLINKS, + }) + if err != nil { + // TODO: Once we bump the minimum Go version to 1.20, we can use + // multiple %w verbs for this wrapping. For now we need to use a + // compatibility shim for older Go versions. + //err = fmt.Errorf("%w: %w", errUnsafeProcfs, err) + return nil, nil, wrapBaseError(err, errUnsafeProcfs) + } + } else { + handle, err = openatFile(procRoot, threadSelf+subpath, unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) + if err != nil { + // TODO: Once we bump the minimum Go version to 1.20, we can use + // multiple %w verbs for this wrapping. For now we need to use a + // compatibility shim for older Go versions. + //err = fmt.Errorf("%w: %w", errUnsafeProcfs, err) + return nil, nil, wrapBaseError(err, errUnsafeProcfs) + } + defer func() { + if Err != nil { + _ = handle.Close() + } + }() + // We can't detect bind-mounts of different parts of procfs on top of + // /proc (a-la RESOLVE_NO_XDEV), but we can at least be sure that we + // aren't on the wrong filesystem here. + if statfs, err := fstatfs(handle); err != nil { + return nil, nil, err + } else if statfs.Type != procSuperMagic { + return nil, nil, fmt.Errorf("%w: incorrect /proc/self/fd filesystem type 0x%x", errUnsafeProcfs, statfs.Type) + } + } + return handle, runtime.UnlockOSThread, nil +} + +// STATX_MNT_ID_UNIQUE is provided in golang.org/x/sys@v0.20.0, but in order to +// avoid bumping the requirement for a single constant we can just define it +// ourselves. +const STATX_MNT_ID_UNIQUE = 0x4000 + +var hasStatxMountId = sync_OnceValue(func() bool { + var ( + stx unix.Statx_t + // We don't care which mount ID we get. The kernel will give us the + // unique one if it is supported. + wantStxMask uint32 = STATX_MNT_ID_UNIQUE | unix.STATX_MNT_ID + ) + err := unix.Statx(-int(unix.EBADF), "/", 0, int(wantStxMask), &stx) + return err == nil && stx.Mask&wantStxMask != 0 +}) + +func getMountId(dir *os.File, path string) (uint64, error) { + // If we don't have statx(STATX_MNT_ID*) support, we can't do anything. + if !hasStatxMountId() { + return 0, nil + } + + var ( + stx unix.Statx_t + // We don't care which mount ID we get. The kernel will give us the + // unique one if it is supported. + wantStxMask uint32 = STATX_MNT_ID_UNIQUE | unix.STATX_MNT_ID + ) + + err := unix.Statx(int(dir.Fd()), path, unix.AT_EMPTY_PATH|unix.AT_SYMLINK_NOFOLLOW, int(wantStxMask), &stx) + if stx.Mask&wantStxMask == 0 { + // It's not a kernel limitation, for some reason we couldn't get a + // mount ID. Assume it's some kind of attack. + err = fmt.Errorf("%w: could not get mount id", errUnsafeProcfs) + } + if err != nil { + return 0, &os.PathError{Op: "statx(STATX_MNT_ID_...)", Path: dir.Name() + "/" + path, Err: err} + } + return stx.Mnt_id, nil +} + +func checkSymlinkOvermount(procRoot *os.File, dir *os.File, path string) error { + // Get the mntId of our procfs handle. + expectedMountId, err := getMountId(procRoot, "") + if err != nil { + return err + } + // Get the mntId of the target magic-link. + gotMountId, err := getMountId(dir, path) + if err != nil { + return err + } + // As long as the directory mount is alive, even with wrapping mount IDs, + // we would expect to see a different mount ID here. (Of course, if we're + // using unsafeHostProcRoot() then an attaker could change this after we + // did this check.) + if expectedMountId != gotMountId { + return fmt.Errorf("%w: symlink %s/%s has an overmount obscuring the real link (mount ids do not match %d != %d)", errUnsafeProcfs, dir.Name(), path, expectedMountId, gotMountId) + } + return nil +} + +func doRawProcSelfFdReadlink(procRoot *os.File, fd int) (string, error) { + fdPath := fmt.Sprintf("fd/%d", fd) + procFdLink, closer, err := procThreadSelf(procRoot, fdPath) + if err != nil { + return "", fmt.Errorf("get safe /proc/thread-self/%s handle: %w", fdPath, err) + } + defer procFdLink.Close() + defer closer() + + // Try to detect if there is a mount on top of the magic-link. Since we use the handle directly + // provide to the closure. If the closure uses the handle directly, this + // should be safe in general (a mount on top of the path afterwards would + // not affect the handle itself) and will definitely be safe if we are + // using privateProcRoot() (at least since Linux 5.12[1], when anonymous + // mount namespaces were completely isolated from external mounts including + // mount propagation events). + // + // [1]: Linux commit ee2e3f50629f ("mount: fix mounting of detached mounts + // onto targets that reside on shared mounts"). + if err := checkSymlinkOvermount(procRoot, procFdLink, ""); err != nil { + return "", fmt.Errorf("check safety of /proc/thread-self/fd/%d magiclink: %w", fd, err) + } + + // readlinkat implies AT_EMPTY_PATH since Linux 2.6.39. See Linux commit + // 65cfc6722361 ("readlinkat(), fchownat() and fstatat() with empty + // relative pathnames"). + return readlinkatFile(procFdLink, "") +} + +func rawProcSelfFdReadlink(fd int) (string, error) { + procRoot, err := getProcRoot() + if err != nil { + return "", err + } + return doRawProcSelfFdReadlink(procRoot, fd) +} + +func procSelfFdReadlink(f *os.File) (string, error) { + return rawProcSelfFdReadlink(int(f.Fd())) +} + +var ( + errPossibleBreakout = errors.New("possible breakout detected") + errInvalidDirectory = errors.New("wandered into deleted directory") + errDeletedInode = errors.New("cannot verify path of deleted inode") +) + +func isDeadInode(file *os.File) error { + // If the nlink of a file drops to 0, there is an attacker deleting + // directories during our walk, which could result in weird /proc values. + // It's better to error out in this case. + stat, err := fstat(file) + if err != nil { + return fmt.Errorf("check for dead inode: %w", err) + } + if stat.Nlink == 0 { + err := errDeletedInode + if stat.Mode&unix.S_IFMT == unix.S_IFDIR { + err = errInvalidDirectory + } + return fmt.Errorf("%w %q", err, file.Name()) + } + return nil +} + +func checkProcSelfFdPath(path string, file *os.File) error { + if err := isDeadInode(file); err != nil { + return err + } + actualPath, err := procSelfFdReadlink(file) + if err != nil { + return fmt.Errorf("get path of handle: %w", err) + } + if actualPath != path { + return fmt.Errorf("%w: handle path %q doesn't match expected path %q", errPossibleBreakout, actualPath, path) + } + return nil +} + +// Test hooks used in the procfs tests to verify that the fallback logic works. +// See testing_mocks_linux_test.go and procfs_linux_test.go for more details. +var ( + hookForcePrivateProcRootOpenTree = hookDummyFile + hookForcePrivateProcRootOpenTreeAtRecursive = hookDummyFile + hookForceGetProcRootUnsafe = hookDummy + + hookForceProcSelfTask = hookDummy + hookForceProcSelf = hookDummy +) + +func hookDummy() bool { return false } +func hookDummyFile(_ *os.File) bool { return false } diff --git a/vendor/github.com/cyphar/filepath-securejoin/vfs.go b/vendor/github.com/cyphar/filepath-securejoin/vfs.go index 4d89a481ca79..36373f8c5173 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/vfs.go +++ b/vendor/github.com/cyphar/filepath-securejoin/vfs.go @@ -1,5 +1,3 @@ -// SPDX-License-Identifier: BSD-3-Clause - // Copyright (C) 2017-2024 SUSE LLC. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go index 884a8b805936..07e0f77dc278 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go @@ -6,11 +6,78 @@ import ( "github.com/opencontainers/selinux/go-selinux" ) +// Deprecated: use selinux.ROFileLabel +var ROMountLabel = selinux.ROFileLabel + +// SetProcessLabel takes a process label and tells the kernel to assign the +// label to the next program executed by the current process. +// Deprecated: use selinux.SetExecLabel +var SetProcessLabel = selinux.SetExecLabel + +// ProcessLabel returns the process label that the kernel will assign +// to the next program executed by the current process. If "" is returned +// this indicates that the default labeling will happen for the process. +// Deprecated: use selinux.ExecLabel +var ProcessLabel = selinux.ExecLabel + +// SetSocketLabel takes a process label and tells the kernel to assign the +// label to the next socket that gets created +// Deprecated: use selinux.SetSocketLabel +var SetSocketLabel = selinux.SetSocketLabel + +// SocketLabel retrieves the current default socket label setting +// Deprecated: use selinux.SocketLabel +var SocketLabel = selinux.SocketLabel + +// SetKeyLabel takes a process label and tells the kernel to assign the +// label to the next kernel keyring that gets created +// Deprecated: use selinux.SetKeyLabel +var SetKeyLabel = selinux.SetKeyLabel + +// KeyLabel retrieves the current default kernel keyring label setting +// Deprecated: use selinux.KeyLabel +var KeyLabel = selinux.KeyLabel + +// FileLabel returns the label for specified path +// Deprecated: use selinux.FileLabel +var FileLabel = selinux.FileLabel + +// PidLabel will return the label of the process running with the specified pid +// Deprecated: use selinux.PidLabel +var PidLabel = selinux.PidLabel + // Init initialises the labeling system func Init() { _ = selinux.GetEnabled() } +// ClearLabels will clear all reserved labels +// Deprecated: use selinux.ClearLabels +var ClearLabels = selinux.ClearLabels + +// ReserveLabel will record the fact that the MCS label has already been used. +// This will prevent InitLabels from using the MCS label in a newly created +// container +// Deprecated: use selinux.ReserveLabel +func ReserveLabel(label string) error { + selinux.ReserveLabel(label) + return nil +} + +// ReleaseLabel will remove the reservation of the MCS label. +// This will allow InitLabels to use the MCS label in a newly created +// containers +// Deprecated: use selinux.ReleaseLabel +func ReleaseLabel(label string) error { + selinux.ReleaseLabel(label) + return nil +} + +// DupSecOpt takes a process label and returns security options that +// can be used to set duplicate labels on future container processes +// Deprecated: use selinux.DupSecOpt +var DupSecOpt = selinux.DupSecOpt + // FormatMountLabel returns a string to be used by the mount command. Using // the SELinux `context` mount option. Changing labels of files on mount // points with this option can never be changed. diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go index 95f29e21f4e8..e49e6d53f7d6 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go @@ -18,7 +18,7 @@ var validOptions = map[string]bool{ "level": true, } -var ErrIncompatibleLabel = errors.New("bad SELinux option: z and Z can not be used together") +var ErrIncompatibleLabel = errors.New("Bad SELinux option z and Z can not be used together") // InitLabels returns the process label and file labels to be used within // the container. A list of options can be passed into this function to alter @@ -52,11 +52,11 @@ func InitLabels(options []string) (plabel string, mlabel string, retErr error) { return "", selinux.PrivContainerMountLabel(), nil } if i := strings.Index(opt, ":"); i == -1 { - return "", "", fmt.Errorf("bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt) + return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt) } con := strings.SplitN(opt, ":", 2) if !validOptions[con[0]] { - return "", "", fmt.Errorf("bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0]) + return "", "", fmt.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0]) } if con[0] == "filetype" { mcon["type"] = con[1] @@ -79,6 +79,12 @@ func InitLabels(options []string) (plabel string, mlabel string, retErr error) { return processLabel, mountLabel, nil } +// Deprecated: The GenLabels function is only to be used during the transition +// to the official API. Use InitLabels(strings.Fields(options)) instead. +func GenLabels(options string) (string, string, error) { + return InitLabels(strings.Fields(options)) +} + // SetFileLabel modifies the "path" label to the specified file label func SetFileLabel(path string, fileLabel string) error { if !selinux.GetEnabled() || fileLabel == "" { @@ -117,6 +123,11 @@ func Relabel(path string, fileLabel string, shared bool) error { return selinux.Chcon(path, fileLabel, true) } +// DisableSecOpt returns a security opt that can disable labeling +// support for future container processes +// Deprecated: use selinux.DisableSecOpt +var DisableSecOpt = selinux.DisableSecOpt + // Validate checks that the label does not include unexpected options func Validate(label string) error { if strings.Contains(label, "z") && strings.Contains(label, "Z") { diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go index 7a54afc5e6d1..1c260cb27d9a 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go @@ -10,6 +10,12 @@ func InitLabels([]string) (string, string, error) { return "", "", nil } +// Deprecated: The GenLabels function is only to be used during the transition +// to the official API. Use InitLabels(strings.Fields(options)) instead. +func GenLabels(string) (string, string, error) { + return "", "", nil +} + func SetFileLabel(string, string) error { return nil } diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go index 15150d475281..af058b84b132 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go @@ -41,10 +41,6 @@ var ( // ErrVerifierNil is returned when a context verifier function is nil. ErrVerifierNil = errors.New("verifier function is nil") - // ErrNotTGLeader is returned by [SetKeyLabel] if the calling thread - // is not the thread group leader. - ErrNotTGLeader = errors.New("calling thread is not the thread group leader") - // CategoryRange allows the upper bound on the category range to be adjusted CategoryRange = DefaultCategoryRange @@ -153,7 +149,7 @@ func CalculateGlbLub(sourceRange, targetRange string) (string, error) { // of the program is finished to guarantee another goroutine does not migrate to the current // thread before execution is complete. func SetExecLabel(label string) error { - return writeConThreadSelf("attr/exec", label) + return writeCon(attrPath("exec"), label) } // SetTaskLabel sets the SELinux label for the current thread, or an error. @@ -161,7 +157,7 @@ func SetExecLabel(label string) error { // be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() to guarantee // the current thread does not run in a new mislabeled thread. func SetTaskLabel(label string) error { - return writeConThreadSelf("attr/current", label) + return writeCon(attrPath("current"), label) } // SetSocketLabel takes a process label and tells the kernel to assign the @@ -170,12 +166,12 @@ func SetTaskLabel(label string) error { // the socket is created to guarantee another goroutine does not migrate // to the current thread before execution is complete. func SetSocketLabel(label string) error { - return writeConThreadSelf("attr/sockcreate", label) + return writeCon(attrPath("sockcreate"), label) } // SocketLabel retrieves the current socket label setting func SocketLabel() (string, error) { - return readConThreadSelf("attr/sockcreate") + return readCon(attrPath("sockcreate")) } // PeerLabel retrieves the label of the client on the other side of a socket @@ -184,21 +180,17 @@ func PeerLabel(fd uintptr) (string, error) { } // SetKeyLabel takes a process label and tells the kernel to assign the -// label to the next kernel keyring that gets created. -// -// Calls to SetKeyLabel should be wrapped in -// runtime.LockOSThread()/runtime.UnlockOSThread() until the kernel keyring is -// created to guarantee another goroutine does not migrate to the current -// thread before execution is complete. -// -// Only the thread group leader can set key label. +// label to the next kernel keyring that gets created. Calls to SetKeyLabel +// should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until +// the kernel keyring is created to guarantee another goroutine does not migrate +// to the current thread before execution is complete. func SetKeyLabel(label string) error { return setKeyLabel(label) } // KeyLabel retrieves the current kernel keyring label setting func KeyLabel() (string, error) { - return keyLabel() + return readCon("/proc/self/attr/keycreate") } // Get returns the Context as a string diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go index 6d7f8e270bd7..c80c10971b97 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -17,11 +17,8 @@ import ( "strings" "sync" - "github.com/cyphar/filepath-securejoin/pathrs-lite" - "github.com/cyphar/filepath-securejoin/pathrs-lite/procfs" - "golang.org/x/sys/unix" - "github.com/opencontainers/selinux/pkg/pwalkdir" + "golang.org/x/sys/unix" ) const ( @@ -48,7 +45,7 @@ type selinuxState struct { type level struct { cats *big.Int - sens int + sens uint } type mlsRange struct { @@ -76,6 +73,10 @@ var ( mcsList: make(map[string]bool), } + // for attrPath() + attrPathOnce sync.Once + haveThreadSelf bool + // for policyRoot() policyRootOnce sync.Once policyRootVal string @@ -137,7 +138,6 @@ func verifySELinuxfsMount(mnt string) bool { return false } - //#nosec G115 -- there is no overflow here. if uint32(buf.Type) != uint32(unix.SELINUX_MAGIC) { return false } @@ -255,183 +255,48 @@ func readConfig(target string) string { return "" } -func readConFd(in *os.File) (string, error) { - data, err := io.ReadAll(in) - if err != nil { - return "", err - } - return string(bytes.TrimSuffix(data, []byte{0})), nil -} - -func writeConFd(out *os.File, val string) error { - var err error - if val != "" { - _, err = out.Write([]byte(val)) - } else { - _, err = out.Write(nil) - } - return err -} - -// openProcThreadSelf is a small wrapper around [procfs.Handle.OpenThreadSelf] -// and [pathrs.Reopen] to make "one-shot opens" slightly more ergonomic. The -// provided mode must be os.O_* flags to indicate what mode the returned file -// should be opened with (flags like os.O_CREAT and os.O_EXCL are not -// supported). -// -// If no error occurred, the returned handle is guaranteed to be exactly -// /proc/thread-self/ with no tricky mounts or symlinks causing you to -// operate on an unexpected path (with some caveats on pre-openat2 or -// pre-fsopen kernels). -func openProcThreadSelf(subpath string, mode int) (*os.File, procfs.ProcThreadSelfCloser, error) { - if subpath == "" { - return nil, nil, ErrEmptyPath - } - - proc, err := procfs.OpenProcRoot() - if err != nil { - return nil, nil, err - } - defer proc.Close() - - handle, closer, err := proc.OpenThreadSelf(subpath) - if err != nil { - return nil, nil, fmt.Errorf("open /proc/thread-self/%s handle: %w", subpath, err) - } - defer handle.Close() // we will return a re-opened handle - - file, err := pathrs.Reopen(handle, mode) - if err != nil { - closer() - return nil, nil, fmt.Errorf("reopen /proc/thread-self/%s handle (%#x): %w", subpath, mode, err) - } - return file, closer, nil -} - -// Read the contents of /proc/thread-self/. -func readConThreadSelf(fpath string) (string, error) { - in, closer, err := openProcThreadSelf(fpath, os.O_RDONLY|unix.O_CLOEXEC) - if err != nil { - return "", err - } - defer closer() - defer in.Close() - - return readConFd(in) -} +func isProcHandle(fh *os.File) error { + var buf unix.Statfs_t -// Write to /proc/thread-self/. -func writeConThreadSelf(fpath, val string) error { - if val == "" { - if !getEnabled() { - return nil + for { + err := unix.Fstatfs(int(fh.Fd()), &buf) + if err == nil { + break + } + if err != unix.EINTR { + return &os.PathError{Op: "fstatfs", Path: fh.Name(), Err: err} } } - - out, closer, err := openProcThreadSelf(fpath, os.O_WRONLY|unix.O_CLOEXEC) - if err != nil { - return err + if buf.Type != unix.PROC_SUPER_MAGIC { + return fmt.Errorf("file %q is not on procfs", fh.Name()) } - defer closer() - defer out.Close() - return writeConFd(out, val) + return nil } -// openProcSelf is a small wrapper around [procfs.Handle.OpenSelf] and -// [pathrs.Reopen] to make "one-shot opens" slightly more ergonomic. The -// provided mode must be os.O_* flags to indicate what mode the returned file -// should be opened with (flags like os.O_CREAT and os.O_EXCL are not -// supported). -// -// If no error occurred, the returned handle is guaranteed to be exactly -// /proc/self/ with no tricky mounts or symlinks causing you to -// operate on an unexpected path (with some caveats on pre-openat2 or -// pre-fsopen kernels). -func openProcSelf(subpath string, mode int) (*os.File, error) { - if subpath == "" { - return nil, ErrEmptyPath - } - - proc, err := procfs.OpenProcRoot() - if err != nil { - return nil, err - } - defer proc.Close() - - handle, err := proc.OpenSelf(subpath) - if err != nil { - return nil, fmt.Errorf("open /proc/self/%s handle: %w", subpath, err) - } - defer handle.Close() // we will return a re-opened handle - - file, err := pathrs.Reopen(handle, mode) - if err != nil { - return nil, fmt.Errorf("reopen /proc/self/%s handle (%#x): %w", subpath, mode, err) +func readCon(fpath string) (string, error) { + if fpath == "" { + return "", ErrEmptyPath } - return file, nil -} -// Read the contents of /proc/self/. -func readConSelf(fpath string) (string, error) { - in, err := openProcSelf(fpath, os.O_RDONLY|unix.O_CLOEXEC) + in, err := os.Open(fpath) if err != nil { return "", err } defer in.Close() - return readConFd(in) -} - -// Write to /proc/self/. -func writeConSelf(fpath, val string) error { - if val == "" { - if !getEnabled() { - return nil - } - } - - out, err := openProcSelf(fpath, os.O_WRONLY|unix.O_CLOEXEC) - if err != nil { - return err + if err := isProcHandle(in); err != nil { + return "", err } - defer out.Close() - - return writeConFd(out, val) + return readConFd(in) } -// openProcPid is a small wrapper around [procfs.Handle.OpenPid] and -// [pathrs.Reopen] to make "one-shot opens" slightly more ergonomic. The -// provided mode must be os.O_* flags to indicate what mode the returned file -// should be opened with (flags like os.O_CREAT and os.O_EXCL are not -// supported). -// -// If no error occurred, the returned handle is guaranteed to be exactly -// /proc/self/ with no tricky mounts or symlinks causing you to -// operate on an unexpected path (with some caveats on pre-openat2 or -// pre-fsopen kernels). -func openProcPid(pid int, subpath string, mode int) (*os.File, error) { - if subpath == "" { - return nil, ErrEmptyPath - } - - proc, err := procfs.OpenProcRoot() - if err != nil { - return nil, err - } - defer proc.Close() - - handle, err := proc.OpenPid(pid, subpath) - if err != nil { - return nil, fmt.Errorf("open /proc/%d/%s handle: %w", pid, subpath, err) - } - defer handle.Close() // we will return a re-opened handle - - file, err := pathrs.Reopen(handle, mode) +func readConFd(in *os.File) (string, error) { + data, err := io.ReadAll(in) if err != nil { - return nil, fmt.Errorf("reopen /proc/%d/%s handle (%#x): %w", pid, subpath, mode, err) + return "", err } - return file, nil + return string(bytes.TrimSuffix(data, []byte{0})), nil } // classIndex returns the int index for an object class in the loaded policy, @@ -527,34 +392,78 @@ func lFileLabel(fpath string) (string, error) { } func setFSCreateLabel(label string) error { - return writeConThreadSelf("attr/fscreate", label) + return writeCon(attrPath("fscreate"), label) } // fsCreateLabel returns the default label the kernel which the kernel is using // for file system objects created by this task. "" indicates default. func fsCreateLabel() (string, error) { - return readConThreadSelf("attr/fscreate") + return readCon(attrPath("fscreate")) } // currentLabel returns the SELinux label of the current process thread, or an error. func currentLabel() (string, error) { - return readConThreadSelf("attr/current") + return readCon(attrPath("current")) } // pidLabel returns the SELinux label of the given pid, or an error. func pidLabel(pid int) (string, error) { - it, err := openProcPid(pid, "attr/current", os.O_RDONLY|unix.O_CLOEXEC) - if err != nil { - return "", nil - } - defer it.Close() - return readConFd(it) + return readCon(fmt.Sprintf("/proc/%d/attr/current", pid)) } // ExecLabel returns the SELinux label that the kernel will use for any programs // that are executed by the current process thread, or an error. func execLabel() (string, error) { - return readConThreadSelf("exec") + return readCon(attrPath("exec")) +} + +func writeCon(fpath, val string) error { + if fpath == "" { + return ErrEmptyPath + } + if val == "" { + if !getEnabled() { + return nil + } + } + + out, err := os.OpenFile(fpath, os.O_WRONLY, 0) + if err != nil { + return err + } + defer out.Close() + + if err := isProcHandle(out); err != nil { + return err + } + + if val != "" { + _, err = out.Write([]byte(val)) + } else { + _, err = out.Write(nil) + } + if err != nil { + return err + } + return nil +} + +func attrPath(attr string) string { + // Linux >= 3.17 provides this + const threadSelfPrefix = "/proc/thread-self/attr" + + attrPathOnce.Do(func() { + st, err := os.Stat(threadSelfPrefix) + if err == nil && st.Mode().IsDir() { + haveThreadSelf = true + } + }) + + if haveThreadSelf { + return filepath.Join(threadSelfPrefix, attr) + } + + return filepath.Join("/proc/self/task", strconv.Itoa(unix.Gettid()), "attr", attr) } // canonicalizeContext takes a context string and writes it to the kernel @@ -592,14 +501,14 @@ func catsToBitset(cats string) (*big.Int, error) { return nil, err } for i := catstart; i <= catend; i++ { - bitset.SetBit(bitset, i, 1) + bitset.SetBit(bitset, int(i), 1) } } else { cat, err := parseLevelItem(ranges[0], category) if err != nil { return nil, err } - bitset.SetBit(bitset, cat, 1) + bitset.SetBit(bitset, int(cat), 1) } } @@ -607,17 +516,16 @@ func catsToBitset(cats string) (*big.Int, error) { } // parseLevelItem parses and verifies that a sensitivity or category are valid -func parseLevelItem(s string, sep levelItem) (int, error) { +func parseLevelItem(s string, sep levelItem) (uint, error) { if len(s) < minSensLen || levelItem(s[0]) != sep { return 0, ErrLevelSyntax } - const bitSize = 31 // Make sure the result fits into signed int32. - val, err := strconv.ParseUint(s[1:], 10, bitSize) + val, err := strconv.ParseUint(s[1:], 10, 32) if err != nil { return 0, err } - return int(val), nil + return uint(val), nil } // parseLevel fills a level from a string that contains @@ -674,8 +582,7 @@ func bitsetToStr(c *big.Int) string { var str string length := 0 - i0 := int(c.TrailingZeroBits()) //#nosec G115 -- don't expect TralingZeroBits to return values with highest bit set. - for i := i0; i < c.BitLen(); i++ { + for i := int(c.TrailingZeroBits()); i < c.BitLen(); i++ { if c.Bit(i) == 0 { continue } @@ -715,7 +622,7 @@ func (l *level) equal(l2 *level) bool { // String returns an mlsRange as a string. func (m mlsRange) String() string { - low := "s" + strconv.Itoa(m.low.sens) + low := "s" + strconv.Itoa(int(m.low.sens)) if m.low.cats != nil && m.low.cats.BitLen() > 0 { low += ":" + bitsetToStr(m.low.cats) } @@ -724,7 +631,7 @@ func (m mlsRange) String() string { return low } - high := "s" + strconv.Itoa(m.high.sens) + high := "s" + strconv.Itoa(int(m.high.sens)) if m.high.cats != nil && m.high.cats.BitLen() > 0 { high += ":" + bitsetToStr(m.high.cats) } @@ -732,16 +639,15 @@ func (m mlsRange) String() string { return low + "-" + high } -// TODO: remove these in favor of built-in min/max -// once we stop supporting Go < 1.21. -func maxInt(a, b int) int { +// TODO: remove min and max once Go < 1.21 is not supported. +func max(a, b uint) uint { if a > b { return a } return b } -func minInt(a, b int) int { +func min(a, b uint) uint { if a < b { return a } @@ -770,10 +676,10 @@ func calculateGlbLub(sourceRange, targetRange string) (string, error) { outrange := &mlsRange{low: &level{}, high: &level{}} /* take the greatest of the low */ - outrange.low.sens = maxInt(s.low.sens, t.low.sens) + outrange.low.sens = max(s.low.sens, t.low.sens) /* take the least of the high */ - outrange.high.sens = minInt(s.high.sens, t.high.sens) + outrange.high.sens = min(s.high.sens, t.high.sens) /* find the intersecting categories */ if s.low.cats != nil && t.low.cats != nil { @@ -818,29 +724,16 @@ func peerLabel(fd uintptr) (string, error) { // setKeyLabel takes a process label and tells the kernel to assign the // label to the next kernel keyring that gets created func setKeyLabel(label string) error { - // Rather than using /proc/thread-self, we want to use /proc/self to - // operate on the thread-group leader. - err := writeConSelf("attr/keycreate", label) + err := writeCon("/proc/self/attr/keycreate", label) if errors.Is(err, os.ErrNotExist) { return nil } if label == "" && errors.Is(err, os.ErrPermission) { return nil } - if errors.Is(err, unix.EACCES) && unix.Getpid() != unix.Gettid() { - return ErrNotTGLeader - } return err } -// KeyLabel retrieves the current kernel keyring label setting for this -// thread-group. -func keyLabel() (string, error) { - // Rather than using /proc/thread-self, we want to use /proc/self to - // operate on the thread-group leader. - return readConSelf("attr/keycreate") -} - // get returns the Context as a string func (c Context) get() string { if l := c["level"]; l != "" { @@ -916,7 +809,8 @@ func enforceMode() int { // setEnforceMode sets the current SELinux mode Enforcing, Permissive. // Disabled is not valid, since this needs to be set at boot time. func setEnforceMode(mode int) error { - return os.WriteFile(selinuxEnforcePath(), []byte(strconv.Itoa(mode)), 0) + //nolint:gosec // ignore G306: permissions to be 0600 or less. + return os.WriteFile(selinuxEnforcePath(), []byte(strconv.Itoa(mode)), 0o644) } // defaultEnforceMode returns the systems default SELinux mode Enforcing, @@ -1123,7 +1017,8 @@ func addMcs(processLabel, fileLabel string) (string, string) { // securityCheckContext validates that the SELinux label is understood by the kernel func securityCheckContext(val string) error { - return os.WriteFile(filepath.Join(getSelinuxMountPoint(), "context"), []byte(val), 0) + //nolint:gosec // ignore G306: permissions to be 0600 or less. + return os.WriteFile(filepath.Join(getSelinuxMountPoint(), "context"), []byte(val), 0o644) } // copyLevel returns a label with the MLS/MCS level from src label replaced on diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go index 382244e5036b..0889fbe0e073 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -3,11 +3,15 @@ package selinux -func readConThreadSelf(string) (string, error) { +func attrPath(string) string { + return "" +} + +func readCon(string) (string, error) { return "", nil } -func writeConThreadSelf(string, string) error { +func writeCon(string, string) error { return nil } @@ -77,10 +81,6 @@ func setKeyLabel(string) error { return nil } -func keyLabel() (string, error) { - return "", nil -} - func (c Context) get() string { return "" } diff --git a/vendor/github.com/openshift/api/.coderabbit.yaml b/vendor/github.com/openshift/api/.coderabbit.yaml index a3ee2d122e37..1cb17f1e19bd 100644 --- a/vendor/github.com/openshift/api/.coderabbit.yaml +++ b/vendor/github.com/openshift/api/.coderabbit.yaml @@ -14,7 +14,6 @@ reviews: - "!payload-manifests" - "!**/zz_generated.crd-manifests/*" # Contains files - "!**/zz_generated.featuregated-crd-manifests/**" # Contains folders - - "!openapi/**" - "!**/vendor/**" - "!vendor/**" tools: diff --git a/vendor/github.com/openshift/api/.golangci.go-validated.yaml b/vendor/github.com/openshift/api/.golangci.go-validated.yaml index ed8fcdbe2de6..44c73149d4cd 100644 --- a/vendor/github.com/openshift/api/.golangci.go-validated.yaml +++ b/vendor/github.com/openshift/api/.golangci.go-validated.yaml @@ -12,7 +12,6 @@ linters: linters: enable: - optionalfields - - nonpointerstructs disable: - "*" lintersConfig: diff --git a/vendor/github.com/openshift/api/.golangci.yaml b/vendor/github.com/openshift/api/.golangci.yaml index 4c6ded3f601d..516339b48828 100644 --- a/vendor/github.com/openshift/api/.golangci.yaml +++ b/vendor/github.com/openshift/api/.golangci.yaml @@ -13,15 +13,12 @@ linters: enable: - forbiddenmarkers - maxlength - - minlength - namingconventions - nobools - nomaps - - preferredmarkers - statussubresource disable: - statusoptional # This is legacy and not something we currently recommend. - - nonpointerstructs # This is intended for native types, not CRD types. lintersConfig: conditions: isFirstField: Warn @@ -33,6 +30,7 @@ linters: - identifier: "openshift:validation:FeatureSetAwareEnum" - identifier: "openshift:validation:FeatureSetAwareXValidation" - identifier: "kubebuilder:validation:UniqueItems" + - identifier: "kubebuilder:validation:Pattern" # Use CEL expressions instead optionalfields: pointers: preference: WhenRequired @@ -46,11 +44,6 @@ linters: # This will force omitzero on optional struct fields. # This means they can be omitted correctly and prevents the need for pointers to structs. policy: SuggestFix - preferredmarkers: - markers: - - preferredIdentifier: "kubebuilder:validation:XValidation" - equivalentIdentifiers: - - identifier: "kubebuilder:validation:Pattern" # Use CEL expressions instead to allow more expressive error messages. requiredfields: pointers: # This will force pointers when the field is required, but only when the zero @@ -67,13 +60,15 @@ linters: policy: SuggestFix namingconventions: conventions: + - name: norefs + violationMatcher: "(?i)ref(erence)?s?$" + operation: Drop + message: "reference fields should not need to be named ref(s)/reference(s)" - name: nokind violationMatcher: "^Kind$" operation: Replacement replacement: "Resource" message: "API Kinds can be ambiguous and should be replaced with Resource" - noreferences: - policy: NoReferences uniquemarkers: customMarkers: - identifier: "openshift:validation:FeatureGateAwareEnum" diff --git a/vendor/github.com/openshift/api/Makefile b/vendor/github.com/openshift/api/Makefile index 9b32b58e4332..c069d804017a 100644 --- a/vendor/github.com/openshift/api/Makefile +++ b/vendor/github.com/openshift/api/Makefile @@ -114,17 +114,15 @@ update-scripts: update-compatibility update-openapi update-deepcopy update-proto # Update codegen runs all generators in the order they are defined in the root.go file. # The per group generators are:[compatibility, deepcopy, swagger-docs, empty-partial-schema, schema-patch, crd-manifest-merge] # The multi group generators are:[openapi] -# The payload generation must come after these generators have run so they are included here as well, rather than in update-non-codegen. .PHONY: update-codegen update-codegen: hack/update-codegen.sh - make update-payload-crds update-payload-featuregates # Update non-codegen runs all generators that are not part of the codegen utility, or # are part of it, but are not run by default when invoking codegen without a specific generator. # E.g. the payload feature gates which is not part of the generator style, but is still a subcommand. .PHONY: update-non-codegen -update-non-codegen: update-protobuf tests-vendor update-prerelease-lifecycle-gen +update-non-codegen: update-protobuf tests-vendor update-prerelease-lifecycle-gen update-payload-crds update-payload-featuregates .PHONY: update-compatibility update-compatibility: diff --git a/vendor/github.com/openshift/api/apiextensions/v1alpha1/types_compatibilityrequirement.go b/vendor/github.com/openshift/api/apiextensions/v1alpha1/types_compatibilityrequirement.go index 5abbfec7c1a1..46e211cd551f 100644 --- a/vendor/github.com/openshift/api/apiextensions/v1alpha1/types_compatibilityrequirement.go +++ b/vendor/github.com/openshift/api/apiextensions/v1alpha1/types_compatibilityrequirement.go @@ -21,7 +21,6 @@ import ( // +kubebuilder:subresource:status // +kubebuilder:resource:path=compatibilityrequirements,scope=Cluster // +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/2479 -// +kubebuilder:metadata:annotations="release.openshift.io/feature-gate=CRDCompatibilityRequirementOperator" type CompatibilityRequirement struct { metav1.TypeMeta `json:",inline"` diff --git a/vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.featuregated-crd-manifests.yaml index 433546401ce1..319f2b335f23 100644 --- a/vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.featuregated-crd-manifests.yaml @@ -1,6 +1,5 @@ compatibilityrequirements.apiextensions.openshift.io: - Annotations: - release.openshift.io/feature-gate: CRDCompatibilityRequirementOperator + Annotations: {} ApprovedPRNumber: https://github.com/openshift/api/pull/2479 CRDName: compatibilityrequirements.apiextensions.openshift.io Capability: "" diff --git a/vendor/github.com/openshift/api/config/v1/types_apiserver.go b/vendor/github.com/openshift/api/config/v1/types_apiserver.go index 31d8881858e2..0afe7b1d8dee 100644 --- a/vendor/github.com/openshift/api/config/v1/types_apiserver.go +++ b/vendor/github.com/openshift/api/config/v1/types_apiserver.go @@ -212,7 +212,6 @@ type APIServerEncryption struct { // +openshift:validation:FeatureGateAwareEnum:featureGate="",enum="";identity;aescbc;aesgcm // +openshift:validation:FeatureGateAwareEnum:featureGate=KMSEncryptionProvider,enum="";identity;aescbc;aesgcm;KMS -// +openshift:validation:FeatureGateAwareEnum:featureGate=KMSEncryption,enum="";identity;aescbc;aesgcm;KMS type EncryptionType string const ( diff --git a/vendor/github.com/openshift/api/config/v1/types_authentication.go b/vendor/github.com/openshift/api/config/v1/types_authentication.go index e7433281f4a3..e300d4eabc5f 100644 --- a/vendor/github.com/openshift/api/config/v1/types_authentication.go +++ b/vendor/github.com/openshift/api/config/v1/types_authentication.go @@ -80,7 +80,8 @@ type AuthenticationSpec struct { // +optional ServiceAccountIssuer string `json:"serviceAccountIssuer"` - // oidcProviders are OIDC identity providers that can issue tokens for this cluster + // oidcProviders are OIDC identity providers that can issue tokens + // for this cluster // Can only be set if "Type" is set to "OIDC". // // At most one provider can be configured. @@ -112,7 +113,8 @@ type AuthenticationStatus struct { // +optional IntegratedOAuthMetadata ConfigMapNameReference `json:"integratedOAuthMetadata"` - // oidcClients is where participating operators place the current OIDC client status for OIDC clients that can be customized by the cluster-admin. + // oidcClients is where participating operators place the current OIDC client status + // for OIDC clients that can be customized by the cluster-admin. // // +listType=map // +listMapKey=componentNamespace @@ -144,7 +146,8 @@ type AuthenticationType string const ( // None means that no cluster managed authentication system is in place. - // Note that user login will only work if a manually configured system is in place and referenced in authentication spec via oauthMetadata and + // Note that user login will only work if a manually configured system is in place and + // referenced in authentication spec via oauthMetadata and // webhookTokenAuthenticator/oidcProviders AuthenticationTypeNone AuthenticationType = "None" @@ -196,8 +199,10 @@ const ( ) type OIDCProvider struct { - // name is a required field that configures the unique human-readable identifier associated with the identity provider. - // It is used to distinguish between multiple identity providers and has no impact on token validation or authentication mechanics. + // name is a required field that configures the unique human-readable identifier + // associated with the identity provider. + // It is used to distinguish between multiple identity providers + // and has no impact on token validation or authentication mechanics. // // name must not be an empty string (""). // @@ -205,12 +210,15 @@ type OIDCProvider struct { // +required Name string `json:"name"` - // issuer is a required field that configures how the platform interacts with the identity provider and how tokens issued from the identity provider are evaluated by the Kubernetes API server. + // issuer is a required field that configures how the platform interacts + // with the identity provider and how tokens issued from the identity provider + // are evaluated by the Kubernetes API server. // // +required Issuer TokenIssuer `json:"issuer"` - // oidcClients is an optional field that configures how on-cluster, platform clients should request tokens from the identity provider. + // oidcClients is an optional field that configures how on-cluster, + // platform clients should request tokens from the identity provider. // oidcClients must not exceed 20 entries and entries must have unique namespace/name pairs. // // +listType=map @@ -220,12 +228,16 @@ type OIDCProvider struct { // +optional OIDCClients []OIDCClientConfig `json:"oidcClients"` - // claimMappings is a required field that configures the rules to be used by the Kubernetes API server for translating claims in a JWT token, issued by the identity provider, to a cluster identity. + // claimMappings is a required field that configures the rules to be used by + // the Kubernetes API server for translating claims in a JWT token, issued + // by the identity provider, to a cluster identity. // // +required ClaimMappings TokenClaimMappings `json:"claimMappings"` - // claimValidationRules is an optional field that configures the rules to be used by the Kubernetes API server for validating the claims in a JWT token issued by the identity provider. + // claimValidationRules is an optional field that configures the rules to + // be used by the Kubernetes API server for validating the claims in a JWT + // token issued by the identity provider. // // Validation rules are joined via an AND operation. // @@ -233,7 +245,9 @@ type OIDCProvider struct { // +optional ClaimValidationRules []TokenClaimValidationRule `json:"claimValidationRules,omitempty"` - // userValidationRules is an optional field that configures the set of rules used to validate the cluster user identity that was constructed via mapping token claims to user identity attributes. + // userValidationRules is an optional field that configures the set of rules + // used to validate the cluster user identity that was constructed via + // mapping token claims to user identity attributes. // Rules are CEL expressions that must evaluate to 'true' for authentication to succeed. // If any rule in the chain of rules evaluates to 'false', authentication will fail. // When specified, at least one rule must be specified and no more than 64 rules may be specified. @@ -252,8 +266,10 @@ type TokenAudience string // +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDCWithUpstreamParity,rule="self.?discoveryURL.orValue(\"\").size() > 0 ? (self.issuerURL.size() == 0 || self.discoveryURL.find('^.+[^/]') != self.issuerURL.find('^.+[^/]')) : true",message="discoveryURL must be different from issuerURL" type TokenIssuer struct { - // issuerURL is a required field that configures the URL used to issue tokens by the identity provider. - // The Kubernetes API server determines how authentication tokens should be handled by matching the 'iss' claim in the JWT to the issuerURL of configured identity providers. + // issuerURL is a required field that configures the URL used to issue tokens + // by the identity provider. + // The Kubernetes API server determines how authentication tokens should be handled + // by matching the 'iss' claim in the JWT to the issuerURL of configured identity providers. // // Must be at least 1 character and must not exceed 512 characters in length. // Must be a valid URL that uses the 'https' scheme and does not contain a query, fragment or user. @@ -268,7 +284,8 @@ type TokenIssuer struct { // +required URL string `json:"issuerURL"` - // audiences is a required field that configures the acceptable audiences the JWT token, issued by the identity provider, must be issued to. + // audiences is a required field that configures the acceptable audiences + // the JWT token, issued by the identity provider, must be issued to. // At least one of the entries must match the 'aud' claim in the JWT token. // // audiences must contain at least one entry and must not exceed ten entries. @@ -279,20 +296,24 @@ type TokenIssuer struct { // +required Audiences []TokenAudience `json:"audiences"` - // issuerCertificateAuthority is an optional field that configures the certificate authority, used by the Kubernetes API server, to validate the connection to the identity provider when fetching discovery information. + // issuerCertificateAuthority is an optional field that configures the + // certificate authority, used by the Kubernetes API server, to validate + // the connection to the identity provider when fetching discovery information. // // When not specified, the system trust is used. // - // When specified, it must reference a ConfigMap in the openshift-config namespace containing the PEM-encoded CA certificates under the 'ca-bundle.crt' key in the data field of the ConfigMap. + // When specified, it must reference a ConfigMap in the openshift-config + // namespace containing the PEM-encoded CA certificates under the 'ca-bundle.crt' + // key in the data field of the ConfigMap. // // +optional CertificateAuthority ConfigMapNameReference `json:"issuerCertificateAuthority"` - // discoveryURL is an optional field that, if specified, overrides the default discovery endpoint used to retrieve OIDC configuration metadata. - // By default, the discovery URL is derived from `issuerURL` as "{issuerURL}/.well-known/openid-configuration". + // discoveryURL is an optional field that, if specified, overrides the default discovery endpoint + // used to retrieve OIDC configuration metadata. By default, the discovery URL is derived from `issuerURL` + // as "{issuerURL}/.well-known/openid-configuration". // - // The discoveryURL must be a valid absolute HTTPS URL. - // It must not contain query parameters, user information, or fragments. - // Additionally, it must differ from the value of `issuerURL` (ignoring trailing slashes). + // The discoveryURL must be a valid absolute HTTPS URL. It must not contain query + // parameters, user information, or fragments. Additionally, it must differ from the value of `url` (ignoring trailing slashes). // The discoveryURL value must be at least 1 character long and no longer than 2048 characters. // // +optional @@ -308,36 +329,39 @@ type TokenIssuer struct { } type TokenClaimMappings struct { - // username is a required field that configures how the username of a cluster identity should be constructed from the claims in a JWT token issued by the identity provider. + // username is a required field that configures how the username of a cluster identity + // should be constructed from the claims in a JWT token issued by the identity provider. // // +required Username UsernameClaimMapping `json:"username"` - // groups is an optional field that configures how the groups of a cluster identity should be constructed from the claims in a JWT token issued by the identity provider. - // - // When referencing a claim, if the claim is present in the JWT token, its value must be a list of groups separated by a comma (','). - // + // groups is an optional field that configures how the groups of a cluster identity + // should be constructed from the claims in a JWT token issued + // by the identity provider. + // When referencing a claim, if the claim is present in the JWT + // token, its value must be a list of groups separated by a comma (','). // For example - '"example"' and '"exampleOne", "exampleTwo", "exampleThree"' are valid claim values. // // +optional Groups PrefixedClaimMapping `json:"groups,omitempty"` - // uid is an optional field for configuring the claim mapping used to construct the uid for the cluster identity. + // uid is an optional field for configuring the claim mapping + // used to construct the uid for the cluster identity. // // When using uid.claim to specify the claim it must be a single string value. // When using uid.expression the expression must result in a single string value. // - // When omitted, this means the user has no opinion and the platform is left to choose a default, which is subject to change over time. - // + // When omitted, this means the user has no opinion and the platform + // is left to choose a default, which is subject to change over time. // The current default is to use the 'sub' claim. // // +optional // +openshift:enable:FeatureGate=ExternalOIDCWithUIDAndExtraClaimMappings UID *TokenClaimOrExpressionMapping `json:"uid,omitempty"` - // extra is an optional field for configuring the mappings used to construct the extra attribute for the cluster identity. + // extra is an optional field for configuring the mappings + // used to construct the extra attribute for the cluster identity. // When omitted, no extra attributes will be present on the cluster identity. - // // key values for extra mappings must be unique. // A maximum of 32 extra attribute mappings may be provided. // @@ -349,39 +373,52 @@ type TokenClaimMappings struct { Extra []ExtraMapping `json:"extra,omitempty"` } -// TokenClaimMapping allows specifying a JWT token claim to be used when mapping claims from an authentication token to cluster identities. +// TokenClaimMapping allows specifying a JWT token +// claim to be used when mapping claims from an +// authentication token to cluster identities. type TokenClaimMapping struct { - // claim is a required field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping. + // claim is a required field that configures the JWT token + // claim whose value is assigned to the cluster identity + // field associated with this mapping. // // +required Claim string `json:"claim"` } -// TokenClaimOrExpressionMapping allows specifying either a JWT token claim or CEL expression to be used when mapping claims from an authentication token to cluster identities. +// TokenClaimOrExpressionMapping allows specifying either a JWT +// token claim or CEL expression to be used when mapping claims +// from an authentication token to cluster identities. // +kubebuilder:validation:XValidation:rule="has(self.claim) ? !has(self.expression) : has(self.expression)",message="precisely one of claim or expression must be set" type TokenClaimOrExpressionMapping struct { - // claim is an optional field for specifying the JWT token claim that is used in the mapping. - // The value of this claim will be assigned to the field in which this mapping is associated. + // claim is an optional field for specifying the + // JWT token claim that is used in the mapping. + // The value of this claim will be assigned to + // the field in which this mapping is associated. // // Precisely one of claim or expression must be set. // claim must not be specified when expression is set. - // When specified, claim must be at least 1 character in length and must not exceed 256 characters in length. + // When specified, claim must be at least 1 character in length + // and must not exceed 256 characters in length. // // +optional // +kubebuilder:validation:MaxLength=256 // +kubebuilder:validation:MinLength=1 Claim string `json:"claim,omitempty"` - // expression is an optional field for specifying a CEL expression that produces a string value from JWT token claims. + // expression is an optional field for specifying a + // CEL expression that produces a string value from + // JWT token claims. // - // CEL expressions have access to the token claims through a CEL variable, 'claims'. + // CEL expressions have access to the token claims + // through a CEL variable, 'claims'. // 'claims' is a map of claim names to claim values. // For example, the 'sub' claim value can be accessed as 'claims.sub'. // Nested claims can be accessed using dot notation ('claims.foo.bar'). // // Precisely one of claim or expression must be set. // expression must not be specified when claim is set. - // When specified, expression must be at least 1 character in length and must not exceed 1024 characters in length. + // When specified, expression must be at least 1 character in length + // and must not exceed 1024 characters in length. // // +optional // +kubebuilder:validation:MaxLength=1024 @@ -389,10 +426,13 @@ type TokenClaimOrExpressionMapping struct { Expression string `json:"expression,omitempty"` } -// ExtraMapping allows specifying a key and CEL expression to evaluate the keys' value. -// It is used to create additional mappings and attributes added to a cluster identity from a provided authentication token. +// ExtraMapping allows specifying a key and CEL expression +// to evaluate the keys' value. It is used to create additional +// mappings and attributes added to a cluster identity from +// a provided authentication token. type ExtraMapping struct { - // key is a required field that specifies the string to use as the extra attribute key. + // key is a required field that specifies the string + // to use as the extra attribute key. // // key must be a domain-prefix path (e.g 'example.org/foo'). // key must not exceed 510 characters in length. @@ -405,7 +445,8 @@ type ExtraMapping struct { // It must only contain lower case alphanumeric characters and '-' or '.'. // It must not use the reserved domains, or be subdomains of, "kubernetes.io", "k8s.io", and "openshift.io". // - // The path portion of the key (string of characters after the '/') must not be empty and must consist of at least one alphanumeric character, percent-encoded octets, '-', '.', '_', '~', '!', '$', '&', ''', '(', ')', '*', '+', ',', ';', '=', and ':'. + // The path portion of the key (string of characters after the '/') must not be empty and must consist of at least one + // alphanumeric character, percent-encoded octets, '-', '.', '_', '~', '!', '$', '&', ''', '(', ')', '*', '+', ',', ';', '=', and ':'. // It must not exceed 256 characters in length. // // +required @@ -427,12 +468,14 @@ type ExtraMapping struct { // +kubebuilder:validation:XValidation:rule="self.split('/', 2)[1].size() <= 256",message="the path of the key must not exceed 256 characters in length" Key string `json:"key"` - // valueExpression is a required field to specify the CEL expression to extract the extra attribute value from a JWT token's claims. + // valueExpression is a required field to specify the CEL expression to extract + // the extra attribute value from a JWT token's claims. // valueExpression must produce a string or string array value. // "", [], and null are treated as the extra mapping not being present. // Empty string values within an array are filtered out. // - // CEL expressions have access to the token claims through a CEL variable, 'claims'. + // CEL expressions have access to the token claims + // through a CEL variable, 'claims'. // 'claims' is a map of claim names to claim values. // For example, the 'sub' claim value can be accessed as 'claims.sub'. // Nested claims can be accessed using dot notation ('claims.foo.bar'). @@ -446,10 +489,12 @@ type ExtraMapping struct { ValueExpression string `json:"valueExpression"` } -// OIDCClientConfig configures how platform clients interact with identity providers as an authentication method. +// OIDCClientConfig configures how platform clients +// interact with identity providers as an authentication +// method type OIDCClientConfig struct { - // componentName is a required field that specifies the name of the platform component being configured to use the identity provider as an authentication mode. - // + // componentName is a required field that specifies the name of the platform + // component being configured to use the identity provider as an authentication mode. // It is used in combination with componentNamespace as a unique identifier. // // componentName must not be an empty string ("") and must not exceed 256 characters in length. @@ -459,8 +504,9 @@ type OIDCClientConfig struct { // +required ComponentName string `json:"componentName"` - // componentNamespace is a required field that specifies the namespace in which the platform component being configured to use the identity provider as an authentication mode is running. - // + // componentNamespace is a required field that specifies the namespace in which the + // platform component being configured to use the identity provider as an authentication + // mode is running. // It is used in combination with componentName as a unique identifier. // // componentNamespace must not be an empty string ("") and must not exceed 63 characters in length. @@ -470,8 +516,11 @@ type OIDCClientConfig struct { // +required ComponentNamespace string `json:"componentNamespace"` - // clientID is a required field that configures the client identifier, from the identity provider, that the platform component uses for authentication requests made to the identity provider. - // The identity provider must accept this identifier for platform components to be able to use the identity provider as an authentication mode. + // clientID is a required field that configures the client identifier, from + // the identity provider, that the platform component uses for authentication + // requests made to the identity provider. + // The identity provider must accept this identifier for platform components + // to be able to use the identity provider as an authentication mode. // // clientID must not be an empty string (""). // @@ -479,21 +528,27 @@ type OIDCClientConfig struct { // +required ClientID string `json:"clientID"` - // clientSecret is an optional field that configures the client secret used by the platform component when making authentication requests to the identity provider. - // - // When not specified, no client secret will be used when making authentication requests to the identity provider. + // clientSecret is an optional field that configures the client secret used + // by the platform component when making authentication requests to the identity provider. // - // When specified, clientSecret references a Secret in the 'openshift-config' namespace that contains the client secret in the 'clientSecret' key of the '.data' field. + // When not specified, no client secret will be used when making authentication requests + // to the identity provider. // + // When specified, clientSecret references a Secret in the 'openshift-config' + // namespace that contains the client secret in the 'clientSecret' key of the '.data' field. // The client secret will be used when making authentication requests to the identity provider. // - // Public clients do not require a client secret but private clients do require a client secret to work with the identity provider. + // Public clients do not require a client secret but private + // clients do require a client secret to work with the identity provider. // // +optional ClientSecret SecretNameReference `json:"clientSecret"` - // extraScopes is an optional field that configures the extra scopes that should be requested by the platform component when making authentication requests to the identity provider. - // This is useful if you have configured claim mappings that requires specific scopes to be requested beyond the standard OIDC scopes. + // extraScopes is an optional field that configures the extra scopes that should + // be requested by the platform component when making authentication requests to the + // identity provider. + // This is useful if you have configured claim mappings that requires specific + // scopes to be requested beyond the standard OIDC scopes. // // When omitted, no additional scopes are requested. // @@ -506,7 +561,8 @@ type OIDCClientConfig struct { // of platform components and how they interact with // the configured identity providers. type OIDCClientStatus struct { - // componentName is a required field that specifies the name of the platform component using the identity provider as an authentication mode. + // componentName is a required field that specifies the name of the platform + // component using the identity provider as an authentication mode. // It is used in combination with componentNamespace as a unique identifier. // // componentName must not be an empty string ("") and must not exceed 256 characters in length. @@ -516,8 +572,9 @@ type OIDCClientStatus struct { // +required ComponentName string `json:"componentName"` - // componentNamespace is a required field that specifies the namespace in which the platform component using the identity provider as an authentication mode is running. - // + // componentNamespace is a required field that specifies the namespace in which the + // platform component using the identity provider as an authentication + // mode is running. // It is used in combination with componentName as a unique identifier. // // componentNamespace must not be an empty string ("") and must not exceed 63 characters in length. @@ -528,7 +585,6 @@ type OIDCClientStatus struct { ComponentNamespace string `json:"componentNamespace"` // currentOIDCClients is an optional list of clients that the component is currently using. - // // Entries must have unique issuerURL/clientID pairs. // // +listType=map @@ -537,7 +593,8 @@ type OIDCClientStatus struct { // +optional CurrentOIDCClients []OIDCClientReference `json:"currentOIDCClients"` - // consumingUsers is an optional list of ServiceAccounts requiring read permissions on the `clientSecret` secret. + // consumingUsers is an optional list of ServiceAccounts requiring + // read permissions on the `clientSecret` secret. // // consumingUsers must not exceed 5 entries. // @@ -563,7 +620,8 @@ type OIDCClientStatus struct { // OIDCClientReference is a reference to a platform component // client configuration. type OIDCClientReference struct { - // oidcProviderName is a required reference to the 'name' of the identity provider configured in 'oidcProviders' that this client is associated with. + // oidcProviderName is a required reference to the 'name' of the identity provider + // configured in 'oidcProviders' that this client is associated with. // // oidcProviderName must not be an empty string (""). // @@ -571,7 +629,8 @@ type OIDCClientReference struct { // +required OIDCProviderName string `json:"oidcProviderName"` - // issuerURL is a required field that specifies the URL of the identity provider that this client is configured to make requests against. + // issuerURL is a required field that specifies the URL of the identity + // provider that this client is configured to make requests against. // // issuerURL must use the 'https' scheme. // @@ -579,7 +638,9 @@ type OIDCClientReference struct { // +required IssuerURL string `json:"issuerURL"` - // clientID is a required field that specifies the client identifier, from the identity provider, that the platform component is using for authentication requests made to the identity provider. + // clientID is a required field that specifies the client identifier, from + // the identity provider, that the platform component is using for authentication + // requests made to the identity provider. // // clientID must not be empty. // @@ -591,7 +652,9 @@ type OIDCClientReference struct { // +kubebuilder:validation:XValidation:rule="has(self.prefixPolicy) && self.prefixPolicy == 'Prefix' ? (has(self.prefix) && size(self.prefix.prefixString) > 0) : !has(self.prefix)",message="prefix must be set if prefixPolicy is 'Prefix', but must remain unset otherwise" // +union type UsernameClaimMapping struct { - // claim is a required field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping. + // claim is a required field that configures the JWT token + // claim whose value is assigned to the cluster identity + // field associated with this mapping. // // claim must not be an empty string ("") and must not exceed 256 characters. // @@ -600,21 +663,23 @@ type UsernameClaimMapping struct { // +kubebuilder:validation:MaxLength:=256 Claim string `json:"claim"` - // prefixPolicy is an optional field that configures how a prefix should be applied to the value of the JWT claim specified in the 'claim' field. + // prefixPolicy is an optional field that configures how a prefix should be + // applied to the value of the JWT claim specified in the 'claim' field. // // Allowed values are 'Prefix', 'NoPrefix', and omitted (not provided or an empty string). // - // When set to 'Prefix', the value specified in the prefix field will be prepended to the value of the JWT claim. - // + // When set to 'Prefix', the value specified in the prefix field will be + // prepended to the value of the JWT claim. // The prefix field must be set when prefixPolicy is 'Prefix'. // - // When set to 'NoPrefix', no prefix will be prepended to the value of the JWT claim. - // - // When omitted, this means no opinion and the platform is left to choose any prefixes that are applied which is subject to change over time. - // Currently, the platform prepends `{issuerURL}#` to the value of the JWT claim when the claim is not 'email'. + // When set to 'NoPrefix', no prefix will be prepended to the value + // of the JWT claim. // + // When omitted, this means no opinion and the platform is left to choose + // any prefixes that are applied which is subject to change over time. + // Currently, the platform prepends `{issuerURL}#` to the value of the JWT claim + // when the claim is not 'email'. // As an example, consider the following scenario: - // // `prefix` is unset, `issuerURL` is set to `https://myoidc.tld`, // the JWT claims include "username":"userA" and "email":"userA@myoidc.tld", // and `claim` is set to: @@ -626,7 +691,8 @@ type UsernameClaimMapping struct { // +unionDiscriminator PrefixPolicy UsernamePrefixPolicy `json:"prefixPolicy"` - // prefix configures the prefix that should be prepended to the value of the JWT claim. + // prefix configures the prefix that should be prepended to the value + // of the JWT claim. // // prefix must be set when prefixPolicy is set to 'Prefix' and must be unset otherwise. // @@ -635,7 +701,9 @@ type UsernameClaimMapping struct { Prefix *UsernamePrefix `json:"prefix"` } -// UsernamePrefixPolicy configures how prefixes should be applied to values extracted from the JWT claims during the process of mapping JWT claims to cluster identity attributes. +// UsernamePrefixPolicy configures how prefixes should be applied +// to values extracted from the JWT claims during the process of mapping +// JWT claims to cluster identity attributes. // +enum type UsernamePrefixPolicy string @@ -654,7 +722,9 @@ var ( // UsernamePrefix configures the string that should // be used as a prefix for username claim mappings. type UsernamePrefix struct { - // prefixString is a required field that configures the prefix that will be applied to cluster identity username attribute during the process of mapping JWT claims to cluster identity attributes. + // prefixString is a required field that configures the prefix that will + // be applied to cluster identity username attribute + // during the process of mapping JWT claims to cluster identity attributes. // // prefixString must not be an empty string (""). // @@ -668,11 +738,15 @@ type UsernamePrefix struct { type PrefixedClaimMapping struct { TokenClaimMapping `json:",inline"` - // prefix is an optional field that configures the prefix that will be applied to the cluster identity attribute during the process of mapping JWT claims to cluster identity attributes. + // prefix is an optional field that configures the prefix that will be + // applied to the cluster identity attribute during the process of mapping + // JWT claims to cluster identity attributes. // // When omitted (""), no prefix is applied to the cluster identity attribute. // - // Example: if `prefix` is set to "myoidc:" and the `claim` in JWT contains an array of strings "a", "b" and "c", the mapping will result in an array of string "myoidc:a", "myoidc:b" and "myoidc:c". + // Example: if `prefix` is set to "myoidc:" and the `claim` in JWT contains + // an array of strings "a", "b" and "c", the mapping will result in an + // array of string "myoidc:a", "myoidc:b" and "myoidc:c". // // +optional Prefix string `json:"prefix"` @@ -706,15 +780,19 @@ type TokenClaimValidationRule struct { // // Allowed values are "RequiredClaim" and "CEL". // - // When set to 'RequiredClaim', the Kubernetes API server will be configured to validate that the incoming JWT contains the required claim and that its value matches the required value. + // When set to 'RequiredClaim', the Kubernetes API server will be configured + // to validate that the incoming JWT contains the required claim and that its + // value matches the required value. // - // When set to 'CEL', the Kubernetes API server will be configured to validate the incoming JWT against the configured CEL expression. + // When set to 'CEL', the Kubernetes API server will be configured + // to validate the incoming JWT against the configured CEL expression. // +required Type TokenValidationRuleType `json:"type"` // requiredClaim allows configuring a required claim name and its expected value. - // This field is required when `type` is set to RequiredClaim, and must be omitted when `type` is set to any other value. - // The Kubernetes API server uses this field to validate if an incoming JWT is valid for this identity provider. + // This field is required when `type` is set to RequiredClaim, and must be omitted + // when `type` is set to any other value. The Kubernetes API server uses this field + // to validate if an incoming JWT is valid for this identity provider. // // +optional RequiredClaim *TokenRequiredClaim `json:"requiredClaim,omitempty"` @@ -736,8 +814,10 @@ type TokenRequiredClaim struct { // +required Claim string `json:"claim"` - // requiredValue is a required field that configures the value that 'claim' must have when taken from the incoming JWT claims. - // If the value in the JWT claims does not match, the token will be rejected for authentication. + // requiredValue is a required field that configures the value that 'claim' must + // have when taken from the incoming JWT claims. + // If the value in the JWT claims does not match, the token + // will be rejected for authentication. // // requiredValue must not be an empty string (""). // @@ -756,7 +836,8 @@ type TokenClaimValidationCELRule struct { // +required Expression string `json:"expression,omitempty"` - // message is a required human-readable message to be logged by the Kubernetes API server if the CEL expression defined in 'expression' fails. + // message is a required human-readable message to be logged by the Kubernetes API server + // if the CEL expression defined in 'expression' fails. // message must be at least 1 character in length and must not exceed 256 characters. // +required // +kubebuilder:validation:MinLength=1 @@ -767,8 +848,8 @@ type TokenClaimValidationCELRule struct { // TokenUserValidationRule provides a CEL-based rule used to validate a token subject. // Each rule contains a CEL expression that is evaluated against the token’s claims. type TokenUserValidationRule struct { - // expression is a required CEL expression that performs a validation on cluster user identity attributes like username, groups, etc. - // + // expression is a required CEL expression that performs a validation + // on cluster user identity attributes like username, groups, etc. // The expression must evaluate to a boolean value. // When the expression evaluates to 'true', the cluster user identity is considered valid. // When the expression evaluates to 'false', the cluster user identity is not considered valid. @@ -778,7 +859,8 @@ type TokenUserValidationRule struct { // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=1024 Expression string `json:"expression,omitempty"` - // message is a required human-readable message to be logged by the Kubernetes API server if the CEL expression defined in 'expression' fails. + // message is a required human-readable message to be logged by the Kubernetes API server + // if the CEL expression defined in 'expression' fails. // message must be at least 1 character in length and must not exceed 256 characters. // +required // +kubebuilder:validation:MinLength=1 diff --git a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go index 369ba1e7a000..313ed57a4144 100644 --- a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go +++ b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go @@ -302,10 +302,9 @@ type PlatformSpec struct { // balancers, dynamic volume provisioning, machine creation and deletion, and // other integrations are enabled. If None, no infrastructure automation is // enabled. Allowed values are "AWS", "Azure", "BareMetal", "GCP", "Libvirt", - // "OpenStack", "VSphere", "oVirt", "IBMCloud", "KubeVirt", "EquinixMetal", - // "PowerVS", "AlibabaCloud", "Nutanix", "External", and "None". Individual - // components may not support all platforms, and must handle unrecognized - // platforms as None if they do not support that platform. + // "OpenStack", "VSphere", "oVirt", "KubeVirt", "EquinixMetal", "PowerVS", + // "AlibabaCloud", "Nutanix" and "None". Individual components may not support all platforms, + // and must handle unrecognized platforms as None if they do not support that platform. // // +unionDiscriminator Type PlatformType `json:"type"` diff --git a/vendor/github.com/openshift/api/config/v1/types_insights.go b/vendor/github.com/openshift/api/config/v1/types_insights.go index 710d4303da22..b0959881f15b 100644 --- a/vendor/github.com/openshift/api/config/v1/types_insights.go +++ b/vendor/github.com/openshift/api/config/v1/types_insights.go @@ -13,7 +13,6 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/2448 // +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01 // +openshift:enable:FeatureGate=InsightsConfig -// +openshift:capability=Insights // // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer). // +openshift:compatibility-gen:level=1 diff --git a/vendor/github.com/openshift/api/config/v1/types_network.go b/vendor/github.com/openshift/api/config/v1/types_network.go index fb8ed2fff743..c0d1602b3766 100644 --- a/vendor/github.com/openshift/api/config/v1/types_network.go +++ b/vendor/github.com/openshift/api/config/v1/types_network.go @@ -41,7 +41,7 @@ type Network struct { // As a general rule, this SHOULD NOT be read directly. Instead, you should // consume the NetworkStatus, as it indicates the currently deployed configuration. // Currently, most spec fields are immutable after installation. Please view the individual ones for further details on each. -// +kubebuilder:validation:XValidation:rule="!has(self.networkDiagnostics) || !has(self.networkDiagnostics.mode) || self.networkDiagnostics.mode!='Disabled' || !has(self.networkDiagnostics.sourcePlacement) && !has(self.networkDiagnostics.targetPlacement)",message="cannot set networkDiagnostics.sourcePlacement and networkDiagnostics.targetPlacement when networkDiagnostics.mode is Disabled" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=NetworkDiagnosticsConfig,rule="!has(self.networkDiagnostics) || !has(self.networkDiagnostics.mode) || self.networkDiagnostics.mode!='Disabled' || !has(self.networkDiagnostics.sourcePlacement) && !has(self.networkDiagnostics.targetPlacement)",message="cannot set networkDiagnostics.sourcePlacement and networkDiagnostics.targetPlacement when networkDiagnostics.mode is Disabled" type NetworkSpec struct { // IP address pool to use for pod IPs. // This field is immutable after installation. @@ -85,6 +85,7 @@ type NetworkSpec struct { // the network diagnostics feature will be disabled. // // +optional + // +openshift:enable:FeatureGate=NetworkDiagnosticsConfig NetworkDiagnostics NetworkDiagnostics `json:"networkDiagnostics"` } @@ -118,6 +119,7 @@ type NetworkStatus struct { // +optional // +listType=map // +listMapKey=type + // +openshift:enable:FeatureGate=NetworkDiagnosticsConfig Conditions []metav1.Condition `json:"conditions,omitempty"` } diff --git a/vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go b/vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go index 48657b089475..1e5189796e4c 100644 --- a/vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go +++ b/vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go @@ -7,10 +7,9 @@ type TLSSecurityProfile struct { // type is one of Old, Intermediate, Modern or Custom. Custom provides the // ability to specify individual TLS security profile parameters. // - // The profiles are based on version 5.7 of the Mozilla Server Side TLS - // configuration guidelines. The cipher lists consist of the configuration's - // "ciphersuites" followed by the Go-specific "ciphers" from the guidelines. - // See: https://ssl-config.mozilla.org/guidelines/5.7.json + // The profiles are currently based on version 5.0 of the Mozilla Server Side TLS + // configuration guidelines (released 2019-06-28) with TLS 1.3 ciphers added for + // forward compatibility. See: https://ssl-config.mozilla.org/guidelines/5.0.json // // The profiles are intent based, so they may change over time as new ciphers are // developed and existing ciphers are found to be insecure. Depending on @@ -23,6 +22,9 @@ type TLSSecurityProfile struct { // old is a TLS profile for use when services need to be accessed by very old // clients or libraries and should be used only as a last resort. // + // The cipher list includes TLS 1.3 ciphers for forward compatibility, followed + // by the "old" profile ciphers. + // // This profile is equivalent to a Custom profile specified as: // minTLSVersion: VersionTLS10 // ciphers: @@ -35,15 +37,23 @@ type TLSSecurityProfile struct { // - ECDHE-RSA-AES256-GCM-SHA384 // - ECDHE-ECDSA-CHACHA20-POLY1305 // - ECDHE-RSA-CHACHA20-POLY1305 + // - DHE-RSA-AES128-GCM-SHA256 + // - DHE-RSA-AES256-GCM-SHA384 + // - DHE-RSA-CHACHA20-POLY1305 // - ECDHE-ECDSA-AES128-SHA256 // - ECDHE-RSA-AES128-SHA256 // - ECDHE-ECDSA-AES128-SHA // - ECDHE-RSA-AES128-SHA + // - ECDHE-ECDSA-AES256-SHA384 + // - ECDHE-RSA-AES256-SHA384 // - ECDHE-ECDSA-AES256-SHA // - ECDHE-RSA-AES256-SHA + // - DHE-RSA-AES128-SHA256 + // - DHE-RSA-AES256-SHA256 // - AES128-GCM-SHA256 // - AES256-GCM-SHA384 // - AES128-SHA256 + // - AES256-SHA256 // - AES128-SHA // - AES256-SHA // - DES-CBC3-SHA @@ -56,6 +66,9 @@ type TLSSecurityProfile struct { // legacy clients and want to remain highly secure while being compatible with // most clients currently in use. // + // The cipher list includes TLS 1.3 ciphers for forward compatibility, followed + // by the "intermediate" profile ciphers. + // // This profile is equivalent to a Custom profile specified as: // minTLSVersion: VersionTLS12 // ciphers: @@ -68,6 +81,8 @@ type TLSSecurityProfile struct { // - ECDHE-RSA-AES256-GCM-SHA384 // - ECDHE-ECDSA-CHACHA20-POLY1305 // - ECDHE-RSA-CHACHA20-POLY1305 + // - DHE-RSA-AES128-GCM-SHA256 + // - DHE-RSA-AES256-GCM-SHA384 // // +optional // +nullable @@ -145,14 +160,12 @@ const ( // TLSProfileSpec is the desired behavior of a TLSSecurityProfile. type TLSProfileSpec struct { // ciphers is used to specify the cipher algorithms that are negotiated - // during the TLS handshake. Operators may remove entries that their operands - // do not support. For example, to use only ECDHE-RSA-AES128-GCM-SHA256 (yaml): + // during the TLS handshake. Operators may remove entries their operands + // do not support. For example, to use DES-CBC3-SHA (yaml): // // ciphers: - // - ECDHE-RSA-AES128-GCM-SHA256 + // - DES-CBC3-SHA // - // TLS 1.3 cipher suites (e.g. TLS_AES_128_GCM_SHA256) are not configurable - // and are always enabled when TLS 1.3 is negotiated. // +listType=atomic Ciphers []string `json:"ciphers"` // minTLSVersion is used to specify the minimal version of the TLS protocol @@ -187,11 +200,9 @@ const ( // TLSProfiles contains a map of TLSProfileType names to TLSProfileSpec. // -// These profiles are based on version 5.7 of the Mozilla Server Side TLS -// configuration guidelines. See: https://ssl-config.mozilla.org/guidelines/5.7.json -// -// Each Ciphers slice is the configuration's "ciphersuites" followed by the -// Go-specific "ciphers" from the guidelines JSON. +// These profiles are based on version 5.0 of the Mozilla Server Side TLS +// configuration guidelines (2019-06-28) with TLS 1.3 cipher suites prepended for +// forward compatibility. See: https://ssl-config.mozilla.org/guidelines/5.0.json // // NOTE: The caller needs to make sure to check that these constants are valid // for their binary. Not all entries map to values for all binaries. In the case @@ -209,15 +220,23 @@ var TLSProfiles = map[TLSProfileType]*TLSProfileSpec{ "ECDHE-RSA-AES256-GCM-SHA384", "ECDHE-ECDSA-CHACHA20-POLY1305", "ECDHE-RSA-CHACHA20-POLY1305", + "DHE-RSA-AES128-GCM-SHA256", + "DHE-RSA-AES256-GCM-SHA384", + "DHE-RSA-CHACHA20-POLY1305", "ECDHE-ECDSA-AES128-SHA256", "ECDHE-RSA-AES128-SHA256", "ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES128-SHA", + "ECDHE-ECDSA-AES256-SHA384", + "ECDHE-RSA-AES256-SHA384", "ECDHE-ECDSA-AES256-SHA", "ECDHE-RSA-AES256-SHA", + "DHE-RSA-AES128-SHA256", + "DHE-RSA-AES256-SHA256", "AES128-GCM-SHA256", "AES256-GCM-SHA384", "AES128-SHA256", + "AES256-SHA256", "AES128-SHA", "AES256-SHA", "DES-CBC3-SHA", @@ -235,6 +254,8 @@ var TLSProfiles = map[TLSProfileType]*TLSProfileSpec{ "ECDHE-RSA-AES256-GCM-SHA384", "ECDHE-ECDSA-CHACHA20-POLY1305", "ECDHE-RSA-CHACHA20-POLY1305", + "DHE-RSA-AES128-GCM-SHA256", + "DHE-RSA-AES256-GCM-SHA384", }, MinTLSVersion: VersionTLS12, }, diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml index eb7c485e03fc..5d4794e4bac5 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml @@ -6,7 +6,6 @@ apiservers.config.openshift.io: Capability: "" Category: "" FeatureGates: - - KMSEncryption - KMSEncryptionProvider FilenameOperatorName: config-operator FilenameOperatorOrdering: "01" @@ -417,7 +416,7 @@ insightsdatagathers.config.openshift.io: Annotations: {} ApprovedPRNumber: https://github.com/openshift/api/pull/2448 CRDName: insightsdatagathers.config.openshift.io - Capability: Insights + Capability: "" Category: "" FeatureGates: - InsightsConfig @@ -443,7 +442,8 @@ networks.config.openshift.io: CRDName: networks.config.openshift.io Capability: "" Category: "" - FeatureGates: [] + FeatureGates: + - NetworkDiagnosticsConfig FilenameOperatorName: config-operator FilenameOperatorOrdering: "01" FilenameRunLevel: "0000_10" diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go index 69fb37c5233c..e7bc0aebb336 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go @@ -407,11 +407,11 @@ func (ExtraMapping) SwaggerDoc() map[string]string { } var map_OIDCClientConfig = map[string]string{ - "": "OIDCClientConfig configures how platform clients interact with identity providers as an authentication method.", - "componentName": "componentName is a required field that specifies the name of the platform component being configured to use the identity provider as an authentication mode.\n\nIt is used in combination with componentNamespace as a unique identifier.\n\ncomponentName must not be an empty string (\"\") and must not exceed 256 characters in length.", - "componentNamespace": "componentNamespace is a required field that specifies the namespace in which the platform component being configured to use the identity provider as an authentication mode is running.\n\nIt is used in combination with componentName as a unique identifier.\n\ncomponentNamespace must not be an empty string (\"\") and must not exceed 63 characters in length.", + "": "OIDCClientConfig configures how platform clients interact with identity providers as an authentication method", + "componentName": "componentName is a required field that specifies the name of the platform component being configured to use the identity provider as an authentication mode. It is used in combination with componentNamespace as a unique identifier.\n\ncomponentName must not be an empty string (\"\") and must not exceed 256 characters in length.", + "componentNamespace": "componentNamespace is a required field that specifies the namespace in which the platform component being configured to use the identity provider as an authentication mode is running. It is used in combination with componentName as a unique identifier.\n\ncomponentNamespace must not be an empty string (\"\") and must not exceed 63 characters in length.", "clientID": "clientID is a required field that configures the client identifier, from the identity provider, that the platform component uses for authentication requests made to the identity provider. The identity provider must accept this identifier for platform components to be able to use the identity provider as an authentication mode.\n\nclientID must not be an empty string (\"\").", - "clientSecret": "clientSecret is an optional field that configures the client secret used by the platform component when making authentication requests to the identity provider.\n\nWhen not specified, no client secret will be used when making authentication requests to the identity provider.\n\nWhen specified, clientSecret references a Secret in the 'openshift-config' namespace that contains the client secret in the 'clientSecret' key of the '.data' field.\n\nThe client secret will be used when making authentication requests to the identity provider.\n\nPublic clients do not require a client secret but private clients do require a client secret to work with the identity provider.", + "clientSecret": "clientSecret is an optional field that configures the client secret used by the platform component when making authentication requests to the identity provider.\n\nWhen not specified, no client secret will be used when making authentication requests to the identity provider.\n\nWhen specified, clientSecret references a Secret in the 'openshift-config' namespace that contains the client secret in the 'clientSecret' key of the '.data' field. The client secret will be used when making authentication requests to the identity provider.\n\nPublic clients do not require a client secret but private clients do require a client secret to work with the identity provider.", "extraScopes": "extraScopes is an optional field that configures the extra scopes that should be requested by the platform component when making authentication requests to the identity provider. This is useful if you have configured claim mappings that requires specific scopes to be requested beyond the standard OIDC scopes.\n\nWhen omitted, no additional scopes are requested.", } @@ -433,8 +433,8 @@ func (OIDCClientReference) SwaggerDoc() map[string]string { var map_OIDCClientStatus = map[string]string{ "": "OIDCClientStatus represents the current state of platform components and how they interact with the configured identity providers.", "componentName": "componentName is a required field that specifies the name of the platform component using the identity provider as an authentication mode. It is used in combination with componentNamespace as a unique identifier.\n\ncomponentName must not be an empty string (\"\") and must not exceed 256 characters in length.", - "componentNamespace": "componentNamespace is a required field that specifies the namespace in which the platform component using the identity provider as an authentication mode is running.\n\nIt is used in combination with componentName as a unique identifier.\n\ncomponentNamespace must not be an empty string (\"\") and must not exceed 63 characters in length.", - "currentOIDCClients": "currentOIDCClients is an optional list of clients that the component is currently using.\n\nEntries must have unique issuerURL/clientID pairs.", + "componentNamespace": "componentNamespace is a required field that specifies the namespace in which the platform component using the identity provider as an authentication mode is running. It is used in combination with componentName as a unique identifier.\n\ncomponentNamespace must not be an empty string (\"\") and must not exceed 63 characters in length.", + "currentOIDCClients": "currentOIDCClients is an optional list of clients that the component is currently using. Entries must have unique issuerURL/clientID pairs.", "consumingUsers": "consumingUsers is an optional list of ServiceAccounts requiring read permissions on the `clientSecret` secret.\n\nconsumingUsers must not exceed 5 entries.", "conditions": "conditions are used to communicate the state of the `oidcClients` entry.\n\nSupported conditions include Available, Degraded and Progressing.\n\nIf Available is true, the component is successfully using the configured client. If Degraded is true, that means something has gone wrong trying to handle the client configuration. If Progressing is true, that means the component is taking some action related to the `oidcClients` entry.", } @@ -458,7 +458,7 @@ func (OIDCProvider) SwaggerDoc() map[string]string { var map_PrefixedClaimMapping = map[string]string{ "": "PrefixedClaimMapping configures a claim mapping that allows for an optional prefix.", - "prefix": "prefix is an optional field that configures the prefix that will be applied to the cluster identity attribute during the process of mapping JWT claims to cluster identity attributes.\n\nWhen omitted (\"\"), no prefix is applied to the cluster identity attribute.\n\nExample: if `prefix` is set to \"myoidc:\" and the `claim` in JWT contains an array of strings \"a\", \"b\" and \"c\", the mapping will result in an array of string \"myoidc:a\", \"myoidc:b\" and \"myoidc:c\".", + "prefix": "prefix is an optional field that configures the prefix that will be applied to the cluster identity attribute during the process of mapping JWT claims to cluster identity attributes.\n\nWhen omitted (\"\"), no prefix is applied to the cluster identity attribute.\n\nExample: if `prefix` is set to \"myoidc:\" and the `claim` in JWT contains an array of strings \"a\", \"b\" and \"c\", the mapping will result in an array of string \"myoidc:a\", \"myoidc:b\" and \"myoidc:c\".", } func (PrefixedClaimMapping) SwaggerDoc() map[string]string { @@ -476,9 +476,9 @@ func (TokenClaimMapping) SwaggerDoc() map[string]string { var map_TokenClaimMappings = map[string]string{ "username": "username is a required field that configures how the username of a cluster identity should be constructed from the claims in a JWT token issued by the identity provider.", - "groups": "groups is an optional field that configures how the groups of a cluster identity should be constructed from the claims in a JWT token issued by the identity provider.\n\nWhen referencing a claim, if the claim is present in the JWT token, its value must be a list of groups separated by a comma (',').\n\nFor example - '\"example\"' and '\"exampleOne\", \"exampleTwo\", \"exampleThree\"' are valid claim values.", - "uid": "uid is an optional field for configuring the claim mapping used to construct the uid for the cluster identity.\n\nWhen using uid.claim to specify the claim it must be a single string value. When using uid.expression the expression must result in a single string value.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose a default, which is subject to change over time.\n\nThe current default is to use the 'sub' claim.", - "extra": "extra is an optional field for configuring the mappings used to construct the extra attribute for the cluster identity. When omitted, no extra attributes will be present on the cluster identity.\n\nkey values for extra mappings must be unique. A maximum of 32 extra attribute mappings may be provided.", + "groups": "groups is an optional field that configures how the groups of a cluster identity should be constructed from the claims in a JWT token issued by the identity provider. When referencing a claim, if the claim is present in the JWT token, its value must be a list of groups separated by a comma (','). For example - '\"example\"' and '\"exampleOne\", \"exampleTwo\", \"exampleThree\"' are valid claim values.", + "uid": "uid is an optional field for configuring the claim mapping used to construct the uid for the cluster identity.\n\nWhen using uid.claim to specify the claim it must be a single string value. When using uid.expression the expression must result in a single string value.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose a default, which is subject to change over time. The current default is to use the 'sub' claim.", + "extra": "extra is an optional field for configuring the mappings used to construct the extra attribute for the cluster identity. When omitted, no extra attributes will be present on the cluster identity. key values for extra mappings must be unique. A maximum of 32 extra attribute mappings may be provided.", } func (TokenClaimMappings) SwaggerDoc() map[string]string { @@ -519,7 +519,7 @@ var map_TokenIssuer = map[string]string{ "issuerURL": "issuerURL is a required field that configures the URL used to issue tokens by the identity provider. The Kubernetes API server determines how authentication tokens should be handled by matching the 'iss' claim in the JWT to the issuerURL of configured identity providers.\n\nMust be at least 1 character and must not exceed 512 characters in length. Must be a valid URL that uses the 'https' scheme and does not contain a query, fragment or user.", "audiences": "audiences is a required field that configures the acceptable audiences the JWT token, issued by the identity provider, must be issued to. At least one of the entries must match the 'aud' claim in the JWT token.\n\naudiences must contain at least one entry and must not exceed ten entries.", "issuerCertificateAuthority": "issuerCertificateAuthority is an optional field that configures the certificate authority, used by the Kubernetes API server, to validate the connection to the identity provider when fetching discovery information.\n\nWhen not specified, the system trust is used.\n\nWhen specified, it must reference a ConfigMap in the openshift-config namespace containing the PEM-encoded CA certificates under the 'ca-bundle.crt' key in the data field of the ConfigMap.", - "discoveryURL": "discoveryURL is an optional field that, if specified, overrides the default discovery endpoint used to retrieve OIDC configuration metadata. By default, the discovery URL is derived from `issuerURL` as \"{issuerURL}/.well-known/openid-configuration\".\n\nThe discoveryURL must be a valid absolute HTTPS URL. It must not contain query parameters, user information, or fragments. Additionally, it must differ from the value of `issuerURL` (ignoring trailing slashes). The discoveryURL value must be at least 1 character long and no longer than 2048 characters.", + "discoveryURL": "discoveryURL is an optional field that, if specified, overrides the default discovery endpoint used to retrieve OIDC configuration metadata. By default, the discovery URL is derived from `issuerURL` as \"{issuerURL}/.well-known/openid-configuration\".\n\nThe discoveryURL must be a valid absolute HTTPS URL. It must not contain query parameters, user information, or fragments. Additionally, it must differ from the value of `url` (ignoring trailing slashes). The discoveryURL value must be at least 1 character long and no longer than 2048 characters.", } func (TokenIssuer) SwaggerDoc() map[string]string { @@ -537,7 +537,7 @@ func (TokenRequiredClaim) SwaggerDoc() map[string]string { var map_TokenUserValidationRule = map[string]string{ "": "TokenUserValidationRule provides a CEL-based rule used to validate a token subject. Each rule contains a CEL expression that is evaluated against the token’s claims.", - "expression": "expression is a required CEL expression that performs a validation on cluster user identity attributes like username, groups, etc.\n\nThe expression must evaluate to a boolean value. When the expression evaluates to 'true', the cluster user identity is considered valid. When the expression evaluates to 'false', the cluster user identity is not considered valid. expression must be at least 1 character in length and must not exceed 1024 characters.", + "expression": "expression is a required CEL expression that performs a validation on cluster user identity attributes like username, groups, etc. The expression must evaluate to a boolean value. When the expression evaluates to 'true', the cluster user identity is considered valid. When the expression evaluates to 'false', the cluster user identity is not considered valid. expression must be at least 1 character in length and must not exceed 1024 characters.", "message": "message is a required human-readable message to be logged by the Kubernetes API server if the CEL expression defined in 'expression' fails. message must be at least 1 character in length and must not exceed 256 characters.", } @@ -547,7 +547,7 @@ func (TokenUserValidationRule) SwaggerDoc() map[string]string { var map_UsernameClaimMapping = map[string]string{ "claim": "claim is a required field that configures the JWT token claim whose value is assigned to the cluster identity field associated with this mapping.\n\nclaim must not be an empty string (\"\") and must not exceed 256 characters.", - "prefixPolicy": "prefixPolicy is an optional field that configures how a prefix should be applied to the value of the JWT claim specified in the 'claim' field.\n\nAllowed values are 'Prefix', 'NoPrefix', and omitted (not provided or an empty string).\n\nWhen set to 'Prefix', the value specified in the prefix field will be prepended to the value of the JWT claim.\n\nThe prefix field must be set when prefixPolicy is 'Prefix'.\n\nWhen set to 'NoPrefix', no prefix will be prepended to the value of the JWT claim.\n\nWhen omitted, this means no opinion and the platform is left to choose any prefixes that are applied which is subject to change over time. Currently, the platform prepends `{issuerURL}#` to the value of the JWT claim when the claim is not 'email'.\n\nAs an example, consider the following scenario:\n\n `prefix` is unset, `issuerURL` is set to `https://myoidc.tld`,\n the JWT claims include \"username\":\"userA\" and \"email\":\"userA@myoidc.tld\",\n and `claim` is set to:\n - \"username\": the mapped value will be \"https://myoidc.tld#userA\"\n - \"email\": the mapped value will be \"userA@myoidc.tld\"", + "prefixPolicy": "prefixPolicy is an optional field that configures how a prefix should be applied to the value of the JWT claim specified in the 'claim' field.\n\nAllowed values are 'Prefix', 'NoPrefix', and omitted (not provided or an empty string).\n\nWhen set to 'Prefix', the value specified in the prefix field will be prepended to the value of the JWT claim. The prefix field must be set when prefixPolicy is 'Prefix'.\n\nWhen set to 'NoPrefix', no prefix will be prepended to the value of the JWT claim.\n\nWhen omitted, this means no opinion and the platform is left to choose any prefixes that are applied which is subject to change over time. Currently, the platform prepends `{issuerURL}#` to the value of the JWT claim when the claim is not 'email'. As an example, consider the following scenario:\n `prefix` is unset, `issuerURL` is set to `https://myoidc.tld`,\n the JWT claims include \"username\":\"userA\" and \"email\":\"userA@myoidc.tld\",\n and `claim` is set to:\n - \"username\": the mapped value will be \"https://myoidc.tld#userA\"\n - \"email\": the mapped value will be \"userA@myoidc.tld\"", "prefix": "prefix configures the prefix that should be prepended to the value of the JWT claim.\n\nprefix must be set when prefixPolicy is set to 'Prefix' and must be unset otherwise.", } @@ -1924,7 +1924,7 @@ func (OvirtPlatformStatus) SwaggerDoc() map[string]string { var map_PlatformSpec = map[string]string{ "": "PlatformSpec holds the desired state specific to the underlying infrastructure provider of the current cluster. Since these are used at spec-level for the underlying cluster, it is supposed that only one of the spec structs is set.", - "type": "type is the underlying infrastructure provider for the cluster. This value controls whether infrastructure automation such as service load balancers, dynamic volume provisioning, machine creation and deletion, and other integrations are enabled. If None, no infrastructure automation is enabled. Allowed values are \"AWS\", \"Azure\", \"BareMetal\", \"GCP\", \"Libvirt\", \"OpenStack\", \"VSphere\", \"oVirt\", \"IBMCloud\", \"KubeVirt\", \"EquinixMetal\", \"PowerVS\", \"AlibabaCloud\", \"Nutanix\", \"External\", and \"None\". Individual components may not support all platforms, and must handle unrecognized platforms as None if they do not support that platform.", + "type": "type is the underlying infrastructure provider for the cluster. This value controls whether infrastructure automation such as service load balancers, dynamic volume provisioning, machine creation and deletion, and other integrations are enabled. If None, no infrastructure automation is enabled. Allowed values are \"AWS\", \"Azure\", \"BareMetal\", \"GCP\", \"Libvirt\", \"OpenStack\", \"VSphere\", \"oVirt\", \"KubeVirt\", \"EquinixMetal\", \"PowerVS\", \"AlibabaCloud\", \"Nutanix\" and \"None\". Individual components may not support all platforms, and must handle unrecognized platforms as None if they do not support that platform.", "aws": "aws contains settings specific to the Amazon Web Services infrastructure provider.", "azure": "azure contains settings specific to the Azure infrastructure provider.", "gcp": "gcp contains settings specific to the Google Cloud Platform infrastructure provider.", @@ -3004,7 +3004,7 @@ func (OldTLSProfile) SwaggerDoc() map[string]string { var map_TLSProfileSpec = map[string]string{ "": "TLSProfileSpec is the desired behavior of a TLSSecurityProfile.", - "ciphers": "ciphers is used to specify the cipher algorithms that are negotiated during the TLS handshake. Operators may remove entries that their operands do not support. For example, to use only ECDHE-RSA-AES128-GCM-SHA256 (yaml):\n\n ciphers:\n - ECDHE-RSA-AES128-GCM-SHA256\n\nTLS 1.3 cipher suites (e.g. TLS_AES_128_GCM_SHA256) are not configurable and are always enabled when TLS 1.3 is negotiated.", + "ciphers": "ciphers is used to specify the cipher algorithms that are negotiated during the TLS handshake. Operators may remove entries their operands do not support. For example, to use DES-CBC3-SHA (yaml):\n\n ciphers:\n - DES-CBC3-SHA", "minTLSVersion": "minTLSVersion is used to specify the minimal version of the TLS protocol that is negotiated during the TLS handshake. For example, to use TLS versions 1.1, 1.2 and 1.3 (yaml):\n\n minTLSVersion: VersionTLS11", } @@ -3014,9 +3014,9 @@ func (TLSProfileSpec) SwaggerDoc() map[string]string { var map_TLSSecurityProfile = map[string]string{ "": "TLSSecurityProfile defines the schema for a TLS security profile. This object is used by operators to apply TLS security settings to operands.", - "type": "type is one of Old, Intermediate, Modern or Custom. Custom provides the ability to specify individual TLS security profile parameters.\n\nThe profiles are based on version 5.7 of the Mozilla Server Side TLS configuration guidelines. The cipher lists consist of the configuration's \"ciphersuites\" followed by the Go-specific \"ciphers\" from the guidelines. See: https://ssl-config.mozilla.org/guidelines/5.7.json\n\nThe profiles are intent based, so they may change over time as new ciphers are developed and existing ciphers are found to be insecure. Depending on precisely which ciphers are available to a process, the list may be reduced.", - "old": "old is a TLS profile for use when services need to be accessed by very old clients or libraries and should be used only as a last resort.\n\nThis profile is equivalent to a Custom profile specified as:\n minTLSVersion: VersionTLS10\n ciphers:\n - TLS_AES_128_GCM_SHA256\n - TLS_AES_256_GCM_SHA384\n - TLS_CHACHA20_POLY1305_SHA256\n - ECDHE-ECDSA-AES128-GCM-SHA256\n - ECDHE-RSA-AES128-GCM-SHA256\n - ECDHE-ECDSA-AES256-GCM-SHA384\n - ECDHE-RSA-AES256-GCM-SHA384\n - ECDHE-ECDSA-CHACHA20-POLY1305\n - ECDHE-RSA-CHACHA20-POLY1305\n - ECDHE-ECDSA-AES128-SHA256\n - ECDHE-RSA-AES128-SHA256\n - ECDHE-ECDSA-AES128-SHA\n - ECDHE-RSA-AES128-SHA\n - ECDHE-ECDSA-AES256-SHA\n - ECDHE-RSA-AES256-SHA\n - AES128-GCM-SHA256\n - AES256-GCM-SHA384\n - AES128-SHA256\n - AES128-SHA\n - AES256-SHA\n - DES-CBC3-SHA", - "intermediate": "intermediate is a TLS profile for use when you do not need compatibility with legacy clients and want to remain highly secure while being compatible with most clients currently in use.\n\nThis profile is equivalent to a Custom profile specified as:\n minTLSVersion: VersionTLS12\n ciphers:\n - TLS_AES_128_GCM_SHA256\n - TLS_AES_256_GCM_SHA384\n - TLS_CHACHA20_POLY1305_SHA256\n - ECDHE-ECDSA-AES128-GCM-SHA256\n - ECDHE-RSA-AES128-GCM-SHA256\n - ECDHE-ECDSA-AES256-GCM-SHA384\n - ECDHE-RSA-AES256-GCM-SHA384\n - ECDHE-ECDSA-CHACHA20-POLY1305\n - ECDHE-RSA-CHACHA20-POLY1305", + "type": "type is one of Old, Intermediate, Modern or Custom. Custom provides the ability to specify individual TLS security profile parameters.\n\nThe profiles are currently based on version 5.0 of the Mozilla Server Side TLS configuration guidelines (released 2019-06-28) with TLS 1.3 ciphers added for forward compatibility. See: https://ssl-config.mozilla.org/guidelines/5.0.json\n\nThe profiles are intent based, so they may change over time as new ciphers are developed and existing ciphers are found to be insecure. Depending on precisely which ciphers are available to a process, the list may be reduced.", + "old": "old is a TLS profile for use when services need to be accessed by very old clients or libraries and should be used only as a last resort.\n\nThe cipher list includes TLS 1.3 ciphers for forward compatibility, followed by the \"old\" profile ciphers.\n\nThis profile is equivalent to a Custom profile specified as:\n minTLSVersion: VersionTLS10\n ciphers:\n - TLS_AES_128_GCM_SHA256\n - TLS_AES_256_GCM_SHA384\n - TLS_CHACHA20_POLY1305_SHA256\n - ECDHE-ECDSA-AES128-GCM-SHA256\n - ECDHE-RSA-AES128-GCM-SHA256\n - ECDHE-ECDSA-AES256-GCM-SHA384\n - ECDHE-RSA-AES256-GCM-SHA384\n - ECDHE-ECDSA-CHACHA20-POLY1305\n - ECDHE-RSA-CHACHA20-POLY1305\n - DHE-RSA-AES128-GCM-SHA256\n - DHE-RSA-AES256-GCM-SHA384\n - DHE-RSA-CHACHA20-POLY1305\n - ECDHE-ECDSA-AES128-SHA256\n - ECDHE-RSA-AES128-SHA256\n - ECDHE-ECDSA-AES128-SHA\n - ECDHE-RSA-AES128-SHA\n - ECDHE-ECDSA-AES256-SHA384\n - ECDHE-RSA-AES256-SHA384\n - ECDHE-ECDSA-AES256-SHA\n - ECDHE-RSA-AES256-SHA\n - DHE-RSA-AES128-SHA256\n - DHE-RSA-AES256-SHA256\n - AES128-GCM-SHA256\n - AES256-GCM-SHA384\n - AES128-SHA256\n - AES256-SHA256\n - AES128-SHA\n - AES256-SHA\n - DES-CBC3-SHA", + "intermediate": "intermediate is a TLS profile for use when you do not need compatibility with legacy clients and want to remain highly secure while being compatible with most clients currently in use.\n\nThe cipher list includes TLS 1.3 ciphers for forward compatibility, followed by the \"intermediate\" profile ciphers.\n\nThis profile is equivalent to a Custom profile specified as:\n minTLSVersion: VersionTLS12\n ciphers:\n - TLS_AES_128_GCM_SHA256\n - TLS_AES_256_GCM_SHA384\n - TLS_CHACHA20_POLY1305_SHA256\n - ECDHE-ECDSA-AES128-GCM-SHA256\n - ECDHE-RSA-AES128-GCM-SHA256\n - ECDHE-ECDSA-AES256-GCM-SHA384\n - ECDHE-RSA-AES256-GCM-SHA384\n - ECDHE-ECDSA-CHACHA20-POLY1305\n - ECDHE-RSA-CHACHA20-POLY1305\n - DHE-RSA-AES128-GCM-SHA256\n - DHE-RSA-AES256-GCM-SHA384", "modern": "modern is a TLS security profile for use with clients that support TLS 1.3 and do not need backward compatibility for older clients.\n\nThis profile is equivalent to a Custom profile specified as:\n minTLSVersion: VersionTLS13\n ciphers:\n - TLS_AES_128_GCM_SHA256\n - TLS_AES_256_GCM_SHA384\n - TLS_CHACHA20_POLY1305_SHA256", "custom": "custom is a user-defined TLS security profile. Be extremely careful using a custom profile as invalid configurations can be catastrophic. An example custom profile looks like this:\n\n minTLSVersion: VersionTLS11\n ciphers:\n - ECDHE-ECDSA-CHACHA20-POLY1305\n - ECDHE-RSA-CHACHA20-POLY1305\n - ECDHE-RSA-AES128-GCM-SHA256\n - ECDHE-ECDSA-AES128-GCM-SHA256", } diff --git a/vendor/github.com/openshift/api/config/v1alpha1/register.go b/vendor/github.com/openshift/api/config/v1alpha1/register.go index c90962495050..4b30ea380b1d 100644 --- a/vendor/github.com/openshift/api/config/v1alpha1/register.go +++ b/vendor/github.com/openshift/api/config/v1alpha1/register.go @@ -40,8 +40,6 @@ func addKnownTypes(scheme *runtime.Scheme) error { &ImagePolicyList{}, &ClusterImagePolicy{}, &ClusterImagePolicyList{}, - &CRIOCredentialProviderConfig{}, - &CRIOCredentialProviderConfigList{}, ) metav1.AddToGroupVersion(scheme, GroupVersion) return nil diff --git a/vendor/github.com/openshift/api/config/v1alpha1/types_backup.go b/vendor/github.com/openshift/api/config/v1alpha1/types_backup.go index 0f3da5184752..77df372d43ef 100644 --- a/vendor/github.com/openshift/api/config/v1alpha1/types_backup.go +++ b/vendor/github.com/openshift/api/config/v1alpha1/types_backup.go @@ -93,7 +93,7 @@ type EtcdBackupSpec struct { PVCName string `json:"pvcName"` } -// RetentionType is the enumeration of valid retention policy types. +// RetentionType is the enumeration of valid retention policy types // +enum // +kubebuilder:validation:Enum:="RetentionNumber";"RetentionSize" type RetentionType string @@ -115,6 +115,7 @@ type RetentionPolicy struct { // The current default is RetentionNumber with 15 backups kept. // +unionDiscriminator // +required + // +kubebuilder:validation:Enum:="";"RetentionNumber";"RetentionSize" RetentionType RetentionType `json:"retentionType"` // retentionNumber configures the retention policy based on the number of backups diff --git a/vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go b/vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go index 29bf8ba4884e..0653eeb5a5ed 100644 --- a/vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go +++ b/vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go @@ -94,11 +94,6 @@ type ClusterMonitoringSpec struct { // When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. // +optional MetricsServerConfig MetricsServerConfig `json:"metricsServerConfig,omitempty,omitzero"` - // prometheusOperatorConfig is an optional field that can be used to configure the Prometheus Operator component. - // Specifically, it can configure how the Prometheus Operator instance is deployed, pod scheduling, and resource allocation. - // When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. - // +optional - PrometheusOperatorConfig PrometheusOperatorConfig `json:"prometheusOperatorConfig,omitempty,omitzero"` } // UserDefinedMonitoring config for user-defined projects. @@ -190,7 +185,6 @@ type AlertmanagerCustomConfig struct { // limit: null // Maximum length for this list is 10. // Minimum length for this list is 1. - // Each resource name must be unique within this list. // +optional // +listType=map // +listMapKey=name @@ -224,8 +218,8 @@ type AlertmanagerCustomConfig struct { // When omitted, this means the user has no opinion and the platform is left // to choose reasonable defaults. These defaults are subject to change over time. // Defaults are empty/unset. - // Maximum length for this list is 10. - // Minimum length for this list is 1. + // Maximum length for this list is 10 + // Minimum length for this list is 1 // +kubebuilder:validation:MaxItems=10 // +kubebuilder:validation:MinItems=1 // +listType=atomic @@ -241,7 +235,7 @@ type AlertmanagerCustomConfig struct { // This field maps directly to the `topologySpreadConstraints` field in the Pod spec. // Default is empty list. // Maximum length for this list is 10. - // Minimum length for this list is 1. + // Minimum length for this list is 1 // Entries must have unique topologyKey and whenUnsatisfiable pairs. // +kubebuilder:validation:MaxItems=10 // +kubebuilder:validation:MinItems=1 @@ -362,8 +356,8 @@ type MetricsServerConfig struct { // When omitted, this means the user has no opinion and the platform is left // to choose reasonable defaults. These defaults are subject to change over time. // Defaults are empty/unset. - // Maximum length for this list is 10. - // Minimum length for this list is 1. + // Maximum length for this list is 10 + // Minimum length for this list is 1 // +kubebuilder:validation:MaxItems=10 // +kubebuilder:validation:MinItems=1 // +listType=atomic @@ -395,7 +389,6 @@ type MetricsServerConfig struct { // limit: null // Maximum length for this list is 10. // Minimum length for this list is 1. - // Each resource name must be unique within this list. // +optional // +listType=map // +listMapKey=name @@ -412,91 +405,7 @@ type MetricsServerConfig struct { // This field maps directly to the `topologySpreadConstraints` field in the Pod spec. // Default is empty list. // Maximum length for this list is 10. - // Minimum length for this list is 1. - // Entries must have unique topologyKey and whenUnsatisfiable pairs. - // +kubebuilder:validation:MaxItems=10 - // +kubebuilder:validation:MinItems=1 - // +listType=map - // +listMapKey=topologyKey - // +listMapKey=whenUnsatisfiable - // +optional - TopologySpreadConstraints []v1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` -} - -// PrometheusOperatorConfig provides configuration options for the Prometheus Operator instance -// Use this configuration to control how the Prometheus Operator instance is deployed, how it logs, and how its pods are scheduled. -// +kubebuilder:validation:MinProperties=1 -type PrometheusOperatorConfig struct { - // logLevel defines the verbosity of logs emitted by Prometheus Operator. - // This field allows users to control the amount and severity of logs generated, which can be useful - // for debugging issues or reducing noise in production environments. - // Allowed values are Error, Warn, Info, and Debug. - // When set to Error, only errors will be logged. - // When set to Warn, both warnings and errors will be logged. - // When set to Info, general information, warnings, and errors will all be logged. - // When set to Debug, detailed debugging information will be logged. - // When omitted, this means no opinion and the platform is left to choose a reasonable default, that is subject to change over time. - // The current default value is `Info`. - // +optional - LogLevel LogLevel `json:"logLevel,omitempty"` - // nodeSelector defines the nodes on which the Pods are scheduled - // nodeSelector is optional. - // - // When omitted, this means the user has no opinion and the platform is left - // to choose reasonable defaults. These defaults are subject to change over time. - // The current default value is `kubernetes.io/os: linux`. - // When specified, nodeSelector must contain at least 1 entry and must not contain more than 10 entries. - // +optional - // +kubebuilder:validation:MinProperties=1 - // +kubebuilder:validation:MaxProperties=10 - NodeSelector map[string]string `json:"nodeSelector,omitempty"` - // resources defines the compute resource requests and limits for the Prometheus Operator container. - // This includes CPU, memory and HugePages constraints to help control scheduling and resource usage. - // When not specified, defaults are used by the platform. Requests cannot exceed limits. - // This field is optional. - // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - // This is a simplified API that maps to Kubernetes ResourceRequirements. - // The current default values are: - // resources: - // - name: cpu - // request: 4m - // limit: null - // - name: memory - // request: 40Mi - // limit: null - // Maximum length for this list is 10. - // Minimum length for this list is 1. - // Each resource name must be unique within this list. - // +optional - // +listType=map - // +listMapKey=name - // +kubebuilder:validation:MaxItems=10 - // +kubebuilder:validation:MinItems=1 - Resources []ContainerResource `json:"resources,omitempty"` - // tolerations defines tolerations for the pods. - // tolerations is optional. - // - // When omitted, this means the user has no opinion and the platform is left - // to choose reasonable defaults. These defaults are subject to change over time. - // Defaults are empty/unset. - // Maximum length for this list is 10. - // Minimum length for this list is 1. - // +kubebuilder:validation:MaxItems=10 - // +kubebuilder:validation:MinItems=1 - // +listType=atomic - // +optional - Tolerations []v1.Toleration `json:"tolerations,omitempty"` - // topologySpreadConstraints defines rules for how Prometheus Operator Pods should be distributed - // across topology domains such as zones, nodes, or other user-defined labels. - // topologySpreadConstraints is optional. - // This helps improve high availability and resource efficiency by avoiding placing - // too many replicas in the same failure domain. - // - // When omitted, this means no opinion and the platform is left to choose a default, which is subject to change over time. - // This field maps directly to the `topologySpreadConstraints` field in the Pod spec. - // Default is empty list. - // Maximum length for this list is 10. - // Minimum length for this list is 1. + // Minimum length for this list is 1 // Entries must have unique topologyKey and whenUnsatisfiable pairs. // +kubebuilder:validation:MaxItems=10 // +kubebuilder:validation:MinItems=1 diff --git a/vendor/github.com/openshift/api/config/v1alpha1/types_crio_credential_provider_config.go b/vendor/github.com/openshift/api/config/v1alpha1/types_crio_credential_provider_config.go deleted file mode 100644 index 9e2e0d39d28f..000000000000 --- a/vendor/github.com/openshift/api/config/v1alpha1/types_crio_credential_provider_config.go +++ /dev/null @@ -1,186 +0,0 @@ -package v1alpha1 - -import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - -// +genclient -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// CRIOCredentialProviderConfig holds cluster-wide singleton resource configurations for CRI-O credential provider, the name of this instance is "cluster". CRI-O credential provider is a binary shipped with CRI-O that provides a way to obtain container image pull credentials from external sources. -// For example, it can be used to fetch mirror registry credentials from secrets resources in the cluster within the same namespace the pod will be running in. -// CRIOCredentialProviderConfig configuration specifies the pod image sources registries that should trigger the CRI-O credential provider execution, which will resolve the CRI-O mirror configurations and obtain the necessary credentials for pod creation. -// Note: Configuration changes will only take effect after the kubelet restarts, which is automatically managed by the cluster during rollout. -// -// The resource is a singleton named "cluster". -// -// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support. -// +kubebuilder:object:root=true -// +kubebuilder:resource:path=criocredentialproviderconfigs,scope=Cluster -// +kubebuilder:subresource:status -// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/2557 -// +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01 -// +openshift:enable:FeatureGate=CRIOCredentialProviderConfig -// +openshift:compatibility-gen:level=4 -// +kubebuilder:validation:XValidation:rule="self.metadata.name == 'cluster'",message="criocredentialproviderconfig is a singleton, .metadata.name must be 'cluster'" -type CRIOCredentialProviderConfig struct { - metav1.TypeMeta `json:",inline"` - - // metadata is the standard object's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ObjectMeta `json:"metadata,omitzero"` - - // spec defines the desired configuration of the CRI-O Credential Provider. - // This field is required and must be provided when creating the resource. - // +required - Spec *CRIOCredentialProviderConfigSpec `json:"spec,omitempty,omitzero"` - - // status represents the current state of the CRIOCredentialProviderConfig. - // When omitted or nil, it indicates that the status has not yet been set by the controller. - // The controller will populate this field with validation conditions and operational state. - // +optional - Status CRIOCredentialProviderConfigStatus `json:"status,omitzero,omitempty"` -} - -// CRIOCredentialProviderConfigSpec defines the desired configuration of the CRI-O Credential Provider. -// +kubebuilder:validation:MinProperties=0 -type CRIOCredentialProviderConfigSpec struct { - // matchImages is a list of string patterns used to determine whether - // the CRI-O credential provider should be invoked for a given image. This list is - // passed to the kubelet CredentialProviderConfig, and if any pattern matches - // the requested image, CRI-O credential provider will be invoked to obtain credentials for pulling - // that image or its mirrors. - // Depending on the platform, the CRI-O credential provider may be installed alongside an existing platform specific provider. - // Conflicts between the existing platform specific provider image match configuration and this list will be handled by - // the following precedence rule: credentials from built-in kubelet providers (e.g., ECR, GCR, ACR) take precedence over those - // from the CRIOCredentialProviderConfig when both match the same image. - // To avoid uncertainty, it is recommended to avoid configuring your private image patterns to overlap with - // existing platform specific provider config(e.g., the entries from https://github.com/openshift/machine-config-operator/blob/main/templates/common/aws/files/etc-kubernetes-credential-providers-ecr-credential-provider.yaml). - // You can check the resource's Status conditions - // to see if any entries were ignored due to exact matches with known built-in provider patterns. - // - // This field is optional, the items of the list must contain between 1 and 50 entries. - // The list is treated as a set, so duplicate entries are not allowed. - // - // For more details, see: - // https://kubernetes.io/docs/tasks/administer-cluster/kubelet-credential-provider/ - // https://github.com/cri-o/crio-credential-provider#architecture - // - // Each entry in matchImages is a pattern which can optionally contain a port and a path. Each entry must be no longer than 512 characters. - // Wildcards ('*') are supported for full subdomain labels, such as '*.k8s.io' or 'k8s.*.io', - // and for top-level domains, such as 'k8s.*' (which matches 'k8s.io' or 'k8s.net'). - // A global wildcard '*' (matching any domain) is not allowed. - // Wildcards may replace an entire hostname label (e.g., *.example.com), but they cannot appear within a label (e.g., f*oo.example.com) and are not allowed in the port or path. - // For example, 'example.*.com' is valid, but 'exa*mple.*.com' is not. - // Each wildcard matches only a single domain label, - // so '*.io' does **not** match '*.k8s.io'. - // - // A match exists between an image and a matchImage when all of the below are true: - // Both contain the same number of domain parts and each part matches. - // The URL path of an matchImages must be a prefix of the target image URL path. - // If the matchImages contains a port, then the port must match in the image as well. - // - // Example values of matchImages: - // - 123456789.dkr.ecr.us-east-1.amazonaws.com - // - *.azurecr.io - // - gcr.io - // - *.*.registry.io - // - registry.io:8080/path - // - // +kubebuilder:validation:MaxItems=50 - // +kubebuilder:validation:MinItems=1 - // +listType=set - // +optional - MatchImages []MatchImage `json:"matchImages,omitempty"` -} - -// MatchImage is a string pattern used to match container image registry addresses. -// It must be a valid fully qualified domain name with optional wildcard, port, and path. -// The maximum length is 512 characters. -// -// Wildcards ('*') are supported for full subdomain labels and top-level domains. -// Each entry can optionally contain a port (e.g., :8080) and a path (e.g., /path). -// Wildcards are not allowed in the port or path portions. -// -// Examples: -// - "registry.io" - matches exactly registry.io -// - "*.azurecr.io" - matches any single subdomain of azurecr.io -// - "registry.io:8080/path" - matches with specific port and path prefix -// -// +kubebuilder:validation:MaxLength=512 -// +kubebuilder:validation:MinLength=1 -// +kubebuilder:validation:XValidation:rule="self != '*'",message="global wildcard '*' is not allowed" -// +kubebuilder:validation:XValidation:rule=`self.matches('^((\\*|[a-z0-9]([a-z0-9-]*[a-z0-9])?)(\\.(\\*|[a-z0-9]([a-z0-9-]*[a-z0-9])?))*)(:[0-9]+)?(/[-a-z0-9._/]*)?$')`,message="invalid matchImages value, must be a valid fully qualified domain name in lowercase with optional wildcard, port, and path" -type MatchImage string - -// +k8s:deepcopy-gen=true -// CRIOCredentialProviderConfigStatus defines the observed state of CRIOCredentialProviderConfig -// +kubebuilder:validation:MinProperties=1 -type CRIOCredentialProviderConfigStatus struct { - // conditions represent the latest available observations of the configuration state. - // When omitted, it indicates that no conditions have been reported yet. - // The maximum number of conditions is 16. - // Conditions are stored as a map keyed by condition type, ensuring uniqueness. - // - // Expected condition types include: - // "Validated": indicates whether the matchImages configuration is valid - // +optional - // +kubebuilder:validation:MaxItems=16 - // +kubebuilder:validation:MinItems=1 - // +listType=map - // +listMapKey=type - Conditions []metav1.Condition `json:"conditions,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// CRIOCredentialProviderConfigList contains a list of CRIOCredentialProviderConfig resources -// -// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support. -// +openshift:compatibility-gen:level=4 -type CRIOCredentialProviderConfigList struct { - metav1.TypeMeta `json:",inline"` - - // metadata is the standard list's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - metav1.ListMeta `json:"metadata"` - - Items []CRIOCredentialProviderConfig `json:"items"` -} - -const ( - // ConditionTypeValidated is a condition type that indicates whether the CRIOCredentialProviderConfig - // matchImages configuration has been validated successfully. - // When True, all matchImage patterns are valid and have been applied. - // When False, the configuration contains errors (see Reason for details). - // Possible reasons for False status: - // - ValidationFailed: matchImages contains invalid patterns - // - ConfigurationPartiallyApplied: some matchImage entries were ignored due to conflicts - ConditionTypeValidated = "Validated" - - // ReasonValidationFailed is a condition reason used with ConditionTypeValidated=False - // to indicate that the matchImages configuration contains one or more invalid registry patterns - // that do not conform to the required format (valid FQDN with optional wildcard, port, and path). - ReasonValidationFailed = "ValidationFailed" - - // ReasonConfigurationPartiallyApplied is a condition reason used with ConditionTypeValidated=False - // to indicate that some matchImage entries were ignored due to conflicts or overlapping patterns. - // The condition message will contain details about which entries were ignored and why. - ReasonConfigurationPartiallyApplied = "ConfigurationPartiallyApplied" - - // ConditionTypeMachineConfigRendered is a condition type that indicates whether - // the CRIOCredentialProviderConfig has been successfully rendered into a - // MachineConfig object. - // When True, the corresponding MachineConfig is present in the cluster. - // When False, rendering failed. - ConditionTypeMachineConfigRendered = "MachineConfigRendered" - - // ReasonMachineConfigRenderingSucceeded is a condition reason used with ConditionTypeMachineConfigRendered=True - // to indicate that the MachineConfig was successfully created/updated in the API server. - ReasonMachineConfigRenderingSucceeded = "MachineConfigRenderingSucceeded" - - // ReasonMachineConfigRenderingFailed is a condition reason used with ConditionTypeMachineConfigRendered=False - // to indicate that the MachineConfig creation/update failed. - // The condition message will contain details about the failure. - ReasonMachineConfigRenderingFailed = "MachineConfigRenderingFailed" -) diff --git a/vendor/github.com/openshift/api/config/v1alpha1/types_insights.go b/vendor/github.com/openshift/api/config/v1alpha1/types_insights.go index bef31b905aba..46666ae3b23b 100644 --- a/vendor/github.com/openshift/api/config/v1alpha1/types_insights.go +++ b/vendor/github.com/openshift/api/config/v1alpha1/types_insights.go @@ -16,7 +16,6 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01 // +openshift:enable:FeatureGate=InsightsConfig // +openshift:compatibility-gen:level=4 -// +openshift:capability=Insights type InsightsDataGather struct { metav1.TypeMeta `json:",inline"` diff --git a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go index dc51326b9702..9ead6aba26b3 100644 --- a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go @@ -192,115 +192,6 @@ func (in *BackupStatus) DeepCopy() *BackupStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CRIOCredentialProviderConfig) DeepCopyInto(out *CRIOCredentialProviderConfig) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - if in.Spec != nil { - in, out := &in.Spec, &out.Spec - *out = new(CRIOCredentialProviderConfigSpec) - (*in).DeepCopyInto(*out) - } - in.Status.DeepCopyInto(&out.Status) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CRIOCredentialProviderConfig. -func (in *CRIOCredentialProviderConfig) DeepCopy() *CRIOCredentialProviderConfig { - if in == nil { - return nil - } - out := new(CRIOCredentialProviderConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *CRIOCredentialProviderConfig) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CRIOCredentialProviderConfigList) DeepCopyInto(out *CRIOCredentialProviderConfigList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]CRIOCredentialProviderConfig, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CRIOCredentialProviderConfigList. -func (in *CRIOCredentialProviderConfigList) DeepCopy() *CRIOCredentialProviderConfigList { - if in == nil { - return nil - } - out := new(CRIOCredentialProviderConfigList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *CRIOCredentialProviderConfigList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CRIOCredentialProviderConfigSpec) DeepCopyInto(out *CRIOCredentialProviderConfigSpec) { - *out = *in - if in.MatchImages != nil { - in, out := &in.MatchImages, &out.MatchImages - *out = make([]MatchImage, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CRIOCredentialProviderConfigSpec. -func (in *CRIOCredentialProviderConfigSpec) DeepCopy() *CRIOCredentialProviderConfigSpec { - if in == nil { - return nil - } - out := new(CRIOCredentialProviderConfigSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CRIOCredentialProviderConfigStatus) DeepCopyInto(out *CRIOCredentialProviderConfigStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]metav1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CRIOCredentialProviderConfigStatus. -func (in *CRIOCredentialProviderConfigStatus) DeepCopy() *CRIOCredentialProviderConfigStatus { - if in == nil { - return nil - } - out := new(CRIOCredentialProviderConfigStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterImagePolicy) DeepCopyInto(out *ClusterImagePolicy) { *out = *in @@ -474,7 +365,6 @@ func (in *ClusterMonitoringSpec) DeepCopyInto(out *ClusterMonitoringSpec) { out.UserDefined = in.UserDefined in.AlertmanagerConfig.DeepCopyInto(&out.AlertmanagerConfig) in.MetricsServerConfig.DeepCopyInto(&out.MetricsServerConfig) - in.PrometheusOperatorConfig.DeepCopyInto(&out.PrometheusOperatorConfig) return } @@ -1062,50 +952,6 @@ func (in *PolicyRootOfTrust) DeepCopy() *PolicyRootOfTrust { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PrometheusOperatorConfig) DeepCopyInto(out *PrometheusOperatorConfig) { - *out = *in - if in.NodeSelector != nil { - in, out := &in.NodeSelector, &out.NodeSelector - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = make([]ContainerResource, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Tolerations != nil { - in, out := &in.Tolerations, &out.Tolerations - *out = make([]v1.Toleration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.TopologySpreadConstraints != nil { - in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints - *out = make([]v1.TopologySpreadConstraint, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PrometheusOperatorConfig. -func (in *PrometheusOperatorConfig) DeepCopy() *PrometheusOperatorConfig { - if in == nil { - return nil - } - out := new(PrometheusOperatorConfig) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RetentionNumberConfig) DeepCopyInto(out *RetentionNumberConfig) { *out = *in diff --git a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.featuregated-crd-manifests.yaml index 14091b5872b1..2f79f801dd40 100644 --- a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.featuregated-crd-manifests.yaml @@ -21,29 +21,6 @@ backups.config.openshift.io: - AutomatedEtcdBackup Version: v1alpha1 -criocredentialproviderconfigs.config.openshift.io: - Annotations: {} - ApprovedPRNumber: https://github.com/openshift/api/pull/2557 - CRDName: criocredentialproviderconfigs.config.openshift.io - Capability: "" - Category: "" - FeatureGates: - - CRIOCredentialProviderConfig - FilenameOperatorName: config-operator - FilenameOperatorOrdering: "01" - FilenameRunLevel: "0000_10" - GroupName: config.openshift.io - HasStatus: true - KindName: CRIOCredentialProviderConfig - Labels: {} - PluralName: criocredentialproviderconfigs - PrinterColumns: [] - Scope: Cluster - ShortNames: null - TopLevelFeatureGates: - - CRIOCredentialProviderConfig - Version: v1alpha1 - clusterimagepolicies.config.openshift.io: Annotations: {} ApprovedPRNumber: https://github.com/openshift/api/pull/1457 @@ -120,7 +97,7 @@ insightsdatagathers.config.openshift.io: Annotations: {} ApprovedPRNumber: https://github.com/openshift/api/pull/1245 CRDName: insightsdatagathers.config.openshift.io - Capability: Insights + Capability: "" Category: "" FeatureGates: - InsightsConfig diff --git a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go index c060ce874673..59a5b3708568 100644 --- a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go @@ -132,10 +132,10 @@ var map_AlertmanagerCustomConfig = map[string]string{ "": "AlertmanagerCustomConfig represents the configuration for a custom Alertmanager deployment. alertmanagerCustomConfig provides configuration options for the default Alertmanager instance that runs in the `openshift-monitoring` namespace. Use this configuration to control whether the default Alertmanager is deployed, how it logs, and how its pods are scheduled.", "logLevel": "logLevel defines the verbosity of logs emitted by Alertmanager. This field allows users to control the amount and severity of logs generated, which can be useful for debugging issues or reducing noise in production environments. Allowed values are Error, Warn, Info, and Debug. When set to Error, only errors will be logged. When set to Warn, both warnings and errors will be logged. When set to Info, general information, warnings, and errors will all be logged. When set to Debug, detailed debugging information will be logged. When omitted, this means no opinion and the platform is left to choose a reasonable default, that is subject to change over time. The current default value is `Info`.", "nodeSelector": "nodeSelector defines the nodes on which the Pods are scheduled nodeSelector is optional.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time. The current default value is `kubernetes.io/os: linux`.", - "resources": "resources defines the compute resource requests and limits for the Alertmanager container. This includes CPU, memory and HugePages constraints to help control scheduling and resource usage. When not specified, defaults are used by the platform. Requests cannot exceed limits. This field is optional. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ This is a simplified API that maps to Kubernetes ResourceRequirements. The current default values are:\n resources:\n - name: cpu\n request: 4m\n limit: null\n - name: memory\n request: 40Mi\n limit: null\nMaximum length for this list is 10. Minimum length for this list is 1. Each resource name must be unique within this list.", + "resources": "resources defines the compute resource requests and limits for the Alertmanager container. This includes CPU, memory and HugePages constraints to help control scheduling and resource usage. When not specified, defaults are used by the platform. Requests cannot exceed limits. This field is optional. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ This is a simplified API that maps to Kubernetes ResourceRequirements. The current default values are:\n resources:\n - name: cpu\n request: 4m\n limit: null\n - name: memory\n request: 40Mi\n limit: null\nMaximum length for this list is 10. Minimum length for this list is 1.", "secrets": "secrets defines a list of secrets that need to be mounted into the Alertmanager. The secrets must reside within the same namespace as the Alertmanager object. They will be added as volumes named secret- and mounted at /etc/alertmanager/secrets/ within the 'alertmanager' container of the Alertmanager Pods.\n\nThese secrets can be used to authenticate Alertmanager with endpoint receivers. For example, you can use secrets to: - Provide certificates for TLS authentication with receivers that require private CA certificates - Store credentials for Basic HTTP authentication with receivers that require password-based auth - Store any other authentication credentials needed by your alert receivers\n\nThis field is optional. Maximum length for this list is 10. Minimum length for this list is 1. Entries in this list must be unique.", - "tolerations": "tolerations defines tolerations for the pods. tolerations is optional.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time. Defaults are empty/unset. Maximum length for this list is 10. Minimum length for this list is 1.", - "topologySpreadConstraints": "topologySpreadConstraints defines rules for how Alertmanager Pods should be distributed across topology domains such as zones, nodes, or other user-defined labels. topologySpreadConstraints is optional. This helps improve high availability and resource efficiency by avoiding placing too many replicas in the same failure domain.\n\nWhen omitted, this means no opinion and the platform is left to choose a default, which is subject to change over time. This field maps directly to the `topologySpreadConstraints` field in the Pod spec. Default is empty list. Maximum length for this list is 10. Minimum length for this list is 1. Entries must have unique topologyKey and whenUnsatisfiable pairs.", + "tolerations": "tolerations defines tolerations for the pods. tolerations is optional.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time. Defaults are empty/unset. Maximum length for this list is 10 Minimum length for this list is 1", + "topologySpreadConstraints": "topologySpreadConstraints defines rules for how Alertmanager Pods should be distributed across topology domains such as zones, nodes, or other user-defined labels. topologySpreadConstraints is optional. This helps improve high availability and resource efficiency by avoiding placing too many replicas in the same failure domain.\n\nWhen omitted, this means no opinion and the platform is left to choose a default, which is subject to change over time. This field maps directly to the `topologySpreadConstraints` field in the Pod spec. Default is empty list. Maximum length for this list is 10. Minimum length for this list is 1 Entries must have unique topologyKey and whenUnsatisfiable pairs.", "volumeClaimTemplate": "volumeClaimTemplate Defines persistent storage for Alertmanager. Use this setting to configure the persistent volume claim, including storage class, volume size, and name. If omitted, the Pod uses ephemeral storage and alert data will not persist across restarts. This field is optional.", } @@ -174,11 +174,10 @@ func (ClusterMonitoringList) SwaggerDoc() map[string]string { } var map_ClusterMonitoringSpec = map[string]string{ - "": "ClusterMonitoringSpec defines the desired state of Cluster Monitoring Operator", - "userDefined": "userDefined set the deployment mode for user-defined monitoring in addition to the default platform monitoring. userDefined is optional. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default value is `Disabled`.", - "alertmanagerConfig": "alertmanagerConfig allows users to configure how the default Alertmanager instance should be deployed in the `openshift-monitoring` namespace. alertmanagerConfig is optional. When omitted, this means no opinion and the platform is left to choose a reasonable default, that is subject to change over time. The current default value is `DefaultConfig`.", - "metricsServerConfig": "metricsServerConfig is an optional field that can be used to configure the Kubernetes Metrics Server that runs in the openshift-monitoring namespace. Specifically, it can configure how the Metrics Server instance is deployed, pod scheduling, its audit policy and log verbosity. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time.", - "prometheusOperatorConfig": "prometheusOperatorConfig is an optional field that can be used to configure the Prometheus Operator component. Specifically, it can configure how the Prometheus Operator instance is deployed, pod scheduling, and resource allocation. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time.", + "": "ClusterMonitoringSpec defines the desired state of Cluster Monitoring Operator", + "userDefined": "userDefined set the deployment mode for user-defined monitoring in addition to the default platform monitoring. userDefined is optional. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default value is `Disabled`.", + "alertmanagerConfig": "alertmanagerConfig allows users to configure how the default Alertmanager instance should be deployed in the `openshift-monitoring` namespace. alertmanagerConfig is optional. When omitted, this means no opinion and the platform is left to choose a reasonable default, that is subject to change over time. The current default value is `DefaultConfig`.", + "metricsServerConfig": "metricsServerConfig is an optional field that can be used to configure the Kubernetes Metrics Server that runs in the openshift-monitoring namespace. Specifically, it can configure how the Metrics Server instance is deployed, pod scheduling, its audit policy and log verbosity. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time.", } func (ClusterMonitoringSpec) SwaggerDoc() map[string]string { @@ -208,29 +207,16 @@ var map_MetricsServerConfig = map[string]string{ "": "MetricsServerConfig provides configuration options for the Metrics Server instance that runs in the `openshift-monitoring` namespace. Use this configuration to control how the Metrics Server instance is deployed, how it logs, and how its pods are scheduled.", "audit": "audit defines the audit configuration used by the Metrics Server instance. audit is optional. When omitted, this means no opinion and the platform is left to choose a reasonable default, that is subject to change over time. The current default sets audit.profile to Metadata", "nodeSelector": "nodeSelector defines the nodes on which the Pods are scheduled nodeSelector is optional.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time. The current default value is `kubernetes.io/os: linux`.", - "tolerations": "tolerations defines tolerations for the pods. tolerations is optional.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time. Defaults are empty/unset. Maximum length for this list is 10. Minimum length for this list is 1.", + "tolerations": "tolerations defines tolerations for the pods. tolerations is optional.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time. Defaults are empty/unset. Maximum length for this list is 10 Minimum length for this list is 1", "verbosity": "verbosity defines the verbosity of log messages for Metrics Server. Valid values are Errors, Info, Trace, TraceAll and omitted. When set to Errors, only critical messages and errors are logged. When set to Info, only basic information messages are logged. When set to Trace, information useful for general debugging is logged. When set to TraceAll, detailed information about metric scraping is logged. When omitted, this means no opinion and the platform is left to choose a reasonable default, that is subject to change over time. The current default value is `Errors`", - "resources": "resources defines the compute resource requests and limits for the Metrics Server container. This includes CPU, memory and HugePages constraints to help control scheduling and resource usage. When not specified, defaults are used by the platform. Requests cannot exceed limits. This field is optional. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ This is a simplified API that maps to Kubernetes ResourceRequirements. The current default values are:\n resources:\n - name: cpu\n request: 4m\n limit: null\n - name: memory\n request: 40Mi\n limit: null\nMaximum length for this list is 10. Minimum length for this list is 1. Each resource name must be unique within this list.", - "topologySpreadConstraints": "topologySpreadConstraints defines rules for how Metrics Server Pods should be distributed across topology domains such as zones, nodes, or other user-defined labels. topologySpreadConstraints is optional. This helps improve high availability and resource efficiency by avoiding placing too many replicas in the same failure domain.\n\nWhen omitted, this means no opinion and the platform is left to choose a default, which is subject to change over time. This field maps directly to the `topologySpreadConstraints` field in the Pod spec. Default is empty list. Maximum length for this list is 10. Minimum length for this list is 1. Entries must have unique topologyKey and whenUnsatisfiable pairs.", + "resources": "resources defines the compute resource requests and limits for the Metrics Server container. This includes CPU, memory and HugePages constraints to help control scheduling and resource usage. When not specified, defaults are used by the platform. Requests cannot exceed limits. This field is optional. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ This is a simplified API that maps to Kubernetes ResourceRequirements. The current default values are:\n resources:\n - name: cpu\n request: 4m\n limit: null\n - name: memory\n request: 40Mi\n limit: null\nMaximum length for this list is 10. Minimum length for this list is 1.", + "topologySpreadConstraints": "topologySpreadConstraints defines rules for how Metrics Server Pods should be distributed across topology domains such as zones, nodes, or other user-defined labels. topologySpreadConstraints is optional. This helps improve high availability and resource efficiency by avoiding placing too many replicas in the same failure domain.\n\nWhen omitted, this means no opinion and the platform is left to choose a default, which is subject to change over time. This field maps directly to the `topologySpreadConstraints` field in the Pod spec. Default is empty list. Maximum length for this list is 10. Minimum length for this list is 1 Entries must have unique topologyKey and whenUnsatisfiable pairs.", } func (MetricsServerConfig) SwaggerDoc() map[string]string { return map_MetricsServerConfig } -var map_PrometheusOperatorConfig = map[string]string{ - "": "PrometheusOperatorConfig provides configuration options for the Prometheus Operator instance Use this configuration to control how the Prometheus Operator instance is deployed, how it logs, and how its pods are scheduled.", - "logLevel": "logLevel defines the verbosity of logs emitted by Prometheus Operator. This field allows users to control the amount and severity of logs generated, which can be useful for debugging issues or reducing noise in production environments. Allowed values are Error, Warn, Info, and Debug. When set to Error, only errors will be logged. When set to Warn, both warnings and errors will be logged. When set to Info, general information, warnings, and errors will all be logged. When set to Debug, detailed debugging information will be logged. When omitted, this means no opinion and the platform is left to choose a reasonable default, that is subject to change over time. The current default value is `Info`.", - "nodeSelector": "nodeSelector defines the nodes on which the Pods are scheduled nodeSelector is optional.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time. The current default value is `kubernetes.io/os: linux`. When specified, nodeSelector must contain at least 1 entry and must not contain more than 10 entries.", - "resources": "resources defines the compute resource requests and limits for the Prometheus Operator container. This includes CPU, memory and HugePages constraints to help control scheduling and resource usage. When not specified, defaults are used by the platform. Requests cannot exceed limits. This field is optional. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ This is a simplified API that maps to Kubernetes ResourceRequirements. The current default values are:\n resources:\n - name: cpu\n request: 4m\n limit: null\n - name: memory\n request: 40Mi\n limit: null\nMaximum length for this list is 10. Minimum length for this list is 1. Each resource name must be unique within this list.", - "tolerations": "tolerations defines tolerations for the pods. tolerations is optional.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose reasonable defaults. These defaults are subject to change over time. Defaults are empty/unset. Maximum length for this list is 10. Minimum length for this list is 1.", - "topologySpreadConstraints": "topologySpreadConstraints defines rules for how Prometheus Operator Pods should be distributed across topology domains such as zones, nodes, or other user-defined labels. topologySpreadConstraints is optional. This helps improve high availability and resource efficiency by avoiding placing too many replicas in the same failure domain.\n\nWhen omitted, this means no opinion and the platform is left to choose a default, which is subject to change over time. This field maps directly to the `topologySpreadConstraints` field in the Pod spec. Default is empty list. Maximum length for this list is 10. Minimum length for this list is 1. Entries must have unique topologyKey and whenUnsatisfiable pairs.", -} - -func (PrometheusOperatorConfig) SwaggerDoc() map[string]string { - return map_PrometheusOperatorConfig -} - var map_UserDefinedMonitoring = map[string]string{ "": "UserDefinedMonitoring config for user-defined projects.", "mode": "mode defines the different configurations of UserDefinedMonitoring Valid values are Disabled and NamespaceIsolated Disabled disables monitoring for user-defined projects. This restricts the default monitoring stack, installed in the openshift-monitoring project, to monitor only platform namespaces, which prevents any custom monitoring configurations or resources from being applied to user-defined namespaces. NamespaceIsolated enables monitoring for user-defined projects with namespace-scoped tenancy. This ensures that metrics, alerts, and monitoring data are isolated at the namespace level. The current default value is `Disabled`.", @@ -240,44 +226,6 @@ func (UserDefinedMonitoring) SwaggerDoc() map[string]string { return map_UserDefinedMonitoring } -var map_CRIOCredentialProviderConfig = map[string]string{ - "": "CRIOCredentialProviderConfig holds cluster-wide singleton resource configurations for CRI-O credential provider, the name of this instance is \"cluster\". CRI-O credential provider is a binary shipped with CRI-O that provides a way to obtain container image pull credentials from external sources. For example, it can be used to fetch mirror registry credentials from secrets resources in the cluster within the same namespace the pod will be running in. CRIOCredentialProviderConfig configuration specifies the pod image sources registries that should trigger the CRI-O credential provider execution, which will resolve the CRI-O mirror configurations and obtain the necessary credentials for pod creation. Note: Configuration changes will only take effect after the kubelet restarts, which is automatically managed by the cluster during rollout.\n\nThe resource is a singleton named \"cluster\".\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", - "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "spec defines the desired configuration of the CRI-O Credential Provider. This field is required and must be provided when creating the resource.", - "status": "status represents the current state of the CRIOCredentialProviderConfig. When omitted or nil, it indicates that the status has not yet been set by the controller. The controller will populate this field with validation conditions and operational state.", -} - -func (CRIOCredentialProviderConfig) SwaggerDoc() map[string]string { - return map_CRIOCredentialProviderConfig -} - -var map_CRIOCredentialProviderConfigList = map[string]string{ - "": "CRIOCredentialProviderConfigList contains a list of CRIOCredentialProviderConfig resources\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", - "metadata": "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", -} - -func (CRIOCredentialProviderConfigList) SwaggerDoc() map[string]string { - return map_CRIOCredentialProviderConfigList -} - -var map_CRIOCredentialProviderConfigSpec = map[string]string{ - "": "CRIOCredentialProviderConfigSpec defines the desired configuration of the CRI-O Credential Provider.", - "matchImages": "matchImages is a list of string patterns used to determine whether the CRI-O credential provider should be invoked for a given image. This list is passed to the kubelet CredentialProviderConfig, and if any pattern matches the requested image, CRI-O credential provider will be invoked to obtain credentials for pulling that image or its mirrors. Depending on the platform, the CRI-O credential provider may be installed alongside an existing platform specific provider. Conflicts between the existing platform specific provider image match configuration and this list will be handled by the following precedence rule: credentials from built-in kubelet providers (e.g., ECR, GCR, ACR) take precedence over those from the CRIOCredentialProviderConfig when both match the same image. To avoid uncertainty, it is recommended to avoid configuring your private image patterns to overlap with existing platform specific provider config(e.g., the entries from https://github.com/openshift/machine-config-operator/blob/main/templates/common/aws/files/etc-kubernetes-credential-providers-ecr-credential-provider.yaml). You can check the resource's Status conditions to see if any entries were ignored due to exact matches with known built-in provider patterns.\n\nThis field is optional, the items of the list must contain between 1 and 50 entries. The list is treated as a set, so duplicate entries are not allowed.\n\nFor more details, see: https://kubernetes.io/docs/tasks/administer-cluster/kubelet-credential-provider/ https://github.com/cri-o/crio-credential-provider#architecture\n\nEach entry in matchImages is a pattern which can optionally contain a port and a path. Each entry must be no longer than 512 characters. Wildcards ('*') are supported for full subdomain labels, such as '*.k8s.io' or 'k8s.*.io', and for top-level domains, such as 'k8s.*' (which matches 'k8s.io' or 'k8s.net'). A global wildcard '*' (matching any domain) is not allowed. Wildcards may replace an entire hostname label (e.g., *.example.com), but they cannot appear within a label (e.g., f*oo.example.com) and are not allowed in the port or path. For example, 'example.*.com' is valid, but 'exa*mple.*.com' is not. Each wildcard matches only a single domain label, so '*.io' does **not** match '*.k8s.io'.\n\nA match exists between an image and a matchImage when all of the below are true: Both contain the same number of domain parts and each part matches. The URL path of an matchImages must be a prefix of the target image URL path. If the matchImages contains a port, then the port must match in the image as well.\n\nExample values of matchImages: - 123456789.dkr.ecr.us-east-1.amazonaws.com - *.azurecr.io - gcr.io - *.*.registry.io - registry.io:8080/path", -} - -func (CRIOCredentialProviderConfigSpec) SwaggerDoc() map[string]string { - return map_CRIOCredentialProviderConfigSpec -} - -var map_CRIOCredentialProviderConfigStatus = map[string]string{ - "": "CRIOCredentialProviderConfigStatus defines the observed state of CRIOCredentialProviderConfig", - "conditions": "conditions represent the latest available observations of the configuration state. When omitted, it indicates that no conditions have been reported yet. The maximum number of conditions is 16. Conditions are stored as a map keyed by condition type, ensuring uniqueness.\n\nExpected condition types include: \"Validated\": indicates whether the matchImages configuration is valid", -} - -func (CRIOCredentialProviderConfigStatus) SwaggerDoc() map[string]string { - return map_CRIOCredentialProviderConfigStatus -} - var map_ImagePolicy = map[string]string{ "": "ImagePolicy holds namespace-wide configuration for image signature verification\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", diff --git a/vendor/github.com/openshift/api/config/v1alpha2/types_insights.go b/vendor/github.com/openshift/api/config/v1alpha2/types_insights.go index fbe666249a14..d59f5920b1ff 100644 --- a/vendor/github.com/openshift/api/config/v1alpha2/types_insights.go +++ b/vendor/github.com/openshift/api/config/v1alpha2/types_insights.go @@ -16,7 +16,6 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // +openshift:file-pattern=cvoRunLevel=0000_10,operatorName=config-operator,operatorOrdering=01 // +openshift:enable:FeatureGate=InsightsConfig // +openshift:compatibility-gen:level=4 -// +openshift:capability=Insights type InsightsDataGather struct { metav1.TypeMeta `json:",inline"` // metadata is the standard object's metadata. diff --git a/vendor/github.com/openshift/api/config/v1alpha2/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/config/v1alpha2/zz_generated.featuregated-crd-manifests.yaml index 1f73e723eb33..99fe308ef811 100644 --- a/vendor/github.com/openshift/api/config/v1alpha2/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/config/v1alpha2/zz_generated.featuregated-crd-manifests.yaml @@ -2,7 +2,7 @@ insightsdatagathers.config.openshift.io: Annotations: {} ApprovedPRNumber: https://github.com/openshift/api/pull/2195 CRDName: insightsdatagathers.config.openshift.io - Capability: Insights + Capability: "" Category: "" FeatureGates: - InsightsConfig diff --git a/vendor/github.com/openshift/api/console/v1/types_console_sample.go b/vendor/github.com/openshift/api/console/v1/types_console_sample.go index c296059b7e93..bd0f6569699a 100644 --- a/vendor/github.com/openshift/api/console/v1/types_console_sample.go +++ b/vendor/github.com/openshift/api/console/v1/types_console_sample.go @@ -125,8 +125,7 @@ type ConsoleSampleSpec struct { // ConsoleSampleSourceType is an enumeration of the supported sample types. // Unsupported samples types will be ignored in the web console. -// +kubebuilder:validation:Enum:="GitImport";"ContainerImport" -// +enum +// +kubebuilder:validation:Enum:=GitImport;ContainerImport type ConsoleSampleSourceType string const ( @@ -145,6 +144,7 @@ type ConsoleSampleSource struct { // type of the sample, currently supported: "GitImport";"ContainerImport" // +unionDiscriminator // +required + // +kubebuilder:validation:Enum:="GitImport";"ContainerImport" Type ConsoleSampleSourceType `json:"type"` // gitImport allows the user to import code from a git repository. diff --git a/vendor/github.com/openshift/api/etcd/README.md b/vendor/github.com/openshift/api/etcd/README.md deleted file mode 100644 index b92d553df7e7..000000000000 --- a/vendor/github.com/openshift/api/etcd/README.md +++ /dev/null @@ -1,211 +0,0 @@ -# etcd.openshift.io API Group - -This API group contains CRDs related to etcd cluster management in Two Node OpenShift with Fencing deployments. - -## API Versions - -### v1alpha1 - -Contains the `PacemakerCluster` custom resource for monitoring Pacemaker cluster health in Two Node OpenShift with Fencing deployments. - -#### PacemakerCluster - -- **Feature Gate**: `DualReplica` -- **Component**: `two-node-fencing` -- **Scope**: Cluster-scoped singleton resource (must be named "cluster") -- **Resource Path**: `pacemakerclusters.etcd.openshift.io` - -The `PacemakerCluster` resource provides visibility into the health and status of a Pacemaker-managed cluster. -It is periodically updated by the cluster-etcd-operator's status collector. - -### Status Subresource Design - -This resource uses the standard Kubernetes status subresource pattern (`+kubebuilder:subresource:status`). -The status collector creates the resource without status, then immediately populates it via the `/status` endpoint. - -**Why not atomic create-with-status?** - -We initially explored removing the status subresource to allow creating the resource with status in a single -atomic operation. This would ensure the resource is never observed in an incomplete state. However: - -1. The Kubernetes API server strips the `status` field from create requests when a status subresource is enabled -2. Without the subresource, we cannot use separate RBAC for spec vs status updates -3. The OpenShift API test framework assumes status subresource exists for status update tests - -The status collector performs a two-step operation: create resource, then immediately update status. -The brief window where status is empty is acceptable since the healthcheck controller handles missing status gracefully. - -### Pacemaker Resources - -A **pacemaker resource** is a unit of work managed by pacemaker. In pacemaker terminology, resources are services -or applications that pacemaker monitors, starts, stops, and moves between nodes to maintain high availability. - -For Two Node OpenShift with Fencing, we manage three resource types: -- **Kubelet**: The Kubernetes node agent and a prerequisite for etcd -- **Etcd**: The distributed key-value store -- **FencingAgent**: Used to isolate failed nodes during a quorum loss event (tracked separately) - -### Status Structure - -```yaml -status: # Optional on creation, populated via status subresource - conditions: # Required when status present (min 3 items) - - type: Healthy - - type: InService - - type: NodeCountAsExpected - lastUpdated: # Required when status present, cannot decrease - nodes: # Control-plane nodes (0-5, expects 2 for TNF) - - nodeName: # RFC 1123 subdomain name - addresses: # Required: List of node addresses (1-8 items) - - type: InternalIP # Currently only InternalIP is supported - address: # First address used for etcd peer URLs - conditions: # Required: Node-level conditions (min 9 items) - - type: Healthy - - type: Online - - type: InService - - type: Active - - type: Ready - - type: Clean - - type: Member - - type: FencingAvailable - - type: FencingHealthy - resources: # Required: Pacemaker resources on this node (min 2) - - name: Kubelet # Both Kubelet and Etcd must be present - conditions: # Required: Resource-level conditions (min 8 items) - - type: Healthy - - type: InService - - type: Managed - - type: Enabled - - type: Operational - - type: Active - - type: Started - - type: Schedulable - - name: Etcd - conditions: [...] # Same 8 conditions as Kubelet (abbreviated) - fencingAgents: # Required: Fencing agents for THIS node (1-8) - - name: # e.g., "master-0_redfish" (unique, max 300 chars) - method: # Fencing method: "Redfish" or "IPMI" - conditions: [...] # Same 8 conditions as resources (abbreviated) -``` - -### Fencing Agents - -Fencing agents are STONITH (Shoot The Other Node In The Head) devices used to isolate failed nodes. -Unlike regular pacemaker resources (Kubelet, Etcd), fencing agents are tracked separately because: - -1. **Mapping by target, not schedule**: Resources are mapped to the node where they are scheduled to run. - Fencing agents are mapped to the node they can *fence* (their target), regardless of which node - their monitoring operations are scheduled on. - -2. **Multiple agents per node**: A node can have multiple fencing agents for redundancy - (e.g., both Redfish and IPMI). Expected: 1 per node, supported: up to 8. - -3. **Health tracking via two node-level conditions**: - - **FencingAvailable**: True if at least one agent is healthy (fencing works), False if all agents unhealthy (degrades operator) - - **FencingHealthy**: True if all agents are healthy (ideal state), False if any agent is unhealthy (emits warning events) - -### Cluster-Level Conditions - -| Condition | True | False | -|-----------|------|-------| -| `Healthy` | Cluster is healthy (`ClusterHealthy`) | Cluster has issues (`ClusterUnhealthy`) | -| `InService` | In service (`InService`) | In maintenance (`InMaintenance`) | -| `NodeCountAsExpected` | Node count is as expected (`AsExpected`) | Wrong count (`InsufficientNodes`, `ExcessiveNodes`) | - -### Node-Level Conditions - -| Condition | True | False | -|-----------|------|-------| -| `Healthy` | Node is healthy (`NodeHealthy`) | Node has issues (`NodeUnhealthy`) | -| `Online` | Node is online (`Online`) | Node is offline (`Offline`) | -| `InService` | In service (`InService`) | In maintenance (`InMaintenance`) | -| `Active` | Node is active (`Active`) | Node is in standby (`Standby`) | -| `Ready` | Node is ready (`Ready`) | Node is pending (`Pending`) | -| `Clean` | Node is clean (`Clean`) | Node is unclean (`Unclean`) | -| `Member` | Node is a member (`Member`) | Not a member (`NotMember`) | -| `FencingAvailable` | At least one agent healthy (`FencingAvailable`) | All agents unhealthy (`FencingUnavailable`) - degrades operator | -| `FencingHealthy` | All agents healthy (`FencingHealthy`) | Some agents unhealthy (`FencingUnhealthy`) - emits warnings | - -### Resource-Level Conditions - -Each resource in the `resources` array and each fencing agent in the `fencingAgents` array has its own conditions. - -| Condition | True | False | -|-----------|------|-------| -| `Healthy` | Resource is healthy (`ResourceHealthy`) | Resource has issues (`ResourceUnhealthy`) | -| `InService` | In service (`InService`) | In maintenance (`InMaintenance`) | -| `Managed` | Managed by pacemaker (`Managed`) | Not managed (`Unmanaged`) | -| `Enabled` | Resource is enabled (`Enabled`) | Resource is disabled (`Disabled`) | -| `Operational` | Resource is operational (`Operational`) | Resource has failed (`Failed`) | -| `Active` | Resource is active (`Active`) | Resource is not active (`Inactive`) | -| `Started` | Resource is started (`Started`) | Resource is stopped (`Stopped`) | -| `Schedulable` | Resource is schedulable (`Schedulable`) | Resource is not schedulable (`Unschedulable`) | - -### Validation Rules - -**Resource naming:** -- Resource name must be "cluster" (singleton) - -**Node name validation:** -- Must be a lowercase RFC 1123 subdomain name -- Consists of lowercase alphanumeric characters, '-' or '.' -- Must start and end with an alphanumeric character -- Maximum 253 characters - -**Node addresses:** -- Uses `PacemakerNodeAddress` type (similar to `corev1.NodeAddress` but with IP validation) -- Currently only `InternalIP` type is supported -- Pacemaker allows multiple addresses for Corosync communication between nodes (1-8 addresses) -- The first address in the list is used for IP-based peer URLs for etcd membership -- IP validation: - - Must be a valid global unicast IPv4 or IPv6 address - - Must be in canonical form (e.g., `192.168.1.1` not `192.168.001.001`, or `2001:db8::1` not `2001:0db8::1`) - - Excludes loopback, link-local, and multicast addresses - - Maximum length is 39 characters (full IPv6 address) - -**Timestamp validation:** -- `lastUpdated` is required when status is present -- Once set, cannot be set to an earlier timestamp (validation uses `!has(oldSelf.lastUpdated)` to handle initial creation) -- Timestamps must always increase (prevents stale updates from overwriting newer data) - -**Status fields:** -- `status` - Optional on creation (pointer type), populated via status subresource -- When status is present, all fields within are required: - - `conditions` - Required array of cluster conditions (min 3 items) - - `lastUpdated` - Required timestamp for staleness detection - - `nodes` - Required array of control-plane node statuses (min 0, max 5; empty allowed for catastrophic failures) - -**Node fields (when node present):** -- `nodeName` - Required, RFC 1123 subdomain -- `addresses` - Required (min 1, max 8 items) -- `conditions` - Required (min 9 items with specific types enforced via XValidation) -- `resources` - Required (min 2 items: Kubelet and Etcd) -- `fencingAgents` - Required (min 1, max 8 items) - -**Conditions validation:** -- Cluster-level: MinItems=3 (Healthy, InService, NodeCountAsExpected) -- Node-level: MinItems=9 (Healthy, Online, InService, Active, Ready, Clean, Member, FencingAvailable, FencingHealthy) -- Resource-level: MinItems=8 (Healthy, InService, Managed, Enabled, Operational, Active, Started, Schedulable) -- Fencing agent-level: MinItems=8 (same conditions as resources) - -All condition arrays have XValidation rules to ensure specific condition types are present. - -**Resource names:** -- Valid values are: `Kubelet`, `Etcd` -- Both resources must be present in each node's `resources` array - -**Fencing agent fields:** -- `name`: Unique identifier for the fencing agent (e.g., "master-0_redfish") - - Must be unique within the `fencingAgents` array - - May contain alphanumeric characters, dots, hyphens, and underscores (`^[a-zA-Z0-9._-]+$`) - - Maximum 300 characters (provides headroom beyond 253 node name + underscore + method) -- `method`: Fencing method enum - valid values are `Redfish` or `IPMI` -- `conditions`: Required, same 8 conditions as resources - -Note: The target node is implied by the parent `PacemakerClusterNodeStatus` - fencing agents are nested under the node they can fence. - -### Usage - -The cluster-etcd-operator healthcheck controller watches this resource and updates operator conditions based on -the cluster state. The aggregate `Healthy` conditions at each level (cluster, node, resource) provide a quick -way to determine overall health. diff --git a/vendor/github.com/openshift/api/etcd/install.go b/vendor/github.com/openshift/api/etcd/install.go deleted file mode 100644 index 7e7474152c4e..000000000000 --- a/vendor/github.com/openshift/api/etcd/install.go +++ /dev/null @@ -1,26 +0,0 @@ -package etcd - -import ( - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - - v1alpha1 "github.com/openshift/api/etcd/v1alpha1" -) - -const ( - GroupName = "etcd.openshift.io" -) - -var ( - schemeBuilder = runtime.NewSchemeBuilder(v1alpha1.Install) - // Install is a function which adds every version of this group to a scheme - Install = schemeBuilder.AddToScheme -) - -func Resource(resource string) schema.GroupResource { - return schema.GroupResource{Group: GroupName, Resource: resource} -} - -func Kind(kind string) schema.GroupKind { - return schema.GroupKind{Group: GroupName, Kind: kind} -} diff --git a/vendor/github.com/openshift/api/etcd/v1alpha1/Makefile b/vendor/github.com/openshift/api/etcd/v1alpha1/Makefile deleted file mode 100644 index 3d019662af64..000000000000 --- a/vendor/github.com/openshift/api/etcd/v1alpha1/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -.PHONY: test -test: - make -C ../../tests test GINKGO_EXTRA_ARGS=--focus="etcd.openshift.io/v1alpha1" diff --git a/vendor/github.com/openshift/api/etcd/v1alpha1/doc.go b/vendor/github.com/openshift/api/etcd/v1alpha1/doc.go deleted file mode 100644 index aea92fb381aa..000000000000 --- a/vendor/github.com/openshift/api/etcd/v1alpha1/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// +k8s:deepcopy-gen=package,register -// +k8s:defaulter-gen=TypeMeta -// +k8s:openapi-gen=true -// +openshift:featuregated-schema-gen=true -// +groupName=etcd.openshift.io -package v1alpha1 diff --git a/vendor/github.com/openshift/api/etcd/v1alpha1/register.go b/vendor/github.com/openshift/api/etcd/v1alpha1/register.go deleted file mode 100644 index 1dc6482f832d..000000000000 --- a/vendor/github.com/openshift/api/etcd/v1alpha1/register.go +++ /dev/null @@ -1,39 +0,0 @@ -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -var ( - GroupName = "etcd.openshift.io" - GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} - schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) - // Install is a function which adds this version to a scheme - Install = schemeBuilder.AddToScheme - - // SchemeGroupVersion generated code relies on this name - // Deprecated - SchemeGroupVersion = GroupVersion - // AddToScheme exists solely to keep the old generators creating valid code - // DEPRECATED - AddToScheme = schemeBuilder.AddToScheme -) - -// Resource generated code relies on this being here, but it logically belongs to the group -// DEPRECATED -func Resource(resource string) schema.GroupResource { - return schema.GroupResource{Group: GroupName, Resource: resource} -} - -func addKnownTypes(scheme *runtime.Scheme) error { - metav1.AddToGroupVersion(scheme, GroupVersion) - - scheme.AddKnownTypes(GroupVersion, - &PacemakerCluster{}, - &PacemakerClusterList{}, - ) - - return nil -} diff --git a/vendor/github.com/openshift/api/etcd/v1alpha1/types_pacemakercluster.go b/vendor/github.com/openshift/api/etcd/v1alpha1/types_pacemakercluster.go deleted file mode 100644 index ab06d0e3904e..000000000000 --- a/vendor/github.com/openshift/api/etcd/v1alpha1/types_pacemakercluster.go +++ /dev/null @@ -1,736 +0,0 @@ -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// PacemakerCluster is used in Two Node OpenShift with Fencing deployments to monitor the health -// of etcd running under pacemaker. - -// Cluster-level condition types for PacemakerCluster.status.conditions -const ( - // ClusterHealthyConditionType tracks the overall health of the pacemaker cluster. - // This is an aggregate condition that reflects the health of all cluster-level conditions and node health. - // Specifically, it aggregates the following conditions: - // - ClusterInServiceConditionType - // - ClusterNodeCountAsExpectedConditionType - // - NodeHealthyConditionType (for each node) - // When True, the cluster is healthy with reason "ClusterHealthy". - // When False, the cluster is unhealthy with reason "ClusterUnhealthy". - ClusterHealthyConditionType = "Healthy" - - // ClusterInServiceConditionType tracks whether the cluster is in service (not in maintenance mode). - // Maintenance mode is a cluster-wide setting that prevents pacemaker from starting or stopping resources. - // When True, the cluster is in service with reason "InService". This is the normal operating state. - // When False, the cluster is in maintenance mode with reason "InMaintenance". This is an unexpected state. - ClusterInServiceConditionType = "InService" - - // ClusterNodeCountAsExpectedConditionType tracks whether the cluster has the expected number of nodes. - // For Two Node OpenShift with Fencing, we are expecting exactly 2 nodes. - // When True, the expected number of nodes are present with reason "AsExpected". - // When False, the node count is incorrect with reason "InsufficientNodes" or "ExcessiveNodes". - ClusterNodeCountAsExpectedConditionType = "NodeCountAsExpected" -) - -// ClusterHealthy condition reasons -const ( - // ClusterHealthyReasonHealthy means the pacemaker cluster is healthy and operating normally. - ClusterHealthyReasonHealthy = "ClusterHealthy" - - // ClusterHealthyReasonUnhealthy means the pacemaker cluster has issues that need investigation. - ClusterHealthyReasonUnhealthy = "ClusterUnhealthy" -) - -// ClusterInService condition reasons -const ( - // ClusterInServiceReasonInService means the cluster is in service (not in maintenance mode). - // This is the normal operating state. - ClusterInServiceReasonInService = "InService" - - // ClusterInServiceReasonInMaintenance means the cluster is in maintenance mode. - // In maintenance mode, pacemaker will not start or stop any resources. Entering and exiting this state requires - // manual user intervention, and is unexpected during normal cluster operation. - ClusterInServiceReasonInMaintenance = "InMaintenance" -) - -// ClusterNodeCountAsExpected condition reasons -const ( - // ClusterNodeCountAsExpectedReasonAsExpected means the expected number of nodes are present. - // For Two Node OpenShift with Fencing, we are expecting exactly 2 nodes. This is the expected healthy state. - ClusterNodeCountAsExpectedReasonAsExpected = "AsExpected" - - // ClusterNodeCountAsExpectedReasonInsufficientNodes means fewer nodes than expected are present. - // For Two Node OpenShift with Fencing, this means that less than 2 nodes are present. Under normal operation, this will only happen during - // a node replacement operation. It's also possible to enter this state with manual user intervention, but - // will also require user intervention to restore normal functionality. - ClusterNodeCountAsExpectedReasonInsufficientNodes = "InsufficientNodes" - - // ClusterNodeCountAsExpectedReasonExcessiveNodes means more nodes than expected are present. - // For Two Node OpenShift with Fencing, this means more than 2 nodes are present. This should be investigated as it is unexpected and should - // never happen during normal cluster operation. It is possible to enter this state with manual user intervention, - // but will also require user intervention to restore normal functionality. - ClusterNodeCountAsExpectedReasonExcessiveNodes = "ExcessiveNodes" -) - -// Node-level condition types for PacemakerCluster.status.nodes[].conditions -const ( - // NodeHealthyConditionType tracks the overall health of a node in the pacemaker cluster. - // This is an aggregate condition that reflects the health of all node-level conditions and resource health. - // Specifically, it aggregates the following conditions: - // - NodeOnlineConditionType - // - NodeInServiceConditionType - // - NodeActiveConditionType - // - NodeReadyConditionType - // - NodeCleanConditionType - // - NodeMemberConditionType - // - NodeFencingAvailableConditionType - // - NodeFencingHealthyConditionType - // - ResourceHealthyConditionType (for each resource in the node's resources list) - // When True, the node is healthy with reason "NodeHealthy". - // When False, the node is unhealthy with reason "NodeUnhealthy". - NodeHealthyConditionType = "Healthy" - - // NodeOnlineConditionType tracks whether a node is online. - // When True, the node is online with reason "Online". This is the normal operating state. - // When False, the node is offline with reason "Offline". This can occur during reboots, failures, maintenance, or replacement. - NodeOnlineConditionType = "Online" - - // NodeInServiceConditionType tracks whether a node is in service (not in maintenance mode). - // A node in maintenance mode is ignored by pacemaker while maintenance mode is active. - // When True, the node is in service with reason "InService". This is the normal operating state. - // When False, the node is in maintenance mode with reason "InMaintenance". This is an unexpected state. - NodeInServiceConditionType = "InService" - - // NodeActiveConditionType tracks whether a node is active (not in standby mode). - // When a node enters standby mode, pacemaker moves its resources to other nodes in the cluster. - // In Two Node OpenShift with Fencing, we do not use standby mode during normal operation. - // When True, the node is active with reason "Active". This is the normal operating state. - // When False, the node is in standby mode with reason "Standby". This is an unexpected state. - NodeActiveConditionType = "Active" - - // NodeReadyConditionType tracks whether a node is ready (not in a pending state). - // A node in a pending state is in the process of joining or leaving the cluster. - // When True, the node is ready with reason "Ready". This is the normal operating state. - // When False, the node is pending with reason "Pending". This is expected to be temporary. - NodeReadyConditionType = "Ready" - - // NodeCleanConditionType tracks whether a node is in a clean state. - // An unclean state means that pacemaker was unable to confirm the node's state, which signifies issues - // in fencing, communication, or configuration. - // When True, the node is clean with reason "Clean". This is the normal operating state. - // When False, the node is unclean with reason "Unclean". This is an unexpected state. - NodeCleanConditionType = "Clean" - - // NodeMemberConditionType tracks whether a node is a member of the cluster. - // Some configurations may use remote nodes or ping nodes, which are nodes that are not members. - // For Two Node OpenShift with Fencing, we expect both nodes to be members. - // When True, the node is a member with reason "Member". This is the normal operating state. - // When False, the node is not a member with reason "NotMember". This is an unexpected state. - NodeMemberConditionType = "Member" - - // NodeFencingAvailableConditionType tracks whether a node can be fenced by at least one fencing agent. - // For Two Node OpenShift with Fencing, each node needs at least one healthy fencing agent to ensure - // that the cluster can recover from a node failure via STONITH (Shoot The Other Node In The Head). - // When True, at least one fencing agent is healthy with reason "FencingAvailable". - // When False, all fencing agents are unhealthy with reason "FencingUnavailable". This is a critical - // state that should degrade the operator. - NodeFencingAvailableConditionType = "FencingAvailable" - - // NodeFencingHealthyConditionType tracks whether all fencing agents for a node are healthy. - // This is an aggregate condition that reflects the health of all fencing agents targeting this node. - // When True, all fencing agents are healthy with reason "FencingHealthy". - // When False, one or more fencing agents are unhealthy with reason "FencingUnhealthy". Warning events - // should be emitted for failing agents, but the operator should not be degraded if FencingAvailable is True. - NodeFencingHealthyConditionType = "FencingHealthy" -) - -// NodeHealthy condition reasons -const ( - // NodeHealthyReasonHealthy means the node is healthy and operating normally. - NodeHealthyReasonHealthy = "NodeHealthy" - - // NodeHealthyReasonUnhealthy means the node has issues that need investigation. - NodeHealthyReasonUnhealthy = "NodeUnhealthy" -) - -// NodeOnline condition reasons -const ( - // NodeOnlineReasonOnline means the node is online. This is the normal operating state. - NodeOnlineReasonOnline = "Online" - - // NodeOnlineReasonOffline means the node is offline. - NodeOnlineReasonOffline = "Offline" -) - -// NodeInService condition reasons -const ( - // NodeInServiceReasonInService means the node is in service (not in maintenance mode). - // This is the normal operating state. - NodeInServiceReasonInService = "InService" - - // NodeInServiceReasonInMaintenance means the node is in maintenance mode. - // This is an unexpected state. - NodeInServiceReasonInMaintenance = "InMaintenance" -) - -// NodeActive condition reasons -const ( - // NodeActiveReasonActive means the node is active (not in standby mode). - // This is the normal operating state. - NodeActiveReasonActive = "Active" - - // NodeActiveReasonStandby means the node is in standby mode. - // This is an unexpected state. - NodeActiveReasonStandby = "Standby" -) - -// NodeReady condition reasons -const ( - // NodeReadyReasonReady means the node is ready (not in a pending state). - // This is the normal operating state. - NodeReadyReasonReady = "Ready" - - // NodeReadyReasonPending means the node is joining or leaving the cluster. - // This state is expected to be temporary. - NodeReadyReasonPending = "Pending" -) - -// NodeClean condition reasons -const ( - // NodeCleanReasonClean means the node is in a clean state. - // This is the normal operating state. - NodeCleanReasonClean = "Clean" - - // NodeCleanReasonUnclean means the node is in an unclean state. - // Pacemaker was unable to confirm the node's state, which signifies issues in fencing, communication, or configuration. - // This is an unexpected state. - NodeCleanReasonUnclean = "Unclean" -) - -// NodeMember condition reasons -const ( - // NodeMemberReasonMember means the node is a member of the cluster. - // For Two Node OpenShift with Fencing, we expect both nodes to be members. This is the normal operating state. - NodeMemberReasonMember = "Member" - - // NodeMemberReasonNotMember means the node is not a member of the cluster. - // This is an unexpected state. - NodeMemberReasonNotMember = "NotMember" -) - -// NodeFencingAvailable condition reasons -const ( - // NodeFencingAvailableReasonAvailable means at least one fencing agent for this node is healthy. - // The cluster can fence this node if needed. This is the normal operating state. - NodeFencingAvailableReasonAvailable = "FencingAvailable" - - // NodeFencingAvailableReasonUnavailable means all fencing agents for this node are unhealthy. - // The cluster cannot fence this node, which compromises high availability. - // This is a critical state that should degrade the operator. - NodeFencingAvailableReasonUnavailable = "FencingUnavailable" -) - -// NodeFencingHealthy condition reasons -const ( - // NodeFencingHealthyReasonHealthy means all fencing agents for this node are healthy. - // This is the ideal operating state with full redundancy. - NodeFencingHealthyReasonHealthy = "FencingHealthy" - - // NodeFencingHealthyReasonUnhealthy means one or more fencing agents for this node are unhealthy. - // Warning events should be emitted for failing agents, but the operator should not be degraded - // if FencingAvailable is still True. - NodeFencingHealthyReasonUnhealthy = "FencingUnhealthy" -) - -// Resource-level condition types for PacemakerCluster.status.nodes[].resources[].conditions -const ( - // ResourceHealthyConditionType tracks the overall health of a pacemaker resource. - // This is an aggregate condition that reflects the health of all resource-level conditions. - // Specifically, it aggregates the following conditions: - // - ResourceInServiceConditionType - // - ResourceManagedConditionType - // - ResourceEnabledConditionType - // - ResourceOperationalConditionType - // - ResourceActiveConditionType - // - ResourceStartedConditionType - // - ResourceSchedulableConditionType - // When True, the resource is healthy with reason "ResourceHealthy". - // When False, the resource is unhealthy with reason "ResourceUnhealthy". - ResourceHealthyConditionType = "Healthy" - - // ResourceInServiceConditionType tracks whether a resource is in service (not in maintenance mode). - // Resources in maintenance mode are not monitored or moved by pacemaker. - // In Two Node OpenShift with Fencing, we do not expect any resources to be in maintenance mode. - // When True, the resource is in service with reason "InService". This is the normal operating state. - // When False, the resource is in maintenance mode with reason "InMaintenance". This is an unexpected state. - ResourceInServiceConditionType = "InService" - - // ResourceManagedConditionType tracks whether a resource is managed by pacemaker. - // Resources that are not managed by pacemaker are effectively invisible to the pacemaker HA logic. - // For Two Node OpenShift with Fencing, all resources are expected to be managed. - // When True, the resource is managed with reason "Managed". This is the normal operating state. - // When False, the resource is not managed with reason "Unmanaged". This is an unexpected state. - ResourceManagedConditionType = "Managed" - - // ResourceEnabledConditionType tracks whether a resource is enabled. - // Resources that are disabled are stopped and not automatically managed or started by the cluster. - // In Two Node OpenShift with Fencing, we do not expect any resources to be disabled. - // When True, the resource is enabled with reason "Enabled". This is the normal operating state. - // When False, the resource is disabled with reason "Disabled". This is an unexpected state. - ResourceEnabledConditionType = "Enabled" - - // ResourceOperationalConditionType tracks whether a resource is operational (not failed). - // A failed resource is one that is not able to start or is in an error state. - // When True, the resource is operational with reason "Operational". This is the normal operating state. - // When False, the resource has failed with reason "Failed". This is an unexpected state. - ResourceOperationalConditionType = "Operational" - - // ResourceActiveConditionType tracks whether a resource is active. - // An active resource is running on a cluster node. - // In Two Node OpenShift with Fencing, all resources are expected to be active. - // When True, the resource is active with reason "Active". This is the normal operating state. - // When False, the resource is not active with reason "Inactive". This is an unexpected state. - ResourceActiveConditionType = "Active" - - // ResourceStartedConditionType tracks whether a resource is started. - // It's normal for a resource like etcd to become stopped in the event of a quorum loss event because - // the pacemaker recovery logic will fence a node and restore etcd quorum on the surviving node as a cluster-of-one. - // A resource that stays stopped for an extended period of time is an unexpected state and should be investigated. - // When True, the resource is started with reason "Started". This is the normal operating state. - // When False, the resource is not started with reason "Stopped". This is expected to be temporary. - ResourceStartedConditionType = "Started" - - // ResourceSchedulableConditionType tracks whether a resource is schedulable (not blocked). - // A resource that is not schedulable is unable to start or move to a different node. - // In Two Node OpenShift with Fencing, we do not expect any resources to be unschedulable. - // When True, the resource is schedulable with reason "Schedulable". This is the normal operating state. - // When False, the resource is not schedulable with reason "Unschedulable". This is an unexpected state. - ResourceSchedulableConditionType = "Schedulable" -) - -// ResourceHealthy condition reasons -const ( - // ResourceHealthyReasonHealthy means the resource is healthy and operating normally. - ResourceHealthyReasonHealthy = "ResourceHealthy" - - // ResourceHealthyReasonUnhealthy means the resource has issues that need investigation. - ResourceHealthyReasonUnhealthy = "ResourceUnhealthy" -) - -// ResourceInService condition reasons -const ( - // ResourceInServiceReasonInService means the resource is in service (not in maintenance mode). - // This is the normal operating state. - ResourceInServiceReasonInService = "InService" - - // ResourceInServiceReasonInMaintenance means the resource is in maintenance mode. - // Resources in maintenance mode are not monitored or moved by pacemaker. This is an unexpected state. - ResourceInServiceReasonInMaintenance = "InMaintenance" -) - -// ResourceManaged condition reasons -const ( - // ResourceManagedReasonManaged means the resource is managed by pacemaker. - // This is the normal operating state. - ResourceManagedReasonManaged = "Managed" - - // ResourceManagedReasonUnmanaged means the resource is not managed by pacemaker. - // Resources that are not managed by pacemaker are effectively invisible to the pacemaker HA logic. - // This is an unexpected state. - ResourceManagedReasonUnmanaged = "Unmanaged" -) - -// ResourceEnabled condition reasons -const ( - // ResourceEnabledReasonEnabled means the resource is enabled. - // This is the normal operating state. - ResourceEnabledReasonEnabled = "Enabled" - - // ResourceEnabledReasonDisabled means the resource is disabled. - // Resources that are disabled are stopped and not automatically managed or started by the cluster. - // This is an unexpected state. - ResourceEnabledReasonDisabled = "Disabled" -) - -// ResourceOperational condition reasons -const ( - // ResourceOperationalReasonOperational means the resource is operational (not failed). - // This is the normal operating state. - ResourceOperationalReasonOperational = "Operational" - - // ResourceOperationalReasonFailed means the resource has failed. - // A failed resource is one that is not able to start or is in an error state. This is an unexpected state. - ResourceOperationalReasonFailed = "Failed" -) - -// ResourceActive condition reasons -const ( - // ResourceActiveReasonActive means the resource is active. - // An active resource is running on a cluster node. This is the normal operating state. - ResourceActiveReasonActive = "Active" - - // ResourceActiveReasonInactive means the resource is not active. - // This is an unexpected state. - ResourceActiveReasonInactive = "Inactive" -) - -// ResourceStarted condition reasons -const ( - // ResourceStartedReasonStarted means the resource is started. - // This is the normal operating state. - ResourceStartedReasonStarted = "Started" - - // ResourceStartedReasonStopped means the resource is stopped. - // It's normal for a resource like etcd to become stopped in the event of a quorum loss event because - // the pacemaker recovery logic will fence a node and restore etcd quorum on the surviving node as a cluster-of-one. - // A resource that stays stopped for an extended period of time is an unexpected state and should be investigated. - ResourceStartedReasonStopped = "Stopped" -) - -// ResourceSchedulable condition reasons -const ( - // ResourceSchedulableReasonSchedulable means the resource is schedulable (not blocked). - // This is the normal operating state. - ResourceSchedulableReasonSchedulable = "Schedulable" - - // ResourceSchedulableReasonUnschedulable means the resource is not schedulable (blocked). - // A resource that is not schedulable is unable to start or move to a different node. This is an unexpected state. - ResourceSchedulableReasonUnschedulable = "Unschedulable" -) - -// PacemakerNodeAddressType represents the type of a node address. -// Currently only InternalIP is supported. -// +kubebuilder:validation:Enum=InternalIP -// +enum -type PacemakerNodeAddressType string - -const ( - // PacemakerNodeInternalIP is an internal IP address assigned to the node. - // This is typically the IP address used for intra-cluster communication. - PacemakerNodeInternalIP PacemakerNodeAddressType = "InternalIP" -) - -// PacemakerNodeAddress contains information for a node's address. -// This is similar to corev1.NodeAddress but adds validation for IP addresses. -type PacemakerNodeAddress struct { - // type is the type of node address. - // Currently only "InternalIP" is supported. - // +required - Type PacemakerNodeAddressType `json:"type,omitempty"` - - // address is the node address. - // For InternalIP, this must be a valid global unicast IPv4 or IPv6 address in canonical form. - // Canonical form means the shortest standard representation (e.g., "192.168.1.1" not "192.168.001.001", - // or "2001:db8::1" not "2001:0db8::1"). Maximum length is 39 characters (full IPv6 address). - // Global unicast includes private/RFC1918 addresses but excludes loopback, link-local, and multicast. - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=39 - // +kubebuilder:validation:XValidation:rule="isIP(self) && ip.isCanonical(self) && ip(self).isGlobalUnicast()",message="must be a valid global unicast IPv4 or IPv6 address in canonical form" - // +required - Address string `json:"address,omitempty"` -} - -// PacemakerClusterResourceName represents the name of a pacemaker resource. -// Fencing agents are tracked separately in the fencingAgents field. -// +kubebuilder:validation:Enum=Kubelet;Etcd -// +enum -type PacemakerClusterResourceName string - -// PacemakerClusterResourceName values -const ( - // PacemakerClusterResourceNameKubelet is the kubelet pacemaker resource. - // The kubelet resource is a prerequisite for etcd in Two Node OpenShift with Fencing deployments. - PacemakerClusterResourceNameKubelet PacemakerClusterResourceName = "Kubelet" - - // PacemakerClusterResourceNameEtcd is the etcd pacemaker resource. - // The etcd resource may temporarily transition to stopped during pacemaker quorum-recovery operations. - PacemakerClusterResourceNameEtcd PacemakerClusterResourceName = "Etcd" -) - -// FencingMethod represents the method used by a fencing agent to isolate failed nodes. -// Valid values are "Redfish" and "IPMI". -// +kubebuilder:validation:Enum=Redfish;IPMI -// +enum -type FencingMethod string - -// FencingMethod values -const ( - // FencingMethodRedfish uses Redfish, a standard RESTful API for server management. - FencingMethodRedfish FencingMethod = "Redfish" - - // FencingMethodIPMI uses IPMI (Intelligent Platform Management Interface), a hardware management interface. - FencingMethodIPMI FencingMethod = "IPMI" -) - -// +genclient -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// PacemakerCluster represents the current state of the pacemaker cluster as reported by the pcs status command. -// PacemakerCluster is a cluster-scoped singleton resource. The name of this instance is "cluster". This -// resource provides a view into the health and status of a pacemaker-managed cluster in Two Node OpenShift with Fencing deployments. -// -// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support. -// +openshift:compatibility-gen:level=4 -// +kubebuilder:object:root=true -// +kubebuilder:resource:path=pacemakerclusters,scope=Cluster,singular=pacemakercluster -// +kubebuilder:subresource:status -// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/2544 -// +openshift:file-pattern=cvoRunLevel=0000_25,operatorName=etcd,operatorOrdering=01,operatorComponent=two-node-fencing -// +openshift:enable:FeatureGate=DualReplica -// +kubebuilder:validation:XValidation:rule="self.metadata.name == 'cluster'",message="PacemakerCluster must be named 'cluster'" -// +kubebuilder:validation:XValidation:rule="!has(oldSelf.status) || has(self.status)",message="status may not be removed once set" -type PacemakerCluster struct { - metav1.TypeMeta `json:",inline"` - - // metadata is the standard object's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +required - metav1.ObjectMeta `json:"metadata,omitempty"` - - // status contains the actual pacemaker cluster status information collected from the cluster. - // The goal of this status is to be able to quickly identify if pacemaker is in a healthy state. - // In Two Node OpenShift with Fencing, a healthy pacemaker cluster has 2 nodes, both of which have healthy kubelet, etcd, and fencing resources. - // This field is optional on creation - the status collector populates it immediately after creating - // the resource via the status subresource. - // +optional - Status PacemakerClusterStatus `json:"status,omitzero"` -} - -// PacemakerClusterStatus contains the actual pacemaker cluster status information. As part of validating the status -// object, we need to ensure that the lastUpdated timestamp may not be set to an earlier timestamp than the current value. -// The validation rule checks if oldSelf has lastUpdated before comparing, to handle the initial status creation case. -// +kubebuilder:validation:XValidation:rule="!has(oldSelf.lastUpdated) || self.lastUpdated >= oldSelf.lastUpdated",message="lastUpdated may not be set to an earlier timestamp" -type PacemakerClusterStatus struct { - // conditions represent the observations of the pacemaker cluster's current state. - // Known condition types are: "Healthy", "InService", "NodeCountAsExpected". - // The "Healthy" condition is an aggregate that tracks the overall health of the cluster. - // The "InService" condition tracks whether the cluster is in service (not in maintenance mode). - // The "NodeCountAsExpected" condition tracks whether the expected number of nodes are present. - // Each of these conditions is required, so the array must contain at least 3 items. - // +listType=map - // +listMapKey=type - // +kubebuilder:validation:MinItems=3 - // +kubebuilder:validation:MaxItems=8 - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Healthy')",message="conditions must contain a condition of type Healthy" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'InService')",message="conditions must contain a condition of type InService" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'NodeCountAsExpected')",message="conditions must contain a condition of type NodeCountAsExpected" - // +required - Conditions []metav1.Condition `json:"conditions,omitempty"` - - // lastUpdated is the timestamp when this status was last updated. This is useful for identifying - // stale status reports. It must be a valid timestamp in RFC3339 format. Once set, this field cannot - // be removed and cannot be set to an earlier timestamp than the current value. - // +kubebuilder:validation:Format=date-time - // +required - LastUpdated metav1.Time `json:"lastUpdated,omitempty,omitzero"` - - // nodes provides detailed status for each control-plane node in the Pacemaker cluster. - // While Pacemaker supports up to 32 nodes, the limit is set to 5 (max OpenShift control-plane nodes). - // For Two Node OpenShift with Fencing, exactly 2 nodes are expected in a healthy cluster. - // An empty list indicates a catastrophic failure where Pacemaker reports no nodes. - // +listType=map - // +listMapKey=nodeName - // +kubebuilder:validation:MinItems=0 - // +kubebuilder:validation:MaxItems=5 - // +required - Nodes *[]PacemakerClusterNodeStatus `json:"nodes,omitempty"` -} - -// PacemakerClusterNodeStatus represents the status of a single node in the pacemaker cluster including -// the node's conditions and the health of critical resources running on that node. -type PacemakerClusterNodeStatus struct { - // conditions represent the observations of the node's current state. - // Known condition types are: "Healthy", "Online", "InService", "Active", "Ready", "Clean", "Member", - // "FencingAvailable", "FencingHealthy". - // The "Healthy" condition is an aggregate that tracks the overall health of the node. - // The "Online" condition tracks whether the node is online. - // The "InService" condition tracks whether the node is in service (not in maintenance mode). - // The "Active" condition tracks whether the node is active (not in standby mode). - // The "Ready" condition tracks whether the node is ready (not in a pending state). - // The "Clean" condition tracks whether the node is in a clean (status known) state. - // The "Member" condition tracks whether the node is a member of the cluster. - // The "FencingAvailable" condition tracks whether this node can be fenced by at least one healthy agent. - // The "FencingHealthy" condition tracks whether all fencing agents for this node are healthy. - // Each of these conditions is required, so the array must contain at least 9 items. - // +listType=map - // +listMapKey=type - // +kubebuilder:validation:MinItems=9 - // +kubebuilder:validation:MaxItems=16 - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Healthy')",message="conditions must contain a condition of type Healthy" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Online')",message="conditions must contain a condition of type Online" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'InService')",message="conditions must contain a condition of type InService" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Active')",message="conditions must contain a condition of type Active" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Ready')",message="conditions must contain a condition of type Ready" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Clean')",message="conditions must contain a condition of type Clean" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Member')",message="conditions must contain a condition of type Member" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'FencingAvailable')",message="conditions must contain a condition of type FencingAvailable" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'FencingHealthy')",message="conditions must contain a condition of type FencingHealthy" - // +required - Conditions []metav1.Condition `json:"conditions,omitempty"` - - // nodeName is the name of the node. This is expected to match the Kubernetes node's name, which must be a lowercase - // RFC 1123 subdomain consisting of lowercase alphanumeric characters, '-' or '.', starting and ending with - // an alphanumeric character, and be at most 253 characters in length. - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=253 - // +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="nodeName must be a lowercase RFC 1123 subdomain consisting of lowercase alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character" - // +required - NodeName string `json:"nodeName,omitempty"` - - // addresses is a list of IP addresses for the node. - // Pacemaker allows multiple IP addresses for Corosync communication between nodes. - // The first address in this list is used for IP-based peer URLs for etcd membership. - // Each address must be a valid global unicast IPv4 or IPv6 address in canonical form - // (e.g., "192.168.1.1" not "192.168.001.001", or "2001:db8::1" not "2001:0db8::1"). - // This excludes loopback, link-local, and multicast addresses. - // +listType=atomic - // +kubebuilder:validation:MinItems=1 - // +kubebuilder:validation:MaxItems=8 - // +required - Addresses []PacemakerNodeAddress `json:"addresses,omitempty"` - - // resources contains the status of pacemaker resources scheduled on this node. - // Each resource entry includes the resource name and its health conditions. - // For Two Node OpenShift with Fencing, we track Kubelet and Etcd resources per node. - // Both resources are required to be present, so the array must contain at least 2 items. - // Valid resource names are "Kubelet" and "Etcd". - // Fencing agents are tracked separately in the fencingAgents field. - // +listType=map - // +listMapKey=name - // +kubebuilder:validation:MinItems=2 - // +kubebuilder:validation:MaxItems=8 - // +kubebuilder:validation:XValidation:rule="self.exists(r, r.name == 'Kubelet')",message="resources must contain a resource named Kubelet" - // +kubebuilder:validation:XValidation:rule="self.exists(r, r.name == 'Etcd')",message="resources must contain a resource named Etcd" - // +required - Resources []PacemakerClusterResourceStatus `json:"resources,omitempty"` - - // fencingAgents contains the status of fencing agents that can fence this node. - // Unlike resources (which are scheduled to run on this node), fencing agents are mapped - // to the node they can fence (their target), not the node where monitoring operations run. - // Each fencing agent entry includes a unique name, fencing type, target node, and health conditions. - // A node is considered fence-capable if at least one fencing agent is healthy. - // Expected to have 1 fencing agent per node, but up to 8 are supported for redundancy. - // Names must be unique within this array. - // +listType=map - // +listMapKey=name - // +kubebuilder:validation:MinItems=1 - // +kubebuilder:validation:MaxItems=8 - // +kubebuilder:validation:XValidation:rule="self.all(x, self.exists_one(y, x.name == y.name))",message="fencing agent names must be unique" - // +required - FencingAgents []PacemakerClusterFencingAgentStatus `json:"fencingAgents,omitempty"` -} - -// PacemakerClusterFencingAgentStatus represents the status of a fencing agent that can fence a node. -// Fencing agents are STONITH (Shoot The Other Node In The Head) devices used to isolate failed nodes. -// Unlike regular pacemaker resources, fencing agents are mapped to their target node (the node they -// can fence), not the node where their monitoring operations are scheduled. -type PacemakerClusterFencingAgentStatus struct { - // conditions represent the observations of the fencing agent's current state. - // Known condition types are: "Healthy", "InService", "Managed", "Enabled", "Operational", - // "Active", "Started", "Schedulable". - // The "Healthy" condition is an aggregate that tracks the overall health of the fencing agent. - // The "InService" condition tracks whether the fencing agent is in service (not in maintenance mode). - // The "Managed" condition tracks whether the fencing agent is managed by pacemaker. - // The "Enabled" condition tracks whether the fencing agent is enabled. - // The "Operational" condition tracks whether the fencing agent is operational (not failed). - // The "Active" condition tracks whether the fencing agent is active (available to be used). - // The "Started" condition tracks whether the fencing agent is started. - // The "Schedulable" condition tracks whether the fencing agent is schedulable (not blocked). - // Each of these conditions is required, so the array must contain at least 8 items. - // +listType=map - // +listMapKey=type - // +kubebuilder:validation:MinItems=8 - // +kubebuilder:validation:MaxItems=16 - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Healthy')",message="conditions must contain a condition of type Healthy" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'InService')",message="conditions must contain a condition of type InService" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Managed')",message="conditions must contain a condition of type Managed" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Enabled')",message="conditions must contain a condition of type Enabled" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Operational')",message="conditions must contain a condition of type Operational" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Active')",message="conditions must contain a condition of type Active" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Started')",message="conditions must contain a condition of type Started" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Schedulable')",message="conditions must contain a condition of type Schedulable" - // +required - Conditions []metav1.Condition `json:"conditions,omitempty"` - - // name is the unique identifier for this fencing agent (e.g., "master-0_redfish"). - // The name must be unique within the fencingAgents array for this node. - // It may contain alphanumeric characters, dots, hyphens, and underscores. - // Maximum length is 300 characters, providing headroom beyond the typical format of - // _ (253 for RFC 1123 node name + 1 underscore + type). - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=300 - // +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._-]+$')",message="name must contain only alphanumeric characters, dots, hyphens, and underscores" - // +required - Name string `json:"name,omitempty"` - - // method is the fencing method used by this agent. - // Valid values are "Redfish" and "IPMI". - // Redfish is a standard RESTful API for server management. - // IPMI (Intelligent Platform Management Interface) is a hardware management interface. - // +required - Method FencingMethod `json:"method,omitempty"` -} - -// PacemakerClusterResourceStatus represents the status of a pacemaker resource scheduled on a node. -// A pacemaker resource is a unit of work managed by pacemaker. In pacemaker terminology, resources are services or -// applications that pacemaker monitors, starts, stops, and moves between nodes to maintain high availability. -// For Two Node OpenShift with Fencing, we track two resources per node: -// - Kubelet (the Kubernetes node agent and a prerequisite for etcd) -// - Etcd (the distributed key-value store) -// -// Fencing agents are tracked separately in the fencingAgents field because they are mapped to -// their target node (the node they can fence), not the node where monitoring operations are scheduled. -type PacemakerClusterResourceStatus struct { - // conditions represent the observations of the resource's current state. - // Known condition types are: "Healthy", "InService", "Managed", "Enabled", "Operational", - // "Active", "Started", "Schedulable". - // The "Healthy" condition is an aggregate that tracks the overall health of the resource. - // The "InService" condition tracks whether the resource is in service (not in maintenance mode). - // The "Managed" condition tracks whether the resource is managed by pacemaker. - // The "Enabled" condition tracks whether the resource is enabled. - // The "Operational" condition tracks whether the resource is operational (not failed). - // The "Active" condition tracks whether the resource is active (available to be used). - // The "Started" condition tracks whether the resource is started. - // The "Schedulable" condition tracks whether the resource is schedulable (not blocked). - // Each of these conditions is required, so the array must contain at least 8 items. - // +listType=map - // +listMapKey=type - // +kubebuilder:validation:MinItems=8 - // +kubebuilder:validation:MaxItems=16 - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Healthy')",message="conditions must contain a condition of type Healthy" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'InService')",message="conditions must contain a condition of type InService" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Managed')",message="conditions must contain a condition of type Managed" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Enabled')",message="conditions must contain a condition of type Enabled" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Operational')",message="conditions must contain a condition of type Operational" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Active')",message="conditions must contain a condition of type Active" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Started')",message="conditions must contain a condition of type Started" - // +kubebuilder:validation:XValidation:rule="self.exists(c, c.type == 'Schedulable')",message="conditions must contain a condition of type Schedulable" - // +required - Conditions []metav1.Condition `json:"conditions,omitempty"` - - // name is the name of the pacemaker resource. - // Valid values are "Kubelet" and "Etcd". - // The Kubelet resource is a prerequisite for etcd in Two Node OpenShift with Fencing deployments. - // The Etcd resource may temporarily transition to stopped during pacemaker quorum-recovery operations. - // Fencing agents are tracked separately in the node's fencingAgents field. - // +required - Name PacemakerClusterResourceName `json:"name,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// PacemakerClusterList contains a list of PacemakerCluster objects. PacemakerCluster is a cluster-scoped singleton -// resource; only one instance named "cluster" may exist. This list type exists only to satisfy Kubernetes API -// conventions. -// -// Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support. -// +openshift:compatibility-gen:level=4 -type PacemakerClusterList struct { - metav1.TypeMeta `json:",inline"` - - // metadata is the standard list's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - metav1.ListMeta `json:"metadata,omitempty"` - - // items is a list of PacemakerCluster objects. - Items []PacemakerCluster `json:"items"` -} diff --git a/vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.deepcopy.go deleted file mode 100644 index 17bf978510d8..000000000000 --- a/vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.deepcopy.go +++ /dev/null @@ -1,210 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -// Code generated by codegen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PacemakerCluster) DeepCopyInto(out *PacemakerCluster) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Status.DeepCopyInto(&out.Status) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PacemakerCluster. -func (in *PacemakerCluster) DeepCopy() *PacemakerCluster { - if in == nil { - return nil - } - out := new(PacemakerCluster) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PacemakerCluster) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PacemakerClusterFencingAgentStatus) DeepCopyInto(out *PacemakerClusterFencingAgentStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PacemakerClusterFencingAgentStatus. -func (in *PacemakerClusterFencingAgentStatus) DeepCopy() *PacemakerClusterFencingAgentStatus { - if in == nil { - return nil - } - out := new(PacemakerClusterFencingAgentStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PacemakerClusterList) DeepCopyInto(out *PacemakerClusterList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]PacemakerCluster, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PacemakerClusterList. -func (in *PacemakerClusterList) DeepCopy() *PacemakerClusterList { - if in == nil { - return nil - } - out := new(PacemakerClusterList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PacemakerClusterList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PacemakerClusterNodeStatus) DeepCopyInto(out *PacemakerClusterNodeStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Addresses != nil { - in, out := &in.Addresses, &out.Addresses - *out = make([]PacemakerNodeAddress, len(*in)) - copy(*out, *in) - } - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = make([]PacemakerClusterResourceStatus, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.FencingAgents != nil { - in, out := &in.FencingAgents, &out.FencingAgents - *out = make([]PacemakerClusterFencingAgentStatus, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PacemakerClusterNodeStatus. -func (in *PacemakerClusterNodeStatus) DeepCopy() *PacemakerClusterNodeStatus { - if in == nil { - return nil - } - out := new(PacemakerClusterNodeStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PacemakerClusterResourceStatus) DeepCopyInto(out *PacemakerClusterResourceStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PacemakerClusterResourceStatus. -func (in *PacemakerClusterResourceStatus) DeepCopy() *PacemakerClusterResourceStatus { - if in == nil { - return nil - } - out := new(PacemakerClusterResourceStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PacemakerClusterStatus) DeepCopyInto(out *PacemakerClusterStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - in.LastUpdated.DeepCopyInto(&out.LastUpdated) - if in.Nodes != nil { - in, out := &in.Nodes, &out.Nodes - *out = new([]PacemakerClusterNodeStatus) - if **in != nil { - in, out := *in, *out - *out = make([]PacemakerClusterNodeStatus, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PacemakerClusterStatus. -func (in *PacemakerClusterStatus) DeepCopy() *PacemakerClusterStatus { - if in == nil { - return nil - } - out := new(PacemakerClusterStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PacemakerNodeAddress) DeepCopyInto(out *PacemakerNodeAddress) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PacemakerNodeAddress. -func (in *PacemakerNodeAddress) DeepCopy() *PacemakerNodeAddress { - if in == nil { - return nil - } - out := new(PacemakerNodeAddress) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.featuregated-crd-manifests.yaml deleted file mode 100644 index f5a64682ab23..000000000000 --- a/vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.featuregated-crd-manifests.yaml +++ /dev/null @@ -1,23 +0,0 @@ -pacemakerclusters.etcd.openshift.io: - Annotations: {} - ApprovedPRNumber: https://github.com/openshift/api/pull/2544 - CRDName: pacemakerclusters.etcd.openshift.io - Capability: "" - Category: "" - FeatureGates: - - DualReplica - FilenameOperatorName: etcd - FilenameOperatorOrdering: "01" - FilenameRunLevel: "0000_25" - GroupName: etcd.openshift.io - HasStatus: true - KindName: PacemakerCluster - Labels: {} - PluralName: pacemakerclusters - PrinterColumns: [] - Scope: Cluster - ShortNames: null - TopLevelFeatureGates: - - DualReplica - Version: v1alpha1 - diff --git a/vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.swagger_doc_generated.go deleted file mode 100644 index 62e1c3ebd7db..000000000000 --- a/vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.swagger_doc_generated.go +++ /dev/null @@ -1,89 +0,0 @@ -package v1alpha1 - -// This file contains a collection of methods that can be used from go-restful to -// generate Swagger API documentation for its models. Please read this PR for more -// information on the implementation: https://github.com/emicklei/go-restful/pull/215 -// -// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if -// they are on one line! For multiple line or blocks that you want to ignore use ---. -// Any context after a --- is ignored. -// -// Those methods can be generated by using hack/update-swagger-docs.sh - -// AUTO-GENERATED FUNCTIONS START HERE -var map_PacemakerCluster = map[string]string{ - "": "PacemakerCluster represents the current state of the pacemaker cluster as reported by the pcs status command. PacemakerCluster is a cluster-scoped singleton resource. The name of this instance is \"cluster\". This resource provides a view into the health and status of a pacemaker-managed cluster in Two Node OpenShift with Fencing deployments.\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", - "metadata": "metadata is the standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "status": "status contains the actual pacemaker cluster status information collected from the cluster. The goal of this status is to be able to quickly identify if pacemaker is in a healthy state. In Two Node OpenShift with Fencing, a healthy pacemaker cluster has 2 nodes, both of which have healthy kubelet, etcd, and fencing resources. This field is optional on creation - the status collector populates it immediately after creating the resource via the status subresource.", -} - -func (PacemakerCluster) SwaggerDoc() map[string]string { - return map_PacemakerCluster -} - -var map_PacemakerClusterFencingAgentStatus = map[string]string{ - "": "PacemakerClusterFencingAgentStatus represents the status of a fencing agent that can fence a node. Fencing agents are STONITH (Shoot The Other Node In The Head) devices used to isolate failed nodes. Unlike regular pacemaker resources, fencing agents are mapped to their target node (the node they can fence), not the node where their monitoring operations are scheduled.", - "conditions": "conditions represent the observations of the fencing agent's current state. Known condition types are: \"Healthy\", \"InService\", \"Managed\", \"Enabled\", \"Operational\", \"Active\", \"Started\", \"Schedulable\". The \"Healthy\" condition is an aggregate that tracks the overall health of the fencing agent. The \"InService\" condition tracks whether the fencing agent is in service (not in maintenance mode). The \"Managed\" condition tracks whether the fencing agent is managed by pacemaker. The \"Enabled\" condition tracks whether the fencing agent is enabled. The \"Operational\" condition tracks whether the fencing agent is operational (not failed). The \"Active\" condition tracks whether the fencing agent is active (available to be used). The \"Started\" condition tracks whether the fencing agent is started. The \"Schedulable\" condition tracks whether the fencing agent is schedulable (not blocked). Each of these conditions is required, so the array must contain at least 8 items.", - "name": "name is the unique identifier for this fencing agent (e.g., \"master-0_redfish\"). The name must be unique within the fencingAgents array for this node. It may contain alphanumeric characters, dots, hyphens, and underscores. Maximum length is 300 characters, providing headroom beyond the typical format of _ (253 for RFC 1123 node name + 1 underscore + type).", - "method": "method is the fencing method used by this agent. Valid values are \"Redfish\" and \"IPMI\". Redfish is a standard RESTful API for server management. IPMI (Intelligent Platform Management Interface) is a hardware management interface.", -} - -func (PacemakerClusterFencingAgentStatus) SwaggerDoc() map[string]string { - return map_PacemakerClusterFencingAgentStatus -} - -var map_PacemakerClusterList = map[string]string{ - "": "PacemakerClusterList contains a list of PacemakerCluster objects. PacemakerCluster is a cluster-scoped singleton resource; only one instance named \"cluster\" may exist. This list type exists only to satisfy Kubernetes API conventions.\n\nCompatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support.", - "metadata": "metadata is the standard list's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "items is a list of PacemakerCluster objects.", -} - -func (PacemakerClusterList) SwaggerDoc() map[string]string { - return map_PacemakerClusterList -} - -var map_PacemakerClusterNodeStatus = map[string]string{ - "": "PacemakerClusterNodeStatus represents the status of a single node in the pacemaker cluster including the node's conditions and the health of critical resources running on that node.", - "conditions": "conditions represent the observations of the node's current state. Known condition types are: \"Healthy\", \"Online\", \"InService\", \"Active\", \"Ready\", \"Clean\", \"Member\", \"FencingAvailable\", \"FencingHealthy\". The \"Healthy\" condition is an aggregate that tracks the overall health of the node. The \"Online\" condition tracks whether the node is online. The \"InService\" condition tracks whether the node is in service (not in maintenance mode). The \"Active\" condition tracks whether the node is active (not in standby mode). The \"Ready\" condition tracks whether the node is ready (not in a pending state). The \"Clean\" condition tracks whether the node is in a clean (status known) state. The \"Member\" condition tracks whether the node is a member of the cluster. The \"FencingAvailable\" condition tracks whether this node can be fenced by at least one healthy agent. The \"FencingHealthy\" condition tracks whether all fencing agents for this node are healthy. Each of these conditions is required, so the array must contain at least 9 items.", - "nodeName": "nodeName is the name of the node. This is expected to match the Kubernetes node's name, which must be a lowercase RFC 1123 subdomain consisting of lowercase alphanumeric characters, '-' or '.', starting and ending with an alphanumeric character, and be at most 253 characters in length.", - "addresses": "addresses is a list of IP addresses for the node. Pacemaker allows multiple IP addresses for Corosync communication between nodes. The first address in this list is used for IP-based peer URLs for etcd membership. Each address must be a valid global unicast IPv4 or IPv6 address in canonical form (e.g., \"192.168.1.1\" not \"192.168.001.001\", or \"2001:db8::1\" not \"2001:0db8::1\"). This excludes loopback, link-local, and multicast addresses.", - "resources": "resources contains the status of pacemaker resources scheduled on this node. Each resource entry includes the resource name and its health conditions. For Two Node OpenShift with Fencing, we track Kubelet and Etcd resources per node. Both resources are required to be present, so the array must contain at least 2 items. Valid resource names are \"Kubelet\" and \"Etcd\". Fencing agents are tracked separately in the fencingAgents field.", - "fencingAgents": "fencingAgents contains the status of fencing agents that can fence this node. Unlike resources (which are scheduled to run on this node), fencing agents are mapped to the node they can fence (their target), not the node where monitoring operations run. Each fencing agent entry includes a unique name, fencing type, target node, and health conditions. A node is considered fence-capable if at least one fencing agent is healthy. Expected to have 1 fencing agent per node, but up to 8 are supported for redundancy. Names must be unique within this array.", -} - -func (PacemakerClusterNodeStatus) SwaggerDoc() map[string]string { - return map_PacemakerClusterNodeStatus -} - -var map_PacemakerClusterResourceStatus = map[string]string{ - "": "PacemakerClusterResourceStatus represents the status of a pacemaker resource scheduled on a node. A pacemaker resource is a unit of work managed by pacemaker. In pacemaker terminology, resources are services or applications that pacemaker monitors, starts, stops, and moves between nodes to maintain high availability. For Two Node OpenShift with Fencing, we track two resources per node:\n - Kubelet (the Kubernetes node agent and a prerequisite for etcd)\n - Etcd (the distributed key-value store)\n\nFencing agents are tracked separately in the fencingAgents field because they are mapped to their target node (the node they can fence), not the node where monitoring operations are scheduled.", - "conditions": "conditions represent the observations of the resource's current state. Known condition types are: \"Healthy\", \"InService\", \"Managed\", \"Enabled\", \"Operational\", \"Active\", \"Started\", \"Schedulable\". The \"Healthy\" condition is an aggregate that tracks the overall health of the resource. The \"InService\" condition tracks whether the resource is in service (not in maintenance mode). The \"Managed\" condition tracks whether the resource is managed by pacemaker. The \"Enabled\" condition tracks whether the resource is enabled. The \"Operational\" condition tracks whether the resource is operational (not failed). The \"Active\" condition tracks whether the resource is active (available to be used). The \"Started\" condition tracks whether the resource is started. The \"Schedulable\" condition tracks whether the resource is schedulable (not blocked). Each of these conditions is required, so the array must contain at least 8 items.", - "name": "name is the name of the pacemaker resource. Valid values are \"Kubelet\" and \"Etcd\". The Kubelet resource is a prerequisite for etcd in Two Node OpenShift with Fencing deployments. The Etcd resource may temporarily transition to stopped during pacemaker quorum-recovery operations. Fencing agents are tracked separately in the node's fencingAgents field.", -} - -func (PacemakerClusterResourceStatus) SwaggerDoc() map[string]string { - return map_PacemakerClusterResourceStatus -} - -var map_PacemakerClusterStatus = map[string]string{ - "": "PacemakerClusterStatus contains the actual pacemaker cluster status information. As part of validating the status object, we need to ensure that the lastUpdated timestamp may not be set to an earlier timestamp than the current value. The validation rule checks if oldSelf has lastUpdated before comparing, to handle the initial status creation case.", - "conditions": "conditions represent the observations of the pacemaker cluster's current state. Known condition types are: \"Healthy\", \"InService\", \"NodeCountAsExpected\". The \"Healthy\" condition is an aggregate that tracks the overall health of the cluster. The \"InService\" condition tracks whether the cluster is in service (not in maintenance mode). The \"NodeCountAsExpected\" condition tracks whether the expected number of nodes are present. Each of these conditions is required, so the array must contain at least 3 items.", - "lastUpdated": "lastUpdated is the timestamp when this status was last updated. This is useful for identifying stale status reports. It must be a valid timestamp in RFC3339 format. Once set, this field cannot be removed and cannot be set to an earlier timestamp than the current value.", - "nodes": "nodes provides detailed status for each control-plane node in the Pacemaker cluster. While Pacemaker supports up to 32 nodes, the limit is set to 5 (max OpenShift control-plane nodes). For Two Node OpenShift with Fencing, exactly 2 nodes are expected in a healthy cluster. An empty list indicates a catastrophic failure where Pacemaker reports no nodes.", -} - -func (PacemakerClusterStatus) SwaggerDoc() map[string]string { - return map_PacemakerClusterStatus -} - -var map_PacemakerNodeAddress = map[string]string{ - "": "PacemakerNodeAddress contains information for a node's address. This is similar to corev1.NodeAddress but adds validation for IP addresses.", - "type": "type is the type of node address. Currently only \"InternalIP\" is supported.", - "address": "address is the node address. For InternalIP, this must be a valid global unicast IPv4 or IPv6 address in canonical form. Canonical form means the shortest standard representation (e.g., \"192.168.1.1\" not \"192.168.001.001\", or \"2001:db8::1\" not \"2001:0db8::1\"). Maximum length is 39 characters (full IPv6 address). Global unicast includes private/RFC1918 addresses but excludes loopback, link-local, and multicast.", -} - -func (PacemakerNodeAddress) SwaggerDoc() map[string]string { - return map_PacemakerNodeAddress -} - -// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/github.com/openshift/api/features.md b/vendor/github.com/openshift/api/features.md index d2a18f5da0ed..fd8d9fa77dfa 100644 --- a/vendor/github.com/openshift/api/features.md +++ b/vendor/github.com/openshift/api/features.md @@ -5,15 +5,13 @@ | EventedPLEG| | | | | | | | | | MachineAPIOperatorDisableMachineHealthCheckController| | | | | | | | | | MultiArchInstallAzure| | | | | | | | | +| NewOLMBoxCutterRuntime| | | | | | | | | | ShortCertRotation| | | | | | | | | -| ClusterAPIComputeInstall| | | Enabled | Enabled | | | | | -| ClusterAPIControlPlaneInstall| | | Enabled | Enabled | | | | | | ClusterAPIMachineManagementVSphere| | | Enabled | Enabled | | | | | | Example2| | | Enabled | Enabled | | | | | | ExternalSnapshotMetadata| | | Enabled | Enabled | | | | | -| KMSEncryptionProvider| | | Enabled | Enabled | | | | | +| IngressControllerDynamicConfigurationManager| | | Enabled | Enabled | | | | | | NetworkConnect| | | Enabled | Enabled | | | | | -| NewOLMBoxCutterRuntime| | | | Enabled | | | | Enabled | | NewOLMCatalogdAPIV1Metas| | | | Enabled | | | | Enabled | | NewOLMPreflightPermissionChecks| | | | Enabled | | | | Enabled | | NoRegistryClusterInstall| | | | Enabled | | | | Enabled | @@ -32,7 +30,6 @@ | BootcNodeManagement| | | Enabled | Enabled | | | Enabled | Enabled | | CBORServingAndStorage| | | Enabled | Enabled | | | Enabled | Enabled | | CRDCompatibilityRequirementOperator| | | Enabled | Enabled | | | Enabled | Enabled | -| CRIOCredentialProviderConfig| | | Enabled | Enabled | | | Enabled | Enabled | | ClientsPreferCBOR| | | Enabled | Enabled | | | Enabled | Enabled | | ClusterAPIInstallIBMCloud| | | Enabled | Enabled | | | Enabled | Enabled | | ClusterAPIMachineManagement| | | Enabled | Enabled | | | Enabled | Enabled | @@ -41,10 +38,8 @@ | ClusterVersionOperatorConfiguration| | | Enabled | Enabled | | | Enabled | Enabled | | ConfigurablePKI| | | Enabled | Enabled | | | Enabled | Enabled | | DNSNameResolver| | | Enabled | Enabled | | | Enabled | Enabled | -| DRAPartitionableDevices| | | Enabled | Enabled | | | Enabled | Enabled | | DualReplica| | | Enabled | Enabled | | | Enabled | Enabled | | DyanmicServiceEndpointIBMCloud| | | Enabled | Enabled | | | Enabled | Enabled | -| EVPN| | | Enabled | Enabled | | | Enabled | Enabled | | EtcdBackendQuota| | | Enabled | Enabled | | | Enabled | Enabled | | EventTTL| | | Enabled | Enabled | | | Enabled | Enabled | | Example| | | Enabled | Enabled | | | Enabled | Enabled | @@ -53,19 +48,19 @@ | GCPCustomAPIEndpoints| | | Enabled | Enabled | | | Enabled | Enabled | | GCPCustomAPIEndpointsInstall| | | Enabled | Enabled | | | Enabled | Enabled | | GCPDualStackInstall| | | Enabled | Enabled | | | Enabled | Enabled | -| GatewayAPIWithoutOLM| | | Enabled | Enabled | | | Enabled | Enabled | | HyperShiftOnlyDynamicResourceAllocation| Enabled | | Enabled | | Enabled | | Enabled | | | ImageModeStatusReporting| | | Enabled | Enabled | | | Enabled | Enabled | -| IngressControllerDynamicConfigurationManager| | | Enabled | Enabled | | | Enabled | Enabled | | InsightsConfig| | | Enabled | Enabled | | | Enabled | Enabled | | InsightsOnDemandDataGather| | | Enabled | Enabled | | | Enabled | Enabled | | IrreconcilableMachineConfig| | | Enabled | Enabled | | | Enabled | Enabled | -| KMSEncryption| | | Enabled | Enabled | | | Enabled | Enabled | +| KMSEncryptionProvider| | | Enabled | Enabled | | | Enabled | Enabled | | MachineAPIMigration| | | Enabled | Enabled | | | Enabled | Enabled | +| ManagedBootImagesCPMS| | | Enabled | Enabled | | | Enabled | Enabled | | MaxUnavailableStatefulSet| | | Enabled | Enabled | | | Enabled | Enabled | | MinimumKubeletVersion| | | Enabled | Enabled | | | Enabled | Enabled | | MixedCPUsAllocation| | | Enabled | Enabled | | | Enabled | Enabled | | MultiDiskSetup| | | Enabled | Enabled | | | Enabled | Enabled | +| MutableCSINodeAllocatableCount| | | Enabled | Enabled | | | Enabled | Enabled | | MutatingAdmissionPolicy| | | Enabled | Enabled | | | Enabled | Enabled | | NewOLM| | Enabled | | Enabled | | Enabled | | Enabled | | NewOLMOwnSingleNamespace| | Enabled | | Enabled | | Enabled | | Enabled | @@ -80,6 +75,9 @@ | VSphereHostVMGroupZonal| | | Enabled | Enabled | | | Enabled | Enabled | | VSphereMixedNodeEnv| | | Enabled | Enabled | | | Enabled | Enabled | | VolumeGroupSnapshot| | | Enabled | Enabled | | | Enabled | Enabled | +| AdditionalRoutingCapabilities| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | +| AdminNetworkPolicy| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | +| AlibabaPlatform| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | AzureWorkloadIdentity| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | BuildCSIVolumes| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | CPMSMachineNamePrefix| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | @@ -97,12 +95,16 @@ | ManagedBootImages| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | ManagedBootImagesAWS| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | ManagedBootImagesAzure| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | -| ManagedBootImagesCPMS| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | ManagedBootImagesvSphere| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | MetricsCollectionProfiles| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | -| MutableCSINodeAllocatableCount| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | +| NetworkDiagnosticsConfig| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | +| NetworkLiveMigration| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | +| NetworkSegmentation| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | OpenShiftPodSecurityAdmission| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | PinnedImages| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | +| PreconfiguredUDNAddresses| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | +| ProcMountType| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | +| RouteAdvertisements| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | RouteExternalCertificate| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | ServiceAccountTokenNodeBinding| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | SigstoreImageVerification| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | @@ -113,3 +115,4 @@ | UserNamespacesSupport| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | VSphereMultiDisk| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | VSphereMultiNetworks| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | +| VolumeAttributesClass| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | diff --git a/vendor/github.com/openshift/api/features/features.go b/vendor/github.com/openshift/api/features/features.go index 36a479071a1b..9159b43d3463 100644 --- a/vendor/github.com/openshift/api/features/features.go +++ b/vendor/github.com/openshift/api/features/features.go @@ -131,13 +131,13 @@ var ( enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade, configv1.Default, configv1.OKD). mustRegister() - FeatureGateCRIOCredentialProviderConfig = newFeatureGate("CRIOCredentialProviderConfig"). - reportProblemsToJiraComponent("node"). - contactPerson("QiWang"). - productScope(ocpSpecific). - enhancementPR("https://github.com/openshift/enhancements/pull/1861"). - enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). - mustRegister() + FeatureGateAlibabaPlatform = newFeatureGate("AlibabaPlatform"). + reportProblemsToJiraComponent("cloud-provider"). + contactPerson("jspeed"). + productScope(ocpSpecific). + enhancementPR(legacyFeatureGateWithoutEnhancement). + enableIn(configv1.Default, configv1.OKD, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). + mustRegister() FeatureGateVSphereHostVMGroupZonal = newFeatureGate("VSphereHostVMGroupZonal"). reportProblemsToJiraComponent("splat"). @@ -171,6 +171,22 @@ var ( enableIn(configv1.Default, configv1.OKD, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). mustRegister() + FeatureGateAdminNetworkPolicy = newFeatureGate("AdminNetworkPolicy"). + reportProblemsToJiraComponent("Networking/ovn-kubernetes"). + contactPerson("tssurya"). + productScope(ocpSpecific). + enhancementPR(legacyFeatureGateWithoutEnhancement). + enableIn(configv1.Default, configv1.OKD, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). + mustRegister() + + FeatureGateNetworkSegmentation = newFeatureGate("NetworkSegmentation"). + reportProblemsToJiraComponent("Networking/ovn-kubernetes"). + contactPerson("tssurya"). + productScope(ocpSpecific). + enhancementPR("https://github.com/openshift/enhancements/pull/1623"). + enableIn(configv1.Default, configv1.OKD, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). + mustRegister() + FeatureGateNetworkConnect = newFeatureGate("NetworkConnect"). reportProblemsToJiraComponent("Networking/ovn-kubernetes"). contactPerson("tssurya"). @@ -179,13 +195,37 @@ var ( enableIn(configv1.DevPreviewNoUpgrade). mustRegister() - FeatureGateEVPN = newFeatureGate("EVPN"). - reportProblemsToJiraComponent("Networking/ovn-kubernetes"). - contactPerson("jcaamano"). - productScope(ocpSpecific). - enhancementPR("https://github.com/openshift/enhancements/pull/1862"). - enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). - mustRegister() + FeatureGateAdditionalRoutingCapabilities = newFeatureGate("AdditionalRoutingCapabilities"). + reportProblemsToJiraComponent("Networking/cluster-network-operator"). + contactPerson("jcaamano"). + productScope(ocpSpecific). + enhancementPR(legacyFeatureGateWithoutEnhancement). + enableIn(configv1.Default, configv1.OKD, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). + mustRegister() + + FeatureGateRouteAdvertisements = newFeatureGate("RouteAdvertisements"). + reportProblemsToJiraComponent("Networking/ovn-kubernetes"). + contactPerson("jcaamano"). + productScope(ocpSpecific). + enhancementPR(legacyFeatureGateWithoutEnhancement). + enableIn(configv1.Default, configv1.OKD, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). + mustRegister() + + FeatureGateNetworkLiveMigration = newFeatureGate("NetworkLiveMigration"). + reportProblemsToJiraComponent("Networking/ovn-kubernetes"). + contactPerson("pliu"). + productScope(ocpSpecific). + enhancementPR(legacyFeatureGateWithoutEnhancement). + enableIn(configv1.Default, configv1.OKD, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). + mustRegister() + + FeatureGateNetworkDiagnosticsConfig = newFeatureGate("NetworkDiagnosticsConfig"). + reportProblemsToJiraComponent("Networking/cluster-network-operator"). + contactPerson("kyrtapz"). + productScope(ocpSpecific). + enhancementPR(legacyFeatureGateWithoutEnhancement). + enableIn(configv1.Default, configv1.OKD, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). + mustRegister() FeatureGateOVNObservability = newFeatureGate("OVNObservability"). reportProblemsToJiraComponent("Networking"). @@ -318,7 +358,7 @@ var ( contactPerson("djoshy"). productScope(ocpSpecific). enhancementPR("https://github.com/openshift/enhancements/pull/1818"). - enableIn(configv1.Default, configv1.OKD, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). + enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). mustRegister() FeatureGateBootImageSkewEnforcement = newFeatureGate("BootImageSkewEnforcement"). @@ -369,6 +409,14 @@ var ( enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade, configv1.Default, configv1.OKD). mustRegister() + FeatureGateVolumeAttributesClass = newFeatureGate("VolumeAttributesClass"). + reportProblemsToJiraComponent("Storage / Kubernetes External Components"). + contactPerson("dfajmon"). + productScope(kubernetes). + enhancementPR("https://github.com/kubernetes/enhancements/issues/3751"). + enableIn(configv1.Default, configv1.OKD, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). + mustRegister() + FeatureGateVolumeGroupSnapshot = newFeatureGate("VolumeGroupSnapshot"). reportProblemsToJiraComponent("Storage / Kubernetes External Components"). contactPerson("fbertina"). @@ -470,7 +518,6 @@ var ( contactPerson("pegoncal"). productScope(ocpSpecific). enhancementPR("https://github.com/openshift/enhancements/pull/1890"). - enableForClusterProfile(SelfManaged, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). mustRegister() FeatureGateInsightsOnDemandDataGather = newFeatureGate("InsightsOnDemandDataGather"). @@ -571,6 +618,14 @@ var ( enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade, configv1.Default, configv1.OKD). mustRegister() + FeatureGateProcMountType = newFeatureGate("ProcMountType"). + reportProblemsToJiraComponent("Node"). + contactPerson("haircommander"). + productScope(kubernetes). + enhancementPR("https://github.com/kubernetes/enhancements/issues/4265"). + enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade, configv1.Default, configv1.OKD). + mustRegister() + FeatureGateVSphereMultiNetworks = newFeatureGate("VSphereMultiNetworks"). reportProblemsToJiraComponent("SPLAT"). contactPerson("rvanderp"). @@ -583,8 +638,8 @@ var ( reportProblemsToJiraComponent("Networking/router"). contactPerson("miciah"). productScope(ocpSpecific). - enhancementPR("https://github.com/openshift/enhancements/pull/1687"). - enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). + enhancementPR(legacyFeatureGateWithoutEnhancement). + enableIn(configv1.DevPreviewNoUpgrade). mustRegister() FeatureGateMinimumKubeletVersion = newFeatureGate("MinimumKubeletVersion"). @@ -608,17 +663,9 @@ var ( contactPerson("swghosh"). productScope(ocpSpecific). enhancementPR("https://github.com/openshift/enhancements/pull/1682"). - enableIn(configv1.DevPreviewNoUpgrade). + enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). mustRegister() - FeatureGateKMSEncryption = newFeatureGate("KMSEncryption"). - reportProblemsToJiraComponent("kube-apiserver"). - contactPerson("ardaguclu"). - productScope(ocpSpecific). - enhancementPR("https://github.com/openshift/enhancements/pull/1900"). - enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). - mustRegister() - FeatureGateHighlyAvailableArbiter = newFeatureGate("HighlyAvailableArbiter"). reportProblemsToJiraComponent("Two Node with Arbiter"). contactPerson("eggfoobar"). @@ -743,6 +790,14 @@ var ( enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). mustRegister() + FeatureGatePreconfiguredUDNAddresses = newFeatureGate("PreconfiguredUDNAddresses"). + reportProblemsToJiraComponent("Networking/ovn-kubernetes"). + contactPerson("kyrtapz"). + productScope(ocpSpecific). + enhancementPR("https://github.com/openshift/enhancements/pull/1793"). + enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade, configv1.Default, configv1.OKD). + mustRegister() + FeatureGateAWSServiceLBNetworkSecurityGroup = newFeatureGate("AWSServiceLBNetworkSecurityGroup"). reportProblemsToJiraComponent("Cloud Compute / Cloud Controller Manager"). contactPerson("mtulio"). @@ -858,7 +913,7 @@ var ( contactPerson("jsafrane"). productScope(kubernetes). enhancementPR("https://github.com/kubernetes/enhancements/issues/4876"). - enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade, configv1.Default, configv1.OKD). + enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). mustRegister() FeatureGateOSStreams = newFeatureGate("OSStreams"). reportProblemsToJiraComponent("MachineConfigOperator"). @@ -899,14 +954,6 @@ var ( enableForClusterProfile(Hypershift, configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade, configv1.Default, configv1.OKD). mustRegister() - FeatureGateDRAPartitionableDevices = newFeatureGate("DRAPartitionableDevices"). - reportProblemsToJiraComponent("Node"). - contactPerson("harche"). - productScope(kubernetes). - enhancementPR("https://github.com/kubernetes/enhancements/issues/4815"). - enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). - mustRegister() - FeatureGateConfigurablePKI = newFeatureGate("ConfigurablePKI"). reportProblemsToJiraComponent("kube-apiserver"). contactPerson("sanchezl"). @@ -914,29 +961,4 @@ var ( enhancementPR("https://github.com/openshift/enhancements/pull/1882"). enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). mustRegister() - - FeatureGateClusterAPIControlPlaneInstall = newFeatureGate("ClusterAPIControlPlaneInstall"). - reportProblemsToJiraComponent("Installer / openshift-installer"). - contactPerson("patrickdillon"). - productScope(ocpSpecific). - enhancementPR("https://github.com/openshift/enhancements/pull/1465"). - enableIn(configv1.DevPreviewNoUpgrade). - mustRegister() - - FeatureGateClusterAPIComputeInstall = newFeatureGate("ClusterAPIComputeInstall"). - reportProblemsToJiraComponent("Installer / openshift-installer"). - contactPerson("patrickdillon"). - productScope(ocpSpecific). - enhancementPR("https://github.com/openshift/enhancements/pull/1465"). - enableIn(configv1.DevPreviewNoUpgrade). - mustRegister() - - FeatureGateGatewayAPIWithoutOLM = newFeatureGate("GatewayAPIWithoutOLM"). - reportProblemsToJiraComponent("Routing"). - contactPerson("miciah"). - productScope(ocpSpecific). - enhancementPR("https://github.com/openshift/enhancements/pull/1933"). - enableIn(configv1.DevPreviewNoUpgrade, configv1.TechPreviewNoUpgrade). - mustRegister() ) - diff --git a/vendor/github.com/openshift/api/features/legacyfeaturegates.go b/vendor/github.com/openshift/api/features/legacyfeaturegates.go index a92c0b9bb90f..dd11fdf6632a 100644 --- a/vendor/github.com/openshift/api/features/legacyfeaturegates.go +++ b/vendor/github.com/openshift/api/features/legacyfeaturegates.go @@ -7,6 +7,10 @@ var legacyFeatureGates = sets.New( // never add to this list, if you think you have an exception ask @deads2k "AWSEFSDriverVolumeMetrics", // never add to this list, if you think you have an exception ask @deads2k + "AdditionalRoutingCapabilities", + // never add to this list, if you think you have an exception ask @deads2k + "AdminNetworkPolicy", + // never add to this list, if you think you have an exception ask @deads2k "AlibabaPlatform", // never add to this list, if you think you have an exception ask @deads2k "AutomatedEtcdBackup", @@ -75,6 +79,12 @@ var legacyFeatureGates = sets.New( // never add to this list, if you think you have an exception ask @deads2k "MultiArchInstallGCP", // never add to this list, if you think you have an exception ask @deads2k + "NetworkDiagnosticsConfig", + // never add to this list, if you think you have an exception ask @deads2k + "NetworkLiveMigration", + // never add to this list, if you think you have an exception ask @deads2k + "NetworkSegmentation", + // never add to this list, if you think you have an exception ask @deads2k "NewOLM", // never add to this list, if you think you have an exception ask @deads2k "OVNObservability", @@ -85,6 +95,8 @@ var legacyFeatureGates = sets.New( // never add to this list, if you think you have an exception ask @deads2k "PrivateHostedZoneAWS", // never add to this list, if you think you have an exception ask @deads2k + "RouteAdvertisements", + // never add to this list, if you think you have an exception ask @deads2k "RouteExternalCertificate", // never add to this list, if you think you have an exception ask @deads2k "SetEIPForNLBIngressController", diff --git a/vendor/github.com/openshift/api/install.go b/vendor/github.com/openshift/api/install.go index e4574e7c4f52..ea5f349708ca 100644 --- a/vendor/github.com/openshift/api/install.go +++ b/vendor/github.com/openshift/api/install.go @@ -55,7 +55,6 @@ import ( "github.com/openshift/api/cloudnetwork" "github.com/openshift/api/config" "github.com/openshift/api/console" - "github.com/openshift/api/etcd" "github.com/openshift/api/helm" "github.com/openshift/api/image" "github.com/openshift/api/imageregistry" @@ -92,7 +91,6 @@ var ( build.Install, config.Install, console.Install, - etcd.Install, helm.Install, image.Install, imageregistry.Install, diff --git a/vendor/github.com/openshift/api/machine/v1beta1/types_awsprovider.go b/vendor/github.com/openshift/api/machine/v1beta1/types_awsprovider.go index e3508d6679d5..d1d5941fa836 100644 --- a/vendor/github.com/openshift/api/machine/v1beta1/types_awsprovider.go +++ b/vendor/github.com/openshift/api/machine/v1beta1/types_awsprovider.go @@ -331,16 +331,9 @@ type Filter struct { // TagSpecification is the name/value pair for a tag type TagSpecification struct { - // name of the tag. - // This field is required and must be a non-empty string. - // Must be between 1 and 128 characters in length. - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=128 - // +required + // name of the tag Name string `json:"name"` - // value of the tag. - // When omitted, this creates a tag with an empty string as the value. - // +optional + // value of the tag Value string `json:"value"` } @@ -414,26 +407,6 @@ type AWSMachineProviderStatus struct { // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:"conditions,omitempty"` - // dedicatedHost tracks the dynamically allocated dedicated host. - // This field is populated when allocationStrategy is Dynamic (with or without DynamicHostAllocation). - // When omitted, this indicates that the dedicated host has not yet been allocated, or allocation is in progress. - // +optional - DedicatedHost *DedicatedHostStatus `json:"dedicatedHost,omitempty"` -} - -// DedicatedHostStatus defines the observed state of a dynamically allocated dedicated host -// associated with an AWSMachine. This struct is used to track the ID of the dedicated host. -type DedicatedHostStatus struct { - // id tracks the dynamically allocated dedicated host ID. - // This field is populated when allocationStrategy is Dynamic (with or without DynamicHostAllocation). - // The value must start with "h-" followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f). - // The use of 8 lowercase hexadecimal characters is for older legacy hosts that may not have been migrated to newer format. - // Must be either 10 or 19 characters in length. - // +kubebuilder:validation:XValidation:rule="self.matches('^h-([0-9a-f]{8}|[0-9a-f]{17})$')",message="id must start with 'h-' followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f)" - // +kubebuilder:validation:MinLength=10 - // +kubebuilder:validation:MaxLength=19 - // +required - ID string `json:"id,omitempty"` } // MarketType describes the market type of an EC2 Instance @@ -481,77 +454,21 @@ type HostAffinity string const ( // HostAffinityAnyAvailable lets the platform select any available dedicated host. - HostAffinityAnyAvailable HostAffinity = "AnyAvailable" // HostAffinityDedicatedHost requires specifying a particular host via dedicatedHost.host.hostID. HostAffinityDedicatedHost HostAffinity = "DedicatedHost" ) -// AllocationStrategy selects how a dedicated host is provided to the system for assigning to the instance. -// +kubebuilder:validation:Enum:=UserProvided;Dynamic -// +enum -type AllocationStrategy string - -const ( - // AllocationStrategyUserProvided specifies that the system should assign instances to a user-provided dedicated host. - AllocationStrategyUserProvided AllocationStrategy = "UserProvided" - - // AllocationStrategyDynamic specifies that the system should dynamically allocate a dedicated host for instances. - AllocationStrategyDynamic AllocationStrategy = "Dynamic" -) - // DedicatedHost represents the configuration for the usage of dedicated host. -// +kubebuilder:validation:XValidation:rule="self.allocationStrategy == 'UserProvided' ? has(self.id) : !has(self.id)",message="id is required when allocationStrategy is UserProvided, and forbidden otherwise" -// +kubebuilder:validation:XValidation:rule="has(self.dynamicHostAllocation) ? self.allocationStrategy == 'Dynamic' : true",message="dynamicHostAllocation is only allowed when allocationStrategy is Dynamic" -// +union type DedicatedHost struct { - // allocationStrategy specifies if the dedicated host will be provided by the admin through the id field or if the host will be dynamically allocated. - // Valid values are UserProvided and Dynamic. - // When omitted, the value defaults to "UserProvided", which requires the id field to be set. - // When allocationStrategy is set to UserProvided, an ID of the dedicated host to assign must be provided. - // When allocationStrategy is set to Dynamic, a dedicated host will be allocated and used to assign instances. - // When allocationStrategy is set to Dynamic, and dynamicHostAllocation is configured, a dedicated host will be allocated and the tags in dynamicHostAllocation will be assigned to that host. - // +optional - // +unionDiscriminator - // +default="UserProvided" - AllocationStrategy *AllocationStrategy `json:"allocationStrategy,omitempty"` - // id identifies the AWS Dedicated Host on which the instance must run. // The value must start with "h-" followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f). // The use of 8 lowercase hexadecimal characters is for older legacy hosts that may not have been migrated to newer format. // Must be either 10 or 19 characters in length. - // This field is required when allocationStrategy is UserProvided, and forbidden otherwise. - // When omitted with allocationStrategy set to Dynamic, the platform will dynamically allocate a dedicated host. - // +kubebuilder:validation:XValidation:rule="self.matches('^h-([0-9a-f]{8}|[0-9a-f]{17})$')",message="id must start with 'h-' followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f)" + // +kubebuilder:validation:XValidation:rule="self.matches('^h-([0-9a-f]{8}|[0-9a-f]{17})$')",message="hostID must start with 'h-' followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f)" // +kubebuilder:validation:MinLength=10 // +kubebuilder:validation:MaxLength=19 - // +optional - // +unionMember=UserProvided + // +required ID string `json:"id,omitempty"` - - // dynamicHostAllocation specifies tags to apply to a dynamically allocated dedicated host. - // This field is only allowed when allocationStrategy is Dynamic, and is mutually exclusive with id. - // When specified, a dedicated host will be allocated with the provided tags applied. - // When omitted (and allocationStrategy is Dynamic), a dedicated host will be allocated without any additional tags. - // +optional - // +unionMember=Dynamic - DynamicHostAllocation *DynamicHostAllocationSpec `json:"dynamicHostAllocation,omitempty"` -} - -// DynamicHostAllocationSpec defines the configuration for dynamic dedicated host allocation. -// This specification always allocates exactly one dedicated host per machine. -// At least one property must be specified when this struct is used. -// Currently only Tags are available for configuring, but in the future more configs may become available. -// +kubebuilder:validation:MinProperties=1 -type DynamicHostAllocationSpec struct { - // tags specifies a set of key-value pairs to apply to the allocated dedicated host. - // When omitted, no additional user-defined tags will be applied to the allocated host. - // A maximum of 50 tags can be specified. - // +kubebuilder:validation:MinItems=1 - // +kubebuilder:validation:MaxItems=50 - // +listType=map - // +listMapKey=name - // +optional - Tags *[]TagSpecification `json:"tags,omitempty"` } diff --git a/vendor/github.com/openshift/api/machine/v1beta1/types_machine.go b/vendor/github.com/openshift/api/machine/v1beta1/types_machine.go index 6bfe850812b8..9510b49fddf7 100644 --- a/vendor/github.com/openshift/api/machine/v1beta1/types_machine.go +++ b/vendor/github.com/openshift/api/machine/v1beta1/types_machine.go @@ -185,18 +185,6 @@ const ( MachineAuthorityMigrating MachineAuthority = "Migrating" ) -// SynchronizedAPI holds the last stable value of authoritativeAPI. -// +kubebuilder:validation:Enum=MachineAPI;ClusterAPI -type SynchronizedAPI string - -const ( - // MachineAPISynchronized indicates that the Machine API is the last synchronized API. - MachineAPISynchronized SynchronizedAPI = "MachineAPI" - - // ClusterAPISynchronized indicates that the Cluster API is the last synchronized API. - ClusterAPISynchronized SynchronizedAPI = "ClusterAPI" -) - // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -419,14 +407,6 @@ type MachineStatus struct { // +optional AuthoritativeAPI MachineAuthority `json:"authoritativeAPI,omitempty"` - // synchronizedAPI holds the last stable value of authoritativeAPI. - // It is used to detect migration cancellation requests and to restore the resource to its previous state. - // Valid values are "MachineAPI" and "ClusterAPI". - // When omitted, the resource has not yet been reconciled by the migration controller. - // +openshift:enable:FeatureGate=MachineAPIMigration - // +optional - SynchronizedAPI SynchronizedAPI `json:"synchronizedAPI,omitempty"` - // synchronizedGeneration is the generation of the authoritative resource that the non-authoritative resource is synchronised with. // This field is set when the authoritative resource is updated and the sync controller has updated the non-authoritative resource to match. // +kubebuilder:validation:Minimum=0 diff --git a/vendor/github.com/openshift/api/machine/v1beta1/types_machineset.go b/vendor/github.com/openshift/api/machine/v1beta1/types_machineset.go index be5476344b12..80cb282b7ffd 100644 --- a/vendor/github.com/openshift/api/machine/v1beta1/types_machineset.go +++ b/vendor/github.com/openshift/api/machine/v1beta1/types_machineset.go @@ -169,14 +169,6 @@ type MachineSetStatus struct { // +optional AuthoritativeAPI MachineAuthority `json:"authoritativeAPI,omitempty"` - // synchronizedAPI holds the last stable value of authoritativeAPI. - // It is used to detect migration cancellation requests and to restore the resource to its previous state. - // Valid values are "MachineAPI" and "ClusterAPI". - // When omitted, the resource has not yet been reconciled by the migration controller. - // +openshift:enable:FeatureGate=MachineAPIMigration - // +optional - SynchronizedAPI SynchronizedAPI `json:"synchronizedAPI,omitempty"` - // synchronizedGeneration is the generation of the authoritative resource that the non-authoritative resource is synchronised with. // This field is set when the authoritative resource is updated and the sync controller has updated the non-authoritative resource to match. // +kubebuilder:validation:Minimum=0 diff --git a/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.deepcopy.go index 63b9bb5ff813..d08906c7d871 100644 --- a/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.deepcopy.go @@ -152,11 +152,6 @@ func (in *AWSMachineProviderStatus) DeepCopyInto(out *AWSMachineProviderStatus) (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.DedicatedHost != nil { - in, out := &in.DedicatedHost, &out.DedicatedHost - *out = new(DedicatedHostStatus) - **out = **in - } return } @@ -517,16 +512,6 @@ func (in *DataDiskManagedDiskParameters) DeepCopy() *DataDiskManagedDiskParamete // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DedicatedHost) DeepCopyInto(out *DedicatedHost) { *out = *in - if in.AllocationStrategy != nil { - in, out := &in.AllocationStrategy, &out.AllocationStrategy - *out = new(AllocationStrategy) - **out = **in - } - if in.DynamicHostAllocation != nil { - in, out := &in.DynamicHostAllocation, &out.DynamicHostAllocation - *out = new(DynamicHostAllocationSpec) - (*in).DeepCopyInto(*out) - } return } @@ -540,22 +525,6 @@ func (in *DedicatedHost) DeepCopy() *DedicatedHost { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DedicatedHostStatus) DeepCopyInto(out *DedicatedHostStatus) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DedicatedHostStatus. -func (in *DedicatedHostStatus) DeepCopy() *DedicatedHostStatus { - if in == nil { - return nil - } - out := new(DedicatedHostStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DiskEncryptionSetParameters) DeepCopyInto(out *DiskEncryptionSetParameters) { *out = *in @@ -588,31 +557,6 @@ func (in *DiskSettings) DeepCopy() *DiskSettings { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DynamicHostAllocationSpec) DeepCopyInto(out *DynamicHostAllocationSpec) { - *out = *in - if in.Tags != nil { - in, out := &in.Tags, &out.Tags - *out = new([]TagSpecification) - if **in != nil { - in, out := *in, *out - *out = make([]TagSpecification, len(*in)) - copy(*out, *in) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicHostAllocationSpec. -func (in *DynamicHostAllocationSpec) DeepCopy() *DynamicHostAllocationSpec { - if in == nil { - return nil - } - out := new(DynamicHostAllocationSpec) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EBSBlockDeviceSpec) DeepCopyInto(out *EBSBlockDeviceSpec) { *out = *in @@ -991,7 +935,7 @@ func (in *HostPlacement) DeepCopyInto(out *HostPlacement) { if in.DedicatedHost != nil { in, out := &in.DedicatedHost, &out.DedicatedHost *out = new(DedicatedHost) - (*in).DeepCopyInto(*out) + **out = **in } return } diff --git a/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go index 2c4a9030cc9c..093a40076946 100644 --- a/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go @@ -54,7 +54,6 @@ var map_AWSMachineProviderStatus = map[string]string{ "instanceId": "instanceId is the instance ID of the machine created in AWS", "instanceState": "instanceState is the state of the AWS instance for this machine", "conditions": "conditions is a set of conditions associated with the Machine to indicate errors or other status", - "dedicatedHost": "dedicatedHost tracks the dynamically allocated dedicated host. This field is populated when allocationStrategy is Dynamic (with or without DynamicHostAllocation). When omitted, this indicates that the dedicated host has not yet been allocated, or allocation is in progress.", } func (AWSMachineProviderStatus) SwaggerDoc() map[string]string { @@ -94,34 +93,14 @@ func (CPUOptions) SwaggerDoc() map[string]string { } var map_DedicatedHost = map[string]string{ - "": "DedicatedHost represents the configuration for the usage of dedicated host.", - "allocationStrategy": "allocationStrategy specifies if the dedicated host will be provided by the admin through the id field or if the host will be dynamically allocated. Valid values are UserProvided and Dynamic. When omitted, the value defaults to \"UserProvided\", which requires the id field to be set. When allocationStrategy is set to UserProvided, an ID of the dedicated host to assign must be provided. When allocationStrategy is set to Dynamic, a dedicated host will be allocated and used to assign instances. When allocationStrategy is set to Dynamic, and dynamicHostAllocation is configured, a dedicated host will be allocated and the tags in dynamicHostAllocation will be assigned to that host.", - "id": "id identifies the AWS Dedicated Host on which the instance must run. The value must start with \"h-\" followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f). The use of 8 lowercase hexadecimal characters is for older legacy hosts that may not have been migrated to newer format. Must be either 10 or 19 characters in length. This field is required when allocationStrategy is UserProvided, and forbidden otherwise. When omitted with allocationStrategy set to Dynamic, the platform will dynamically allocate a dedicated host.", - "dynamicHostAllocation": "dynamicHostAllocation specifies tags to apply to a dynamically allocated dedicated host. This field is only allowed when allocationStrategy is Dynamic, and is mutually exclusive with id. When specified, a dedicated host will be allocated with the provided tags applied. When omitted (and allocationStrategy is Dynamic), a dedicated host will be allocated without any additional tags.", + "": "DedicatedHost represents the configuration for the usage of dedicated host.", + "id": "id identifies the AWS Dedicated Host on which the instance must run. The value must start with \"h-\" followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f). The use of 8 lowercase hexadecimal characters is for older legacy hosts that may not have been migrated to newer format. Must be either 10 or 19 characters in length.", } func (DedicatedHost) SwaggerDoc() map[string]string { return map_DedicatedHost } -var map_DedicatedHostStatus = map[string]string{ - "": "DedicatedHostStatus defines the observed state of a dynamically allocated dedicated host associated with an AWSMachine. This struct is used to track the ID of the dedicated host.", - "id": "id tracks the dynamically allocated dedicated host ID. This field is populated when allocationStrategy is Dynamic (with or without DynamicHostAllocation). The value must start with \"h-\" followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f). The use of 8 lowercase hexadecimal characters is for older legacy hosts that may not have been migrated to newer format. Must be either 10 or 19 characters in length.", -} - -func (DedicatedHostStatus) SwaggerDoc() map[string]string { - return map_DedicatedHostStatus -} - -var map_DynamicHostAllocationSpec = map[string]string{ - "": "DynamicHostAllocationSpec defines the configuration for dynamic dedicated host allocation. This specification always allocates exactly one dedicated host per machine. At least one property must be specified when this struct is used. Currently only Tags are available for configuring, but in the future more configs may become available.", - "tags": "tags specifies a set of key-value pairs to apply to the allocated dedicated host. When omitted, no additional user-defined tags will be applied to the allocated host. A maximum of 50 tags can be specified.", -} - -func (DynamicHostAllocationSpec) SwaggerDoc() map[string]string { - return map_DynamicHostAllocationSpec -} - var map_EBSBlockDeviceSpec = map[string]string{ "": "EBSBlockDeviceSpec describes a block device for an EBS volume. https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EbsBlockDevice", "deleteOnTermination": "Indicates whether the EBS volume is deleted on machine termination.\n\nDeprecated: setting this field has no effect.", @@ -197,8 +176,8 @@ func (SpotMarketOptions) SwaggerDoc() map[string]string { var map_TagSpecification = map[string]string{ "": "TagSpecification is the name/value pair for a tag", - "name": "name of the tag. This field is required and must be a non-empty string. Must be between 1 and 128 characters in length.", - "value": "value of the tag. When omitted, this creates a tag with an empty string as the value.", + "name": "name of the tag", + "value": "value of the tag", } func (TagSpecification) SwaggerDoc() map[string]string { @@ -647,7 +626,6 @@ var map_MachineStatus = map[string]string{ "phase": "phase represents the current phase of machine actuation. One of: Failed, Provisioning, Provisioned, Running, Deleting", "conditions": "conditions defines the current state of the Machine", "authoritativeAPI": "authoritativeAPI is the API that is authoritative for this resource. Valid values are MachineAPI, ClusterAPI and Migrating. This value is updated by the migration controller to reflect the authoritative API. Machine API and Cluster API controllers use this value to determine whether or not to reconcile the resource. When set to Migrating, the migration controller is currently performing the handover of authority from one API to the other.", - "synchronizedAPI": "synchronizedAPI holds the last stable value of authoritativeAPI. It is used to detect migration cancellation requests and to restore the resource to its previous state. Valid values are \"MachineAPI\" and \"ClusterAPI\". When omitted, the resource has not yet been reconciled by the migration controller.", "synchronizedGeneration": "synchronizedGeneration is the generation of the authoritative resource that the non-authoritative resource is synchronised with. This field is set when the authoritative resource is updated and the sync controller has updated the non-authoritative resource to match.", } @@ -751,7 +729,6 @@ var map_MachineSetStatus = map[string]string{ "errorReason": "In the event that there is a terminal problem reconciling the replicas, both ErrorReason and ErrorMessage will be set. ErrorReason will be populated with a succinct value suitable for machine interpretation, while ErrorMessage will contain a more verbose string suitable for logging and human consumption.\n\nThese fields should not be set for transitive errors that a controller faces that are expected to be fixed automatically over time (like service outages), but instead indicate that something is fundamentally wrong with the MachineTemplate's spec or the configuration of the machine controller, and that manual intervention is required. Examples of terminal errors would be invalid combinations of settings in the spec, values that are unsupported by the machine controller, or the responsible machine controller itself being critically misconfigured.\n\nAny transient errors that occur during the reconciliation of Machines can be added as events to the MachineSet object and/or logged in the controller's output.", "conditions": "conditions defines the current state of the MachineSet", "authoritativeAPI": "authoritativeAPI is the API that is authoritative for this resource. Valid values are MachineAPI, ClusterAPI and Migrating. This value is updated by the migration controller to reflect the authoritative API. Machine API and Cluster API controllers use this value to determine whether or not to reconcile the resource. When set to Migrating, the migration controller is currently performing the handover of authority from one API to the other.", - "synchronizedAPI": "synchronizedAPI holds the last stable value of authoritativeAPI. It is used to detect migration cancellation requests and to restore the resource to its previous state. Valid values are \"MachineAPI\" and \"ClusterAPI\". When omitted, the resource has not yet been reconciled by the migration controller.", "synchronizedGeneration": "synchronizedGeneration is the generation of the authoritative resource that the non-authoritative resource is synchronised with. This field is set when the authoritative resource is updated and the sync controller has updated the non-authoritative resource to match.", } diff --git a/vendor/github.com/openshift/api/operator/v1/types_machineconfiguration.go b/vendor/github.com/openshift/api/operator/v1/types_machineconfiguration.go index f5836af0f8cc..c6bcd22bc0fc 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_machineconfiguration.go +++ b/vendor/github.com/openshift/api/operator/v1/types_machineconfiguration.go @@ -18,8 +18,7 @@ import ( // Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer). // +openshift:compatibility-gen:level=1 // +openshift:validation:FeatureGateAwareXValidation:featureGate=BootImageSkewEnforcement,rule="self.?status.bootImageSkewEnforcementStatus.mode.orValue(\"\") == 'Automatic' ? self.?spec.managedBootImages.hasValue() || self.?status.managedBootImagesStatus.hasValue() : true",message="when skew enforcement is in Automatic mode, a boot image configuration is required" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=BootImageSkewEnforcement,rule="self.?status.bootImageSkewEnforcementStatus.mode.orValue(\"\") == 'Automatic' ? !(self.?spec.managedBootImages.machineManagers.hasValue()) || size(self.spec.managedBootImages.machineManagers) > 0 : true",message="when skew enforcement is in Automatic mode, managedBootImages.machineManagers must not be an empty list" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=BootImageSkewEnforcement,rule="self.?status.bootImageSkewEnforcementStatus.mode.orValue(\"\") == 'Automatic' ? !(self.?spec.managedBootImages.machineManagers.hasValue()) || !self.spec.managedBootImages.machineManagers.exists(m, m.resource == 'machinesets' && m.apiGroup == 'machine.openshift.io') || self.spec.managedBootImages.machineManagers.exists(m, m.resource == 'machinesets' && m.apiGroup == 'machine.openshift.io' && m.selection.mode == 'All') : true",message="when skew enforcement is in Automatic mode, any MachineAPI MachineSet MachineManager must use selection mode 'All'" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=BootImageSkewEnforcement,rule="self.?status.bootImageSkewEnforcementStatus.mode.orValue(\"\") == 'Automatic' ? !(self.?spec.managedBootImages.machineManagers.hasValue()) || self.spec.managedBootImages.machineManagers.exists(m, m.selection.mode == 'All' && m.resource == 'machinesets' && m.apiGroup == 'machine.openshift.io') : true",message="when skew enforcement is in Automatic mode, managedBootImages must contain a MachineManager opting in all MachineAPI MachineSets" // +openshift:validation:FeatureGateAwareXValidation:featureGate=BootImageSkewEnforcement,rule="self.?status.bootImageSkewEnforcementStatus.mode.orValue(\"\") == 'Automatic' ? !(self.?status.managedBootImagesStatus.machineManagers.hasValue()) || self.status.managedBootImagesStatus.machineManagers.exists(m, m.selection.mode == 'All' && m.resource == 'machinesets' && m.apiGroup == 'machine.openshift.io'): true",message="when skew enforcement is in Automatic mode, managedBootImagesStatus must contain a MachineManager opting in all MachineAPI MachineSets" type MachineConfiguration struct { metav1.TypeMeta `json:",inline"` diff --git a/vendor/github.com/openshift/api/operator/v1/types_network.go b/vendor/github.com/openshift/api/operator/v1/types_network.go index 1cf56f549bfc..111240eecff0 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_network.go +++ b/vendor/github.com/openshift/api/operator/v1/types_network.go @@ -54,7 +54,7 @@ type NetworkList struct { // NetworkSpec is the top-level network configuration object. // +kubebuilder:validation:XValidation:rule="!has(self.defaultNetwork) || !has(self.defaultNetwork.ovnKubernetesConfig) || !has(self.defaultNetwork.ovnKubernetesConfig.gatewayConfig) || !has(self.defaultNetwork.ovnKubernetesConfig.gatewayConfig.ipForwarding) || self.defaultNetwork.ovnKubernetesConfig.gatewayConfig.ipForwarding == oldSelf.defaultNetwork.ovnKubernetesConfig.gatewayConfig.ipForwarding || self.defaultNetwork.ovnKubernetesConfig.gatewayConfig.ipForwarding == 'Restricted' || self.defaultNetwork.ovnKubernetesConfig.gatewayConfig.ipForwarding == 'Global'",message="invalid value for IPForwarding, valid values are 'Restricted' or 'Global'" -// +kubebuilder:validation:XValidation:rule="(has(self.additionalRoutingCapabilities) && ('FRR' in self.additionalRoutingCapabilities.providers)) || !has(self.defaultNetwork) || !has(self.defaultNetwork.ovnKubernetesConfig) || !has(self.defaultNetwork.ovnKubernetesConfig.routeAdvertisements) || self.defaultNetwork.ovnKubernetesConfig.routeAdvertisements != 'Enabled'",message="Route advertisements cannot be Enabled if 'FRR' routing capability provider is not available" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=RouteAdvertisements,rule="(has(self.additionalRoutingCapabilities) && ('FRR' in self.additionalRoutingCapabilities.providers)) || !has(self.defaultNetwork) || !has(self.defaultNetwork.ovnKubernetesConfig) || !has(self.defaultNetwork.ovnKubernetesConfig.routeAdvertisements) || self.defaultNetwork.ovnKubernetesConfig.routeAdvertisements != 'Enabled'",message="Route advertisements cannot be Enabled if 'FRR' routing capability provider is not available" type NetworkSpec struct { OperatorSpec `json:",inline"` @@ -136,6 +136,7 @@ type NetworkSpec struct { // capabilities acquired through the enablement of these components but may // require specific configuration on their side to do so; refer to their // respective documentation and configuration options. + // +openshift:enable:FeatureGate=AdditionalRoutingCapabilities // +optional AdditionalRoutingCapabilities *AdditionalRoutingCapabilities `json:"additionalRoutingCapabilities,omitempty"` } @@ -156,7 +157,7 @@ const ( ) // NetworkMigration represents the cluster network migration configuration. -// +kubebuilder:validation:XValidation:rule="!has(self.mtu) || !has(self.networkType) || self.networkType == \"\" || has(self.mode) && self.mode == 'Live'",message="networkType migration in mode other than 'Live' may not be configured at the same time as mtu migration" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=NetworkLiveMigration,rule="!has(self.mtu) || !has(self.networkType) || self.networkType == \"\" || has(self.mode) && self.mode == 'Live'",message="networkType migration in mode other than 'Live' may not be configured at the same time as mtu migration" type NetworkMigration struct { // mtu contains the MTU migration configuration. Set this to allow changing // the MTU values for the default network. If unset, the operation of @@ -464,6 +465,7 @@ type OVNKubernetesConfig struct { // means the user has no opinion and the platform is left to choose // reasonable defaults. These defaults are subject to change over time. The // current default is "Disabled". + // +openshift:enable:FeatureGate=RouteAdvertisements // +optional RouteAdvertisements RouteAdvertisementsEnablement `json:"routeAdvertisements,omitempty"` } diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml index 51a758804d60..e7c94e286946 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml @@ -327,7 +327,10 @@ networks.operator.openshift.io: CRDName: networks.operator.openshift.io Capability: "" Category: "" - FeatureGates: [] + FeatureGates: + - AdditionalRoutingCapabilities + - NetworkLiveMigration + - RouteAdvertisements FilenameOperatorName: network FilenameOperatorOrdering: "01" FilenameRunLevel: "0000_70" diff --git a/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go b/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go index be0337b90020..33a09ae16e37 100644 --- a/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go +++ b/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go @@ -30,8 +30,6 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/client-go/util/cert" - - configv1 "github.com/openshift/api/config/v1" ) // TLS versions that are known to golang. Go 1.13 adds support for @@ -143,11 +141,7 @@ var ciphers = map[string]uint16{ } // openSSLToIANACiphersMap maps OpenSSL cipher suite names to IANA names -// Ref: https://www.iana.org/assignments/tls-parameters/tls-parameters.xml -// This must hold a 1:1 mapping for each OpenSSL cipher defined in openshift/api TLSSecurityProfiles, -// so it can be used to translate OpenSSL ciphers to IANA ciphers, which is what go's crypto/tls understands. -// Ciphers in this map must also be compatible with go's crypto/tls ciphers: -// https://github.com/golang/go/blob/d4febb45179fa99ee1d5783bcb693ed7ba14115c/src/crypto/tls/cipher_suites.go#L682-L724 +// ref: https://www.iana.org/assignments/tls-parameters/tls-parameters.xml var openSSLToIANACiphersMap = map[string]string{ // TLS 1.3 ciphers - not configurable in go 1.13, all of them are used in TLSv1.3 flows "TLS_AES_128_GCM_SHA256": "TLS_AES_128_GCM_SHA256", // 0x13,0x01 @@ -167,21 +161,6 @@ var openSSLToIANACiphersMap = map[string]string{ "AES256-GCM-SHA384": "TLS_RSA_WITH_AES_256_GCM_SHA384", // 0x00,0x9D "AES128-SHA256": "TLS_RSA_WITH_AES_128_CBC_SHA256", // 0x00,0x3C - // Go's crypto/tls does not support CBC mode and DHE ciphers, so we don't want to include them here. - // See: - // - https://github.com/golang/go/issues/26652 - // - https://github.com/golang/go/issues/7758 - // - https://redhat-internal.slack.com/archives/C098FU5MRAB/p1770309657097269 - // - // "ECDHE-ECDSA-AES256-SHA384": "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", // 0xC0,0x24 - // "ECDHE-RSA-AES256-SHA384": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", // 0xC0,0x28 - // "AES256-SHA256": "TLS_RSA_WITH_AES_256_CBC_SHA256", // 0x00,0x3D - // "DHE-RSA-AES128-GCM-SHA256": "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", // 0x00,0x9E - // "DHE-RSA-AES256-GCM-SHA384": "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", // 0x00,0x9F - // "DHE-RSA-CHACHA20-POLY1305": "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", // 0xCC,0xAA - // "DHE-RSA-AES128-SHA256": "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", // 0x00,0x67 - // "DHE-RSA-AES256-SHA256": "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", // 0x00,0x6B - // TLS 1 "ECDHE-ECDSA-AES128-SHA": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", // 0xC0,0x09 "ECDHE-RSA-AES128-SHA": "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", // 0xC0,0x13 @@ -189,10 +168,9 @@ var openSSLToIANACiphersMap = map[string]string{ "ECDHE-RSA-AES256-SHA": "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", // 0xC0,0x14 // SSL 3 - "AES128-SHA": "TLS_RSA_WITH_AES_128_CBC_SHA", // 0x00,0x2F - "AES256-SHA": "TLS_RSA_WITH_AES_256_CBC_SHA", // 0x00,0x35 - "DES-CBC3-SHA": "TLS_RSA_WITH_3DES_EDE_CBC_SHA", // 0x00,0x0A - "ECDHE-RSA-DES-CBC3-SHA": "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", // 0xC0,0x12 + "AES128-SHA": "TLS_RSA_WITH_AES_128_CBC_SHA", // 0x00,0x2F + "AES256-SHA": "TLS_RSA_WITH_AES_256_CBC_SHA", // 0x00,0x35 + "DES-CBC3-SHA": "TLS_RSA_WITH_3DES_EDE_CBC_SHA", // 0x00,0x0A } // CipherSuitesToNamesOrDie given a list of cipher suites as ints, return their readable names @@ -264,44 +242,35 @@ func ValidCipherSuites() []string { sort.Strings(validCipherSuites) return validCipherSuites } - -// DefaultTLSProfileType is the intermediate profile type. -const DefaultTLSProfileType = configv1.TLSProfileIntermediateType - -// DefaultCiphers returns the default cipher suites for TLS connections. -// -// RECOMMENDATION: Instead of relying on this function directly, consumers should respect -// TLSSecurityProfile settings from one of the OpenShift API configuration resources: -// - For API servers: Use apiserver.config.openshift.io/cluster Spec.TLSSecurityProfile -// - For ingress controllers: Use operator.openshift.io/v1 IngressController Spec.TLSSecurityProfile -// - For kubelet: Use machineconfiguration.openshift.io/v1 KubeletConfig Spec.TLSSecurityProfile -// -// These API resources allow cluster administrators to choose between Old, Intermediate, -// Modern, or Custom TLS profiles. Components should observe these settings. func DefaultCiphers() []uint16 { - // Aligned with intermediate profile of the 5.7 version of the Mozilla Server - // Side TLS guidelines found at: https://ssl-config.mozilla.org/guidelines/5.7.json - // - // Latest guidelines: https://ssl-config.mozilla.org/guidelines/latest.json - // - // This profile provides strong security with wide compatibility. - // It requires TLS 1.2+ and uses only AEAD cipher suites (GCM, ChaCha20-Poly1305) - // with ECDHE key exchange for perfect forward secrecy. - // - // All CBC-mode ciphers have been removed due to padding oracle vulnerabilities. - // All RSA key exchange ciphers have been removed due to lack of perfect forward secrecy. - // - // HTTP/2 compliance: All ciphers are compliant with RFC7540, section 9.2. + // HTTP/2 mandates TLS 1.2 or higher with an AEAD cipher + // suite (GCM, Poly1305) and ephemeral key exchange (ECDHE, DHE) for + // perfect forward secrecy. Servers may provide additional cipher + // suites for backwards compatibility with HTTP/1.1 clients. + // See RFC7540, section 9.2 (Use of TLS Features) and Appendix A + // (TLS 1.2 Cipher Suite Black List). return []uint16{ - // TLS 1.2 cipher suites with ECDHE + AEAD tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // required by HTTP/2 + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // required by http/2 tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - - // TLS 1.3 cipher suites (negotiated automatically, not configurable) + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // forbidden by http/2, not flagged by http2isBadCipher() in go1.8 + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, // forbidden by http/2, not flagged by http2isBadCipher() in go1.8 + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, // forbidden by http/2 + tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, // forbidden by http/2 + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, // forbidden by http/2 + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, // forbidden by http/2 + tls.TLS_RSA_WITH_AES_128_GCM_SHA256, // forbidden by http/2 + tls.TLS_RSA_WITH_AES_256_GCM_SHA384, // forbidden by http/2 + // the next one is in the intermediate suite, but go1.8 http2isBadCipher() complains when it is included at the recommended index + // because it comes after ciphers forbidden by the http/2 spec + // tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + // tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, // forbidden by http/2, disabled to mitigate SWEET32 attack + // tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, // forbidden by http/2, disabled to mitigate SWEET32 attack + tls.TLS_RSA_WITH_AES_128_CBC_SHA, // forbidden by http/2 + tls.TLS_RSA_WITH_AES_256_CBC_SHA, // forbidden by http/2 tls.TLS_AES_128_GCM_SHA256, tls.TLS_AES_256_GCM_SHA384, tls.TLS_CHACHA20_POLY1305_SHA256, diff --git a/vendor/github.com/openshift/library-go/pkg/operator/certrotation/signer.go b/vendor/github.com/openshift/library-go/pkg/operator/certrotation/signer.go index c2c8b8368f62..1cb4e5554242 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/certrotation/signer.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/certrotation/signer.go @@ -188,7 +188,7 @@ func getValidityFromAnnotations(annotations map[string]string) (notBefore time.T return notBefore, notAfter, fmt.Sprintf("bad expiry: %q", notAfterString) } notBeforeString := annotations[CertificateNotBeforeAnnotation] - if len(notBeforeString) == 0 { + if len(notAfterString) == 0 { return notBefore, notAfter, "missing notBefore" } notBefore, err = time.Parse(time.RFC3339, notBeforeString) diff --git a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/admissionregistration.go b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/admissionregistration.go index 0b52c3a3242b..88bd00b25187 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/admissionregistration.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/admissionregistration.go @@ -415,51 +415,3 @@ func ApplyValidatingAdmissionPolicyBindingV1(ctx context.Context, client admissi cache.UpdateCachedResourceMetadata(requiredOriginal, actual) return actual, true, nil } - -func DeleteValidatingAdmissionPolicyV1beta1(ctx context.Context, client admissionregistrationclientv1beta1.ValidatingAdmissionPoliciesGetter, recorder events.Recorder, required *admissionregistrationv1beta1.ValidatingAdmissionPolicy) (*admissionregistrationv1beta1.ValidatingAdmissionPolicy, bool, error) { - err := client.ValidatingAdmissionPolicies().Delete(ctx, required.Name, metav1.DeleteOptions{}) - if err != nil && apierrors.IsNotFound(err) { - return nil, false, nil - } - if err != nil { - return nil, false, err - } - resourcehelper.ReportDeleteEvent(recorder, required, err) - return nil, true, nil -} - -func DeleteValidatingAdmissionPolicyBindingV1beta1(ctx context.Context, client admissionregistrationclientv1beta1.ValidatingAdmissionPolicyBindingsGetter, recorder events.Recorder, required *admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding) (*admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding, bool, error) { - err := client.ValidatingAdmissionPolicyBindings().Delete(ctx, required.Name, metav1.DeleteOptions{}) - if err != nil && apierrors.IsNotFound(err) { - return nil, false, nil - } - if err != nil { - return nil, false, err - } - resourcehelper.ReportDeleteEvent(recorder, required, err) - return nil, true, nil -} - -func DeleteValidatingAdmissionPolicyV1(ctx context.Context, client admissionregistrationclientv1.ValidatingAdmissionPoliciesGetter, recorder events.Recorder, required *admissionregistrationv1.ValidatingAdmissionPolicy) (*admissionregistrationv1.ValidatingAdmissionPolicy, bool, error) { - err := client.ValidatingAdmissionPolicies().Delete(ctx, required.Name, metav1.DeleteOptions{}) - if err != nil && apierrors.IsNotFound(err) { - return nil, false, nil - } - if err != nil { - return nil, false, err - } - resourcehelper.ReportDeleteEvent(recorder, required, err) - return nil, true, nil -} - -func DeleteValidatingAdmissionPolicyBindingV1(ctx context.Context, client admissionregistrationclientv1.ValidatingAdmissionPolicyBindingsGetter, recorder events.Recorder, required *admissionregistrationv1.ValidatingAdmissionPolicyBinding) (*admissionregistrationv1.ValidatingAdmissionPolicyBinding, bool, error) { - err := client.ValidatingAdmissionPolicyBindings().Delete(ctx, required.Name, metav1.DeleteOptions{}) - if err != nil && apierrors.IsNotFound(err) { - return nil, false, nil - } - if err != nil { - return nil, false, err - } - resourcehelper.ReportDeleteEvent(recorder, required, err) - return nil, true, nil -} diff --git a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/generic.go b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/generic.go index 58f49823f3f5..9105464bd093 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/generic.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/generic.go @@ -147,7 +147,7 @@ func ApplyDirectly(ctx context.Context, clients *ClientHolder, recorder events.R if clients.kubeClient == nil { result.Error = fmt.Errorf("missing kubeClient") } else { - result.Result, result.Changed, result.Error = ApplyNetworkPolicy(ctx, clients.kubeClient.NetworkingV1(), recorder, t, cache) + result.Result, result.Changed, result.Error = ApplyNetworkPolicy(ctx, clients.kubeClient.NetworkingV1(), recorder, t) } case *rbacv1.ClusterRole: if clients.kubeClient == nil { @@ -380,30 +380,6 @@ func DeleteAll(ctx context.Context, clients *ClientHolder, recorder events.Recor } else { _, result.Changed, result.Error = DeleteValidatingWebhookConfiguration(ctx, clients.kubeClient.AdmissionregistrationV1(), recorder, t) } - case *admissionregistrationv1beta1.ValidatingAdmissionPolicy: - if clients.kubeClient == nil { - result.Error = fmt.Errorf("missing kubeClient") - } else { - _, result.Changed, result.Error = DeleteValidatingAdmissionPolicyV1beta1(ctx, clients.kubeClient.AdmissionregistrationV1beta1(), recorder, t) - } - case *admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding: - if clients.kubeClient == nil { - result.Error = fmt.Errorf("missing kubeClient") - } else { - _, result.Changed, result.Error = DeleteValidatingAdmissionPolicyBindingV1beta1(ctx, clients.kubeClient.AdmissionregistrationV1beta1(), recorder, t) - } - case *admissionregistrationv1.ValidatingAdmissionPolicy: - if clients.kubeClient == nil { - result.Error = fmt.Errorf("missing kubeClient") - } else { - _, result.Changed, result.Error = DeleteValidatingAdmissionPolicyV1(ctx, clients.kubeClient.AdmissionregistrationV1(), recorder, t) - } - case *admissionregistrationv1.ValidatingAdmissionPolicyBinding: - if clients.kubeClient == nil { - result.Error = fmt.Errorf("missing kubeClient") - } else { - _, result.Changed, result.Error = DeleteValidatingAdmissionPolicyBindingV1(ctx, clients.kubeClient.AdmissionregistrationV1(), recorder, t) - } case *storagev1.CSIDriver: if clients.kubeClient == nil { result.Error = fmt.Errorf("missing kubeClient") diff --git a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/networking.go b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/networking.go index cc2de17ff346..0a3df326e4d0 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/networking.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/networking.go @@ -15,44 +15,34 @@ import ( "github.com/openshift/library-go/pkg/operator/resource/resourcemerge" ) -// ApplyNetworkPolicy merges objectmeta and requires spec -func ApplyNetworkPolicy(ctx context.Context, client networkingclientv1.NetworkPoliciesGetter, recorder events.Recorder, required *networkingv1.NetworkPolicy, cache ResourceCache) (*networkingv1.NetworkPolicy, bool, error) { +// ApplyClusterRole merges objectmeta, does not worry about anything else +func ApplyNetworkPolicy(ctx context.Context, client networkingclientv1.NetworkPoliciesGetter, recorder events.Recorder, required *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, bool, error) { existing, err := client.NetworkPolicies(required.Namespace).Get(ctx, required.Name, metav1.GetOptions{}) if apierrors.IsNotFound(err) { requiredCopy := required.DeepCopy() actual, err := client.NetworkPolicies(required.Namespace).Create( ctx, resourcemerge.WithCleanLabelsAndAnnotations(requiredCopy).(*networkingv1.NetworkPolicy), metav1.CreateOptions{}) resourcehelper.ReportCreateEvent(recorder, required, err) - cache.UpdateCachedResourceMetadata(required, actual) return actual, true, err } if err != nil { return nil, false, err } - if cache.SafeToSkipApply(required, existing) { - return existing, false, nil - } - modified := false existingCopy := existing.DeepCopy() resourcemerge.EnsureObjectMeta(&modified, &existingCopy.ObjectMeta, required.ObjectMeta) - specContentSame := equality.Semantic.DeepEqual(existingCopy.Spec, required.Spec) - if specContentSame && !modified { - cache.UpdateCachedResourceMetadata(required, existingCopy) + if equality.Semantic.DeepEqual(existingCopy.Spec, required.Spec) && !modified { return existingCopy, false, nil } - existingCopy.Spec = required.Spec - if klog.V(2).Enabled() { klog.Infof("NetworkPolicy %q changes: %v", required.Name, JSONPatchNoError(existing, existingCopy)) } actual, err := client.NetworkPolicies(existingCopy.Namespace).Update(ctx, existingCopy, metav1.UpdateOptions{}) resourcehelper.ReportUpdateEvent(recorder, required, err) - cache.UpdateCachedResourceMetadata(required, actual) return actual, true, err } diff --git a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/storage.go b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/storage.go index afbdc53ee989..d44a5d571ac2 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/storage.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/storage.go @@ -135,10 +135,9 @@ func storageClassNeedsRecreate(oldSC, newSC *storagev1.StorageClass) bool { return false } -// ApplyCSIDriver merges objectmeta and tries to update spec if any of the required fields were cleared by the API server. -// It assumes they were cleared due to a feature gate not enabled in the API server and it will be enabled soon. -// When used by StaticResourceController, it will retry periodically and eventually save the spec with the field. +// ApplyCSIDriver merges objectmeta, does not worry about anything else func ApplyCSIDriver(ctx context.Context, client storageclientv1.CSIDriversGetter, recorder events.Recorder, requiredOriginal *storagev1.CSIDriver) (*storagev1.CSIDriver, bool, error) { + required := requiredOriginal.DeepCopy() if required.Annotations == nil { required.Annotations = map[string]string{} @@ -174,40 +173,14 @@ func ApplyCSIDriver(ctx context.Context, client storageclientv1.CSIDriversGetter } } - needsUpdate := false - // Most CSIDriver fields are immutable. Any change to them should trigger Delete() + Create() calls. - needsRecreate := false - + metadataModified := false existingCopy := existing.DeepCopy() - // Metadata change should need just Update() call. - resourcemerge.EnsureObjectMeta(&needsUpdate, &existingCopy.ObjectMeta, required.ObjectMeta) + resourcemerge.EnsureObjectMeta(&metadataModified, &existingCopy.ObjectMeta, required.ObjectMeta) requiredSpecHash := required.Annotations[specHashAnnotation] existingSpecHash := existing.Annotations[specHashAnnotation] - // Assume whole re-create is needed on any spec change. - // We don't keep a track of which field is mutable. - needsRecreate = requiredSpecHash != existingSpecHash - - // TODO: remove when CSIDriver spec.nodeAllocatableUpdatePeriodSeconds is enabled by default - // (https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/4876-mutable-csinode-allocatable) - if !needsRecreate && !alphaFieldsSaved(existingCopy, required) { - // The required spec is the same as in previous succesful call, however, - // the API server must have cleared some alpha/beta fields in it. - // Try to save the object again. In case the fields are cleared again, - // the caller (typically StaticResourceController) must retry periodically. - klog.V(4).Infof("Detected CSIDriver %q field cleared by the API server, updating", required.Name) - - // Assumption: the alpha fields are **mutable**, so only Update() is needed. - // Update() with the same spec as before + the field cleared by the API server - // won't generate any informer events. StaticResourceController will retry with - // periodic retry (1 minute.) - // We cannot use needsRecreate=true, as it will generate informer events and - // StaticResourceController will retry immediately, leading to a busy loop. - needsUpdate = true - existingCopy.Spec = required.Spec - } - - if !needsUpdate && !needsRecreate { + sameSpec := requiredSpecHash == existingSpecHash + if sameSpec && !metadataModified { return existing, false, nil } @@ -215,16 +188,16 @@ func ApplyCSIDriver(ctx context.Context, client storageclientv1.CSIDriversGetter klog.Infof("CSIDriver %q changes: %v", required.Name, JSONPatchNoError(existing, existingCopy)) } - if !needsRecreate { - // only needsUpdate is true, update the object by a simple Update call + if sameSpec { + // Update metadata by a simple Update call actual, err := client.CSIDrivers().Update(ctx, existingCopy, metav1.UpdateOptions{}) resourcehelper.ReportUpdateEvent(recorder, required, err) return actual, true, err } - // needsRecreate is true, needsUpdate does not matter. Delete and re-create the object. existingCopy.Spec = required.Spec existingCopy.ObjectMeta.ResourceVersion = "" + // Spec is read-only after creation. Delete and re-create the object err = client.CSIDrivers().Delete(ctx, existingCopy.Name, metav1.DeleteOptions{}) resourcehelper.ReportDeleteEvent(recorder, existingCopy, err, "Deleting CSIDriver to re-create it with updated parameters") if err != nil && !apierrors.IsNotFound(err) { @@ -241,17 +214,10 @@ func ApplyCSIDriver(ctx context.Context, client storageclientv1.CSIDriversGetter } else if err != nil { err = fmt.Errorf("failed to re-create CSIDriver %s: %s", existingCopy.Name, err) } - resourcehelper.ReportCreateEvent(recorder, actual, err) + resourcehelper.ReportCreateEvent(recorder, existingCopy, err) return actual, true, err } -// alphaFieldsSaved checks that all required fields in the CSIDriver required spec are present and equal in the actual spec. -func alphaFieldsSaved(actual, required *storagev1.CSIDriver) bool { - // DeepDerivative checks that all fields in "required" are present and equal in "actual" - // Fields not present in "required" are ignored. - return equality.Semantic.DeepDerivative(required.Spec, actual.Spec) -} - func validateRequiredCSIDriverLabels(required *storagev1.CSIDriver) error { supportsEphemeralVolumes := false for _, mode := range required.Spec.VolumeLifecycleModes { diff --git a/vendor/golang.org/x/crypto/argon2/argon2.go b/vendor/golang.org/x/crypto/argon2/argon2.go index 2b65ec91ac39..29f0a2de4514 100644 --- a/vendor/golang.org/x/crypto/argon2/argon2.go +++ b/vendor/golang.org/x/crypto/argon2/argon2.go @@ -6,7 +6,7 @@ // Argon2 was selected as the winner of the Password Hashing Competition and can // be used to derive cryptographic keys from passwords. // -// For a detailed specification of Argon2 see [argon2-specs.pdf]. +// For a detailed specification of Argon2 see [1]. // // If you aren't sure which function you need, use Argon2id (IDKey) and // the parameter recommendations for your scenario. @@ -17,7 +17,7 @@ // It uses data-independent memory access, which is preferred for password // hashing and password-based key derivation. Argon2i requires more passes over // memory than Argon2id to protect from trade-off attacks. The recommended -// parameters (taken from [RFC 9106 Section 7.3]) for non-interactive operations are time=3 and to +// parameters (taken from [2]) for non-interactive operations are time=3 and to // use the maximum available memory. // // # Argon2id @@ -27,11 +27,11 @@ // half of the first iteration over the memory and data-dependent memory access // for the rest. Argon2id is side-channel resistant and provides better brute- // force cost savings due to time-memory tradeoffs than Argon2i. The recommended -// parameters for non-interactive operations (taken from [RFC 9106 Section 7.3]) are time=1 and to +// parameters for non-interactive operations (taken from [2]) are time=1 and to // use the maximum available memory. // -// [argon2-specs.pdf]: https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf -// [RFC 9106 Section 7.3]: https://www.rfc-editor.org/rfc/rfc9106.html#section-7.3 +// [1] https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf +// [2] https://tools.ietf.org/html/draft-irtf-cfrg-argon2-03#section-9.3 package argon2 import ( @@ -59,7 +59,7 @@ const ( // // key := argon2.Key([]byte("some password"), salt, 3, 32*1024, 4, 32) // -// [RFC 9106 Section 7.3] recommends time=3, and memory=32*1024 as a sensible number. +// The draft RFC recommends[2] time=3, and memory=32*1024 is a sensible number. // If using that amount of memory (32 MB) is not possible in some contexts then // the time parameter can be increased to compensate. // @@ -69,8 +69,6 @@ const ( // adjusted to the number of available CPUs. The cost parameters should be // increased as memory latency and CPU parallelism increases. Remember to get a // good random salt. -// -// [RFC 9106 Section 7.3]: https://www.rfc-editor.org/rfc/rfc9106.html#section-7.3 func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte { return deriveKey(argon2i, password, salt, nil, nil, time, memory, threads, keyLen) } @@ -85,7 +83,7 @@ func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint3 // // key := argon2.IDKey([]byte("some password"), salt, 1, 64*1024, 4, 32) // -// [RFC 9106 Section 7.3] recommends time=1, and memory=64*1024 as a sensible number. +// The draft RFC recommends[2] time=1, and memory=64*1024 is a sensible number. // If using that amount of memory (64 MB) is not possible in some contexts then // the time parameter can be increased to compensate. // @@ -95,8 +93,6 @@ func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint3 // adjusted to the numbers of available CPUs. The cost parameters should be // increased as memory latency and CPU parallelism increases. Remember to get a // good random salt. -// -// [RFC 9106 Section 7.3]: https://www.rfc-editor.org/rfc/rfc9106.html#section-7.3 func IDKey(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte { return deriveKey(argon2id, password, salt, nil, nil, time, memory, threads, keyLen) } diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s index 769af387e2e5..7dd2638e88ad 100644 --- a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s +++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s @@ -29,7 +29,7 @@ loop: MOVD $NUM_ROUNDS, R21 VLD1 (R11), [V30.S4, V31.S4] - // load constants + // load contants // VLD4R (R10), [V0.S4, V1.S4, V2.S4, V3.S4] WORD $0x4D60E940 diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go index b850e772e165..50695a14f62d 100644 --- a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go +++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go @@ -56,10 +56,7 @@ func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) [] ret, out := sliceForAppend(dst, len(plaintext)+16) if alias.InexactOverlap(out, plaintext) { - panic("chacha20poly1305: invalid buffer overlap of output and input") - } - if alias.AnyOverlap(out, additionalData) { - panic("chacha20poly1305: invalid buffer overlap of output and additional data") + panic("chacha20poly1305: invalid buffer overlap") } chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData) return ret @@ -76,10 +73,7 @@ func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ( ciphertext = ciphertext[:len(ciphertext)-16] ret, out := sliceForAppend(dst, len(ciphertext)) if alias.InexactOverlap(out, ciphertext) { - panic("chacha20poly1305: invalid buffer overlap of output and input") - } - if alias.AnyOverlap(out, additionalData) { - panic("chacha20poly1305: invalid buffer overlap of output and additional data") + panic("chacha20poly1305: invalid buffer overlap") } if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) { for i := range out { diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go index 2ecc840fca2c..6313898f0a75 100644 --- a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go +++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go @@ -31,10 +31,7 @@ func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []b ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize) ciphertext, tag := out[:len(plaintext)], out[len(plaintext):] if alias.InexactOverlap(out, plaintext) { - panic("chacha20poly1305: invalid buffer overlap of output and input") - } - if alias.AnyOverlap(out, additionalData) { - panic("chacha20poly1305: invalid buffer overlap of output and additional data") + panic("chacha20poly1305: invalid buffer overlap") } var polyKey [32]byte @@ -70,10 +67,7 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData [] ret, out := sliceForAppend(dst, len(ciphertext)) if alias.InexactOverlap(out, ciphertext) { - panic("chacha20poly1305: invalid buffer overlap of output and input") - } - if alias.AnyOverlap(out, additionalData) { - panic("chacha20poly1305: invalid buffer overlap of output and additional data") + panic("chacha20poly1305: invalid buffer overlap") } if !p.Verify(tag) { for i := range out { diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go index 048faef3a5dc..8ff087df4cc8 100644 --- a/vendor/golang.org/x/crypto/curve25519/curve25519.go +++ b/vendor/golang.org/x/crypto/curve25519/curve25519.go @@ -3,14 +3,11 @@ // license that can be found in the LICENSE file. // Package curve25519 provides an implementation of the X25519 function, which -// performs scalar multiplication on the elliptic curve known as Curve25519 -// according to [RFC 7748]. +// performs scalar multiplication on the elliptic curve known as Curve25519. +// See RFC 7748. // -// The curve25519 package is a wrapper for the X25519 implementation in the -// crypto/ecdh package. It is [frozen] and is not accepting new features. -// -// [RFC 7748]: https://datatracker.ietf.org/doc/html/rfc7748 -// [frozen]: https://go.dev/wiki/Frozen +// This package is a wrapper for the X25519 implementation +// in the crypto/ecdh package. package curve25519 import "crypto/ecdh" diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go index df453dcce087..59b3a95a7d20 100644 --- a/vendor/golang.org/x/crypto/ed25519/ed25519.go +++ b/vendor/golang.org/x/crypto/ed25519/ed25519.go @@ -2,19 +2,16 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package ed25519 implements the Ed25519 signature algorithm. +// Package ed25519 implements the Ed25519 signature algorithm. See +// https://ed25519.cr.yp.to/. // // These functions are also compatible with the “Ed25519” function defined in -// [RFC 8032]. However, unlike RFC 8032's formulation, this package's private key +// RFC 8032. However, unlike RFC 8032's formulation, this package's private key // representation includes a public key suffix to make multiple signing // operations with the same key more efficient. This package refers to the RFC // 8032 private key as the “seed”. // -// The ed25519 package is a wrapper for the Ed25519 implementation in the -// crypto/ed25519 package. It is [frozen] and is not accepting new features. -// -// [RFC 8032]: https://datatracker.ietf.org/doc/html/rfc8032 -// [frozen]: https://go.dev/wiki/Frozen +// This package is a wrapper around the standard library crypto/ed25519 package. package ed25519 import ( diff --git a/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go b/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go index 490cb633ce94..fa1a91907957 100644 --- a/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go +++ b/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go @@ -53,7 +53,7 @@ func (c *Config) hash() crypto.Hash { func (c *Config) encodedCount() uint8 { if c == nil || c.S2KCount == 0 { - return 96 // The common case. Corresponding to 65536 + return 96 // The common case. Correspoding to 65536 } i := c.S2KCount diff --git a/vendor/golang.org/x/crypto/pkcs12/pkcs12.go b/vendor/golang.org/x/crypto/pkcs12/pkcs12.go index 374d9facf8b2..3a89bdb3e393 100644 --- a/vendor/golang.org/x/crypto/pkcs12/pkcs12.go +++ b/vendor/golang.org/x/crypto/pkcs12/pkcs12.go @@ -4,16 +4,12 @@ // Package pkcs12 implements some of PKCS#12. // -// This implementation is distilled from [RFC 7292] and referenced documents. -// It is intended for decoding P12/PFX-stored certificates and keys for use -// with the crypto/tls package. +// This implementation is distilled from https://tools.ietf.org/html/rfc7292 +// and referenced documents. It is intended for decoding P12/PFX-stored +// certificates and keys for use with the crypto/tls package. // -// The pkcs12 package is [frozen] and is not accepting new features. -// If it's missing functionality you need, consider an alternative like -// software.sslmate.com/src/go-pkcs12. -// -// [RFC 7292]: https://datatracker.ietf.org/doc/html/rfc7292 -// [frozen]: https://go.dev/wiki/Frozen +// This package is frozen. If it's missing functionality you need, consider +// an alternative like software.sslmate.com/src/go-pkcs12. package pkcs12 import ( diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go index 75df77406d61..3685b3445873 100644 --- a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go +++ b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go @@ -3,10 +3,6 @@ // license that can be found in the LICENSE file. // Package salsa provides low-level access to functions in the Salsa family. -// -// Deprecated: this package exposes unsafe low-level operations. New applications -// should consider using the AEAD construction in golang.org/x/crypto/chacha20poly1305 -// instead. Existing users should migrate to golang.org/x/crypto/salsa20. package salsa import "math/bits" diff --git a/vendor/golang.org/x/crypto/sha3/doc.go b/vendor/golang.org/x/crypto/sha3/doc.go new file mode 100644 index 000000000000..bbf391fe6e59 --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/doc.go @@ -0,0 +1,66 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package sha3 implements the SHA-3 fixed-output-length hash functions and +// the SHAKE variable-output-length hash functions defined by FIPS-202. +// +// All types in this package also implement [encoding.BinaryMarshaler], +// [encoding.BinaryAppender] and [encoding.BinaryUnmarshaler] to marshal and +// unmarshal the internal state of the hash. +// +// Both types of hash function use the "sponge" construction and the Keccak +// permutation. For a detailed specification see http://keccak.noekeon.org/ +// +// # Guidance +// +// If you aren't sure what function you need, use SHAKE256 with at least 64 +// bytes of output. The SHAKE instances are faster than the SHA3 instances; +// the latter have to allocate memory to conform to the hash.Hash interface. +// +// If you need a secret-key MAC (message authentication code), prepend the +// secret key to the input, hash with SHAKE256 and read at least 32 bytes of +// output. +// +// # Security strengths +// +// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security +// strength against preimage attacks of x bits. Since they only produce "x" +// bits of output, their collision-resistance is only "x/2" bits. +// +// The SHAKE-256 and -128 functions have a generic security strength of 256 and +// 128 bits against all attacks, provided that at least 2x bits of their output +// is used. Requesting more than 64 or 32 bytes of output, respectively, does +// not increase the collision-resistance of the SHAKE functions. +// +// # The sponge construction +// +// A sponge builds a pseudo-random function from a public pseudo-random +// permutation, by applying the permutation to a state of "rate + capacity" +// bytes, but hiding "capacity" of the bytes. +// +// A sponge starts out with a zero state. To hash an input using a sponge, up +// to "rate" bytes of the input are XORed into the sponge's state. The sponge +// is then "full" and the permutation is applied to "empty" it. This process is +// repeated until all the input has been "absorbed". The input is then padded. +// The digest is "squeezed" from the sponge in the same way, except that output +// is copied out instead of input being XORed in. +// +// A sponge is parameterized by its generic security strength, which is equal +// to half its capacity; capacity + rate is equal to the permutation's width. +// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means +// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2. +// +// # Recommendations +// +// The SHAKE functions are recommended for most new uses. They can produce +// output of arbitrary length. SHAKE256, with an output length of at least +// 64 bytes, provides 256-bit security against all attacks. The Keccak team +// recommends it for most applications upgrading from SHA2-512. (NIST chose a +// much stronger, but much slower, sponge instance for SHA3-512.) +// +// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions. +// They produce output of the same length, with the same security strengths +// against all attacks. This means, in particular, that SHA3-256 only has +// 128-bit collision resistance, because its output length is 32 bytes. +package sha3 diff --git a/vendor/golang.org/x/crypto/sha3/hashes.go b/vendor/golang.org/x/crypto/sha3/hashes.go index a51269d91aaa..31fffbe04408 100644 --- a/vendor/golang.org/x/crypto/sha3/hashes.go +++ b/vendor/golang.org/x/crypto/sha3/hashes.go @@ -2,94 +2,127 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package sha3 implements the SHA-3 hash algorithms and the SHAKE extendable -// output functions defined in FIPS 202. -// -// Most of this package is a wrapper around the crypto/sha3 package in the -// standard library. The only exception is the legacy Keccak hash functions. package sha3 +// This file provides functions for creating instances of the SHA-3 +// and SHAKE hash functions, as well as utility functions for hashing +// bytes. + import ( - "crypto/sha3" + "crypto" "hash" ) // New224 creates a new SHA3-224 hash. // Its generic security strength is 224 bits against preimage attacks, // and 112 bits against collision attacks. -// -// It is a wrapper for the [sha3.New224] function in the standard library. -// -//go:fix inline func New224() hash.Hash { - return sha3.New224() + return new224() } // New256 creates a new SHA3-256 hash. // Its generic security strength is 256 bits against preimage attacks, // and 128 bits against collision attacks. -// -// It is a wrapper for the [sha3.New256] function in the standard library. -// -//go:fix inline func New256() hash.Hash { - return sha3.New256() + return new256() } // New384 creates a new SHA3-384 hash. // Its generic security strength is 384 bits against preimage attacks, // and 192 bits against collision attacks. -// -// It is a wrapper for the [sha3.New384] function in the standard library. -// -//go:fix inline func New384() hash.Hash { - return sha3.New384() + return new384() } // New512 creates a new SHA3-512 hash. // Its generic security strength is 512 bits against preimage attacks, // and 256 bits against collision attacks. -// -// It is a wrapper for the [sha3.New512] function in the standard library. -// -//go:fix inline func New512() hash.Hash { - return sha3.New512() + return new512() } -// Sum224 returns the SHA3-224 digest of the data. +func init() { + crypto.RegisterHash(crypto.SHA3_224, New224) + crypto.RegisterHash(crypto.SHA3_256, New256) + crypto.RegisterHash(crypto.SHA3_384, New384) + crypto.RegisterHash(crypto.SHA3_512, New512) +} + +const ( + dsbyteSHA3 = 0b00000110 + dsbyteKeccak = 0b00000001 + dsbyteShake = 0b00011111 + dsbyteCShake = 0b00000100 + + // rateK[c] is the rate in bytes for Keccak[c] where c is the capacity in + // bits. Given the sponge size is 1600 bits, the rate is 1600 - c bits. + rateK256 = (1600 - 256) / 8 + rateK448 = (1600 - 448) / 8 + rateK512 = (1600 - 512) / 8 + rateK768 = (1600 - 768) / 8 + rateK1024 = (1600 - 1024) / 8 +) + +func new224Generic() *state { + return &state{rate: rateK448, outputLen: 28, dsbyte: dsbyteSHA3} +} + +func new256Generic() *state { + return &state{rate: rateK512, outputLen: 32, dsbyte: dsbyteSHA3} +} + +func new384Generic() *state { + return &state{rate: rateK768, outputLen: 48, dsbyte: dsbyteSHA3} +} + +func new512Generic() *state { + return &state{rate: rateK1024, outputLen: 64, dsbyte: dsbyteSHA3} +} + +// NewLegacyKeccak256 creates a new Keccak-256 hash. // -// It is a wrapper for the [sha3.Sum224] function in the standard library. +// Only use this function if you require compatibility with an existing cryptosystem +// that uses non-standard padding. All other users should use New256 instead. +func NewLegacyKeccak256() hash.Hash { + return &state{rate: rateK512, outputLen: 32, dsbyte: dsbyteKeccak} +} + +// NewLegacyKeccak512 creates a new Keccak-512 hash. // -//go:fix inline -func Sum224(data []byte) [28]byte { - return sha3.Sum224(data) +// Only use this function if you require compatibility with an existing cryptosystem +// that uses non-standard padding. All other users should use New512 instead. +func NewLegacyKeccak512() hash.Hash { + return &state{rate: rateK1024, outputLen: 64, dsbyte: dsbyteKeccak} +} + +// Sum224 returns the SHA3-224 digest of the data. +func Sum224(data []byte) (digest [28]byte) { + h := New224() + h.Write(data) + h.Sum(digest[:0]) + return } // Sum256 returns the SHA3-256 digest of the data. -// -// It is a wrapper for the [sha3.Sum256] function in the standard library. -// -//go:fix inline -func Sum256(data []byte) [32]byte { - return sha3.Sum256(data) +func Sum256(data []byte) (digest [32]byte) { + h := New256() + h.Write(data) + h.Sum(digest[:0]) + return } // Sum384 returns the SHA3-384 digest of the data. -// -// It is a wrapper for the [sha3.Sum384] function in the standard library. -// -//go:fix inline -func Sum384(data []byte) [48]byte { - return sha3.Sum384(data) +func Sum384(data []byte) (digest [48]byte) { + h := New384() + h.Write(data) + h.Sum(digest[:0]) + return } // Sum512 returns the SHA3-512 digest of the data. -// -// It is a wrapper for the [sha3.Sum512] function in the standard library. -// -//go:fix inline -func Sum512(data []byte) [64]byte { - return sha3.Sum512(data) +func Sum512(data []byte) (digest [64]byte) { + h := New512() + h.Write(data) + h.Sum(digest[:0]) + return } diff --git a/vendor/golang.org/x/crypto/sha3/hashes_noasm.go b/vendor/golang.org/x/crypto/sha3/hashes_noasm.go new file mode 100644 index 000000000000..9d85fb621446 --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/hashes_noasm.go @@ -0,0 +1,23 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !gc || purego || !s390x + +package sha3 + +func new224() *state { + return new224Generic() +} + +func new256() *state { + return new256Generic() +} + +func new384() *state { + return new384Generic() +} + +func new512() *state { + return new512Generic() +} diff --git a/vendor/golang.org/x/crypto/sha3/legacy_keccakf.go b/vendor/golang.org/x/crypto/sha3/keccakf.go similarity index 98% rename from vendor/golang.org/x/crypto/sha3/legacy_keccakf.go rename to vendor/golang.org/x/crypto/sha3/keccakf.go index 101588c16cce..ce48b1dd3edd 100644 --- a/vendor/golang.org/x/crypto/sha3/legacy_keccakf.go +++ b/vendor/golang.org/x/crypto/sha3/keccakf.go @@ -2,11 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package sha3 +//go:build !amd64 || purego || !gc -// This implementation is only used for NewLegacyKeccak256 and -// NewLegacyKeccak512, which are not implemented by crypto/sha3. -// All other functions in this package are wrappers around crypto/sha3. +package sha3 import "math/bits" diff --git a/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go new file mode 100644 index 000000000000..b908696be58f --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go @@ -0,0 +1,13 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build amd64 && !purego && gc + +package sha3 + +// This function is implemented in keccakf_amd64.s. + +//go:noescape + +func keccakF1600(a *[25]uint64) diff --git a/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s new file mode 100644 index 000000000000..99e2f16e9719 --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s @@ -0,0 +1,5419 @@ +// Code generated by command: go run keccakf_amd64_asm.go -out ../keccakf_amd64.s -pkg sha3. DO NOT EDIT. + +//go:build amd64 && !purego && gc + +// func keccakF1600(a *[25]uint64) +TEXT ·keccakF1600(SB), $200-8 + MOVQ a+0(FP), DI + + // Convert the user state into an internal state + NOTQ 8(DI) + NOTQ 16(DI) + NOTQ 64(DI) + NOTQ 96(DI) + NOTQ 136(DI) + NOTQ 160(DI) + + // Execute the KeccakF permutation + MOVQ (DI), SI + MOVQ 8(DI), BP + MOVQ 32(DI), R15 + XORQ 40(DI), SI + XORQ 48(DI), BP + XORQ 72(DI), R15 + XORQ 80(DI), SI + XORQ 88(DI), BP + XORQ 112(DI), R15 + XORQ 120(DI), SI + XORQ 128(DI), BP + XORQ 152(DI), R15 + XORQ 160(DI), SI + XORQ 168(DI), BP + MOVQ 176(DI), DX + MOVQ 184(DI), R8 + XORQ 192(DI), R15 + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000000000001, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000000008082, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x800000000000808a, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000080008000, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x000000000000808b, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000080000001, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000080008081, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000008009, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x000000000000008a, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000000000088, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000080008009, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x000000008000000a, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x000000008000808b, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x800000000000008b, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000008089, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000008003, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000008002, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000000080, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x000000000000800a, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x800000008000000a, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000080008081, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000000008080, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + MOVQ R12, BP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + XORQ R10, R15 + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + XORQ R11, R15 + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(DI), R12 + XORQ 56(DI), DX + XORQ R15, BX + XORQ 96(DI), R12 + XORQ 136(DI), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(DI), R13 + XORQ 64(DI), R8 + XORQ SI, CX + XORQ 104(DI), R13 + XORQ 144(DI), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (DI), R10 + MOVQ 48(DI), R11 + XORQ R13, R9 + MOVQ 96(DI), R12 + MOVQ 144(DI), R13 + MOVQ 192(DI), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x0000000080000001, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (SP) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(SP) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(SP) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(SP) + MOVQ R12, 8(SP) + MOVQ R12, BP + + // Result g + MOVQ 72(DI), R11 + XORQ R9, R11 + MOVQ 80(DI), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(DI), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(DI), R13 + MOVQ 176(DI), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(SP) + XORQ AX, SI + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(SP) + XORQ AX, BP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(SP) + NOTQ R14 + XORQ R10, R15 + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(SP) + + // Result k + MOVQ 8(DI), R10 + MOVQ 56(DI), R11 + MOVQ 104(DI), R12 + MOVQ 152(DI), R13 + MOVQ 160(DI), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(SP) + XORQ AX, SI + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(SP) + XORQ AX, BP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(SP) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(SP) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(SP) + XORQ R10, R15 + + // Result m + MOVQ 40(DI), R11 + XORQ BX, R11 + MOVQ 88(DI), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(DI), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(DI), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(DI), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(SP) + XORQ AX, SI + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(SP) + XORQ AX, BP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(SP) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(SP) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(SP) + XORQ R11, R15 + + // Result s + MOVQ 16(DI), R10 + MOVQ 64(DI), R11 + MOVQ 112(DI), R12 + XORQ DX, R10 + MOVQ 120(DI), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(DI), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(SP) + ROLQ $0x27, R12 + XORQ R9, R15 + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(SP) + XORQ BX, SI + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(SP) + XORQ CX, BP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(SP) + MOVQ R8, 184(SP) + + // Prepare round + MOVQ BP, BX + ROLQ $0x01, BX + MOVQ 16(SP), R12 + XORQ 56(SP), DX + XORQ R15, BX + XORQ 96(SP), R12 + XORQ 136(SP), DX + XORQ DX, R12 + MOVQ R12, CX + ROLQ $0x01, CX + MOVQ 24(SP), R13 + XORQ 64(SP), R8 + XORQ SI, CX + XORQ 104(SP), R13 + XORQ 144(SP), R8 + XORQ R8, R13 + MOVQ R13, DX + ROLQ $0x01, DX + MOVQ R15, R8 + XORQ BP, DX + ROLQ $0x01, R8 + MOVQ SI, R9 + XORQ R12, R8 + ROLQ $0x01, R9 + + // Result b + MOVQ (SP), R10 + MOVQ 48(SP), R11 + XORQ R13, R9 + MOVQ 96(SP), R12 + MOVQ 144(SP), R13 + MOVQ 192(SP), R14 + XORQ CX, R11 + ROLQ $0x2c, R11 + XORQ DX, R12 + XORQ BX, R10 + ROLQ $0x2b, R12 + MOVQ R11, SI + MOVQ $0x8000000080008008, AX + ORQ R12, SI + XORQ R10, AX + XORQ AX, SI + MOVQ SI, (DI) + XORQ R9, R14 + ROLQ $0x0e, R14 + MOVQ R10, R15 + ANDQ R11, R15 + XORQ R14, R15 + MOVQ R15, 32(DI) + XORQ R8, R13 + ROLQ $0x15, R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 16(DI) + NOTQ R12 + ORQ R10, R14 + ORQ R13, R12 + XORQ R13, R14 + XORQ R11, R12 + MOVQ R14, 24(DI) + MOVQ R12, 8(DI) + NOP + + // Result g + MOVQ 72(SP), R11 + XORQ R9, R11 + MOVQ 80(SP), R12 + ROLQ $0x14, R11 + XORQ BX, R12 + ROLQ $0x03, R12 + MOVQ 24(SP), R10 + MOVQ R11, AX + ORQ R12, AX + XORQ R8, R10 + MOVQ 128(SP), R13 + MOVQ 176(SP), R14 + ROLQ $0x1c, R10 + XORQ R10, AX + MOVQ AX, 40(DI) + NOP + XORQ CX, R13 + ROLQ $0x2d, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 48(DI) + NOP + XORQ DX, R14 + ROLQ $0x3d, R14 + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 64(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 72(DI) + NOTQ R14 + NOP + ORQ R14, R13 + XORQ R12, R13 + MOVQ R13, 56(DI) + + // Result k + MOVQ 8(SP), R10 + MOVQ 56(SP), R11 + MOVQ 104(SP), R12 + MOVQ 152(SP), R13 + MOVQ 160(SP), R14 + XORQ DX, R11 + ROLQ $0x06, R11 + XORQ R8, R12 + ROLQ $0x19, R12 + MOVQ R11, AX + ORQ R12, AX + XORQ CX, R10 + ROLQ $0x01, R10 + XORQ R10, AX + MOVQ AX, 80(DI) + NOP + XORQ R9, R13 + ROLQ $0x08, R13 + MOVQ R12, AX + ANDQ R13, AX + XORQ R11, AX + MOVQ AX, 88(DI) + NOP + XORQ BX, R14 + ROLQ $0x12, R14 + NOTQ R13 + MOVQ R13, AX + ANDQ R14, AX + XORQ R12, AX + MOVQ AX, 96(DI) + MOVQ R14, AX + ORQ R10, AX + XORQ R13, AX + MOVQ AX, 104(DI) + ANDQ R11, R10 + XORQ R14, R10 + MOVQ R10, 112(DI) + NOP + + // Result m + MOVQ 40(SP), R11 + XORQ BX, R11 + MOVQ 88(SP), R12 + ROLQ $0x24, R11 + XORQ CX, R12 + MOVQ 32(SP), R10 + ROLQ $0x0a, R12 + MOVQ R11, AX + MOVQ 136(SP), R13 + ANDQ R12, AX + XORQ R9, R10 + MOVQ 184(SP), R14 + ROLQ $0x1b, R10 + XORQ R10, AX + MOVQ AX, 120(DI) + NOP + XORQ DX, R13 + ROLQ $0x0f, R13 + MOVQ R12, AX + ORQ R13, AX + XORQ R11, AX + MOVQ AX, 128(DI) + NOP + XORQ R8, R14 + ROLQ $0x38, R14 + NOTQ R13 + MOVQ R13, AX + ORQ R14, AX + XORQ R12, AX + MOVQ AX, 136(DI) + ORQ R10, R11 + XORQ R14, R11 + MOVQ R11, 152(DI) + ANDQ R10, R14 + XORQ R13, R14 + MOVQ R14, 144(DI) + NOP + + // Result s + MOVQ 16(SP), R10 + MOVQ 64(SP), R11 + MOVQ 112(SP), R12 + XORQ DX, R10 + MOVQ 120(SP), R13 + ROLQ $0x3e, R10 + XORQ R8, R11 + MOVQ 168(SP), R14 + ROLQ $0x37, R11 + XORQ R9, R12 + MOVQ R10, R9 + XORQ CX, R14 + ROLQ $0x02, R14 + ANDQ R11, R9 + XORQ R14, R9 + MOVQ R9, 192(DI) + ROLQ $0x27, R12 + NOP + NOTQ R11 + XORQ BX, R13 + MOVQ R11, BX + ANDQ R12, BX + XORQ R10, BX + MOVQ BX, 160(DI) + NOP + ROLQ $0x29, R13 + MOVQ R12, CX + ORQ R13, CX + XORQ R11, CX + MOVQ CX, 168(DI) + NOP + MOVQ R13, DX + MOVQ R14, R8 + ANDQ R14, DX + ORQ R10, R8 + XORQ R12, DX + XORQ R13, R8 + MOVQ DX, 176(DI) + MOVQ R8, 184(DI) + + // Revert the internal state to the user state + NOTQ 8(DI) + NOTQ 16(DI) + NOTQ 64(DI) + NOTQ 96(DI) + NOTQ 136(DI) + NOTQ 160(DI) + RET diff --git a/vendor/golang.org/x/crypto/sha3/legacy_hash.go b/vendor/golang.org/x/crypto/sha3/sha3.go similarity index 83% rename from vendor/golang.org/x/crypto/sha3/legacy_hash.go rename to vendor/golang.org/x/crypto/sha3/sha3.go index b8784536e017..6658c44479b6 100644 --- a/vendor/golang.org/x/crypto/sha3/legacy_hash.go +++ b/vendor/golang.org/x/crypto/sha3/sha3.go @@ -4,46 +4,15 @@ package sha3 -// This implementation is only used for NewLegacyKeccak256 and -// NewLegacyKeccak512, which are not implemented by crypto/sha3. -// All other functions in this package are wrappers around crypto/sha3. - import ( "crypto/subtle" "encoding/binary" "errors" - "hash" "unsafe" "golang.org/x/sys/cpu" ) -const ( - dsbyteKeccak = 0b00000001 - - // rateK[c] is the rate in bytes for Keccak[c] where c is the capacity in - // bits. Given the sponge size is 1600 bits, the rate is 1600 - c bits. - rateK256 = (1600 - 256) / 8 - rateK512 = (1600 - 512) / 8 - rateK1024 = (1600 - 1024) / 8 -) - -// NewLegacyKeccak256 creates a new Keccak-256 hash. -// -// Only use this function if you require compatibility with an existing cryptosystem -// that uses non-standard padding. All other users should use New256 instead. -func NewLegacyKeccak256() hash.Hash { - return &state{rate: rateK512, outputLen: 32, dsbyte: dsbyteKeccak} -} - -// NewLegacyKeccak512 creates a new Keccak-512 hash. -// -// Only use this function if you require compatibility with an existing cryptosystem -// that uses non-standard padding. All other users should use New512 instead. -func NewLegacyKeccak512() hash.Hash { - return &state{rate: rateK1024, outputLen: 64, dsbyte: dsbyteKeccak} -} - // spongeDirection indicates the direction bytes are flowing through the sponge. type spongeDirection int @@ -204,9 +173,12 @@ func (d *state) Sum(in []byte) []byte { } const ( + magicSHA3 = "sha\x08" + magicShake = "sha\x09" + magicCShake = "sha\x0a" magicKeccak = "sha\x0b" // magic || rate || main state || n || sponge direction - marshaledSize = len(magicKeccak) + 1 + 200 + 1 + 1 + marshaledSize = len(magicSHA3) + 1 + 200 + 1 + 1 ) func (d *state) MarshalBinary() ([]byte, error) { @@ -215,6 +187,12 @@ func (d *state) MarshalBinary() ([]byte, error) { func (d *state) AppendBinary(b []byte) ([]byte, error) { switch d.dsbyte { + case dsbyteSHA3: + b = append(b, magicSHA3...) + case dsbyteShake: + b = append(b, magicShake...) + case dsbyteCShake: + b = append(b, magicCShake...) case dsbyteKeccak: b = append(b, magicKeccak...) default: @@ -232,9 +210,12 @@ func (d *state) UnmarshalBinary(b []byte) error { return errors.New("sha3: invalid hash state") } - magic := string(b[:len(magicKeccak)]) - b = b[len(magicKeccak):] + magic := string(b[:len(magicSHA3)]) + b = b[len(magicSHA3):] switch { + case magic == magicSHA3 && d.dsbyte == dsbyteSHA3: + case magic == magicShake && d.dsbyte == dsbyteShake: + case magic == magicCShake && d.dsbyte == dsbyteCShake: case magic == magicKeccak && d.dsbyte == dsbyteKeccak: default: return errors.New("sha3: invalid hash state identifier") diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go new file mode 100644 index 000000000000..00d8034ae627 --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go @@ -0,0 +1,303 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego + +package sha3 + +// This file contains code for using the 'compute intermediate +// message digest' (KIMD) and 'compute last message digest' (KLMD) +// instructions to compute SHA-3 and SHAKE hashes on IBM Z. + +import ( + "hash" + + "golang.org/x/sys/cpu" +) + +// codes represent 7-bit KIMD/KLMD function codes as defined in +// the Principles of Operation. +type code uint64 + +const ( + // function codes for KIMD/KLMD + sha3_224 code = 32 + sha3_256 = 33 + sha3_384 = 34 + sha3_512 = 35 + shake_128 = 36 + shake_256 = 37 + nopad = 0x100 +) + +// kimd is a wrapper for the 'compute intermediate message digest' instruction. +// src must be a multiple of the rate for the given function code. +// +//go:noescape +func kimd(function code, chain *[200]byte, src []byte) + +// klmd is a wrapper for the 'compute last message digest' instruction. +// src padding is handled by the instruction. +// +//go:noescape +func klmd(function code, chain *[200]byte, dst, src []byte) + +type asmState struct { + a [200]byte // 1600 bit state + buf []byte // care must be taken to ensure cap(buf) is a multiple of rate + rate int // equivalent to block size + storage [3072]byte // underlying storage for buf + outputLen int // output length for full security + function code // KIMD/KLMD function code + state spongeDirection // whether the sponge is absorbing or squeezing +} + +func newAsmState(function code) *asmState { + var s asmState + s.function = function + switch function { + case sha3_224: + s.rate = 144 + s.outputLen = 28 + case sha3_256: + s.rate = 136 + s.outputLen = 32 + case sha3_384: + s.rate = 104 + s.outputLen = 48 + case sha3_512: + s.rate = 72 + s.outputLen = 64 + case shake_128: + s.rate = 168 + s.outputLen = 32 + case shake_256: + s.rate = 136 + s.outputLen = 64 + default: + panic("sha3: unrecognized function code") + } + + // limit s.buf size to a multiple of s.rate + s.resetBuf() + return &s +} + +func (s *asmState) clone() *asmState { + c := *s + c.buf = c.storage[:len(s.buf):cap(s.buf)] + return &c +} + +// copyIntoBuf copies b into buf. It will panic if there is not enough space to +// store all of b. +func (s *asmState) copyIntoBuf(b []byte) { + bufLen := len(s.buf) + s.buf = s.buf[:len(s.buf)+len(b)] + copy(s.buf[bufLen:], b) +} + +// resetBuf points buf at storage, sets the length to 0 and sets cap to be a +// multiple of the rate. +func (s *asmState) resetBuf() { + max := (cap(s.storage) / s.rate) * s.rate + s.buf = s.storage[:0:max] +} + +// Write (via the embedded io.Writer interface) adds more data to the running hash. +// It never returns an error. +func (s *asmState) Write(b []byte) (int, error) { + if s.state != spongeAbsorbing { + panic("sha3: Write after Read") + } + length := len(b) + for len(b) > 0 { + if len(s.buf) == 0 && len(b) >= cap(s.buf) { + // Hash the data directly and push any remaining bytes + // into the buffer. + remainder := len(b) % s.rate + kimd(s.function, &s.a, b[:len(b)-remainder]) + if remainder != 0 { + s.copyIntoBuf(b[len(b)-remainder:]) + } + return length, nil + } + + if len(s.buf) == cap(s.buf) { + // flush the buffer + kimd(s.function, &s.a, s.buf) + s.buf = s.buf[:0] + } + + // copy as much as we can into the buffer + n := len(b) + if len(b) > cap(s.buf)-len(s.buf) { + n = cap(s.buf) - len(s.buf) + } + s.copyIntoBuf(b[:n]) + b = b[n:] + } + return length, nil +} + +// Read squeezes an arbitrary number of bytes from the sponge. +func (s *asmState) Read(out []byte) (n int, err error) { + // The 'compute last message digest' instruction only stores the digest + // at the first operand (dst) for SHAKE functions. + if s.function != shake_128 && s.function != shake_256 { + panic("sha3: can only call Read for SHAKE functions") + } + + n = len(out) + + // need to pad if we were absorbing + if s.state == spongeAbsorbing { + s.state = spongeSqueezing + + // write hash directly into out if possible + if len(out)%s.rate == 0 { + klmd(s.function, &s.a, out, s.buf) // len(out) may be 0 + s.buf = s.buf[:0] + return + } + + // write hash into buffer + max := cap(s.buf) + if max > len(out) { + max = (len(out)/s.rate)*s.rate + s.rate + } + klmd(s.function, &s.a, s.buf[:max], s.buf) + s.buf = s.buf[:max] + } + + for len(out) > 0 { + // flush the buffer + if len(s.buf) != 0 { + c := copy(out, s.buf) + out = out[c:] + s.buf = s.buf[c:] + continue + } + + // write hash directly into out if possible + if len(out)%s.rate == 0 { + klmd(s.function|nopad, &s.a, out, nil) + return + } + + // write hash into buffer + s.resetBuf() + if cap(s.buf) > len(out) { + s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate] + } + klmd(s.function|nopad, &s.a, s.buf, nil) + } + return +} + +// Sum appends the current hash to b and returns the resulting slice. +// It does not change the underlying hash state. +func (s *asmState) Sum(b []byte) []byte { + if s.state != spongeAbsorbing { + panic("sha3: Sum after Read") + } + + // Copy the state to preserve the original. + a := s.a + + // Hash the buffer. Note that we don't clear it because we + // aren't updating the state. + switch s.function { + case sha3_224, sha3_256, sha3_384, sha3_512: + klmd(s.function, &a, nil, s.buf) + return append(b, a[:s.outputLen]...) + case shake_128, shake_256: + d := make([]byte, s.outputLen, 64) + klmd(s.function, &a, d, s.buf) + return append(b, d[:s.outputLen]...) + default: + panic("sha3: unknown function") + } +} + +// Reset resets the Hash to its initial state. +func (s *asmState) Reset() { + for i := range s.a { + s.a[i] = 0 + } + s.resetBuf() + s.state = spongeAbsorbing +} + +// Size returns the number of bytes Sum will return. +func (s *asmState) Size() int { + return s.outputLen +} + +// BlockSize returns the hash's underlying block size. +// The Write method must be able to accept any amount +// of data, but it may operate more efficiently if all writes +// are a multiple of the block size. +func (s *asmState) BlockSize() int { + return s.rate +} + +// Clone returns a copy of the ShakeHash in its current state. +func (s *asmState) Clone() ShakeHash { + return s.clone() +} + +// new224 returns an assembly implementation of SHA3-224 if available, +// otherwise it returns a generic implementation. +func new224() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_224) + } + return new224Generic() +} + +// new256 returns an assembly implementation of SHA3-256 if available, +// otherwise it returns a generic implementation. +func new256() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_256) + } + return new256Generic() +} + +// new384 returns an assembly implementation of SHA3-384 if available, +// otherwise it returns a generic implementation. +func new384() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_384) + } + return new384Generic() +} + +// new512 returns an assembly implementation of SHA3-512 if available, +// otherwise it returns a generic implementation. +func new512() hash.Hash { + if cpu.S390X.HasSHA3 { + return newAsmState(sha3_512) + } + return new512Generic() +} + +// newShake128 returns an assembly implementation of SHAKE-128 if available, +// otherwise it returns a generic implementation. +func newShake128() ShakeHash { + if cpu.S390X.HasSHA3 { + return newAsmState(shake_128) + } + return newShake128Generic() +} + +// newShake256 returns an assembly implementation of SHAKE-256 if available, +// otherwise it returns a generic implementation. +func newShake256() ShakeHash { + if cpu.S390X.HasSHA3 { + return newAsmState(shake_256) + } + return newShake256Generic() +} diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.s b/vendor/golang.org/x/crypto/sha3/sha3_s390x.s new file mode 100644 index 000000000000..826b862c7796 --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.s @@ -0,0 +1,33 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc && !purego + +#include "textflag.h" + +// func kimd(function code, chain *[200]byte, src []byte) +TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40 + MOVD function+0(FP), R0 + MOVD chain+8(FP), R1 + LMG src+16(FP), R2, R3 // R2=base, R3=len + +continue: + WORD $0xB93E0002 // KIMD --, R2 + BVS continue // continue if interrupted + MOVD $0, R0 // reset R0 for pre-go1.8 compilers + RET + +// func klmd(function code, chain *[200]byte, dst, src []byte) +TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64 + // TODO: SHAKE support + MOVD function+0(FP), R0 + MOVD chain+8(FP), R1 + LMG dst+16(FP), R2, R3 // R2=base, R3=len + LMG src+40(FP), R4, R5 // R4=base, R5=len + +continue: + WORD $0xB93F0024 // KLMD R2, R4 + BVS continue // continue if interrupted + MOVD $0, R0 // reset R0 for pre-go1.8 compilers + RET diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go index 6f3f70c2656c..a6b3a4281f5b 100644 --- a/vendor/golang.org/x/crypto/sha3/shake.go +++ b/vendor/golang.org/x/crypto/sha3/shake.go @@ -4,10 +4,24 @@ package sha3 +// This file defines the ShakeHash interface, and provides +// functions for creating SHAKE and cSHAKE instances, as well as utility +// functions for hashing bytes to arbitrary-length output. +// +// +// SHAKE implementation is based on FIPS PUB 202 [1] +// cSHAKE implementations is based on NIST SP 800-185 [2] +// +// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf +// [2] https://doi.org/10.6028/NIST.SP.800-185 + import ( - "crypto/sha3" + "bytes" + "encoding/binary" + "errors" "hash" "io" + "math/bits" ) // ShakeHash defines the interface to hash functions that support @@ -18,7 +32,7 @@ type ShakeHash interface { hash.Hash // Read reads more output from the hash; reading affects the hash's - // state. (ShakeHash.Read is thus very different from Hash.Sum.) + // state. (ShakeHash.Read is thus very different from Hash.Sum) // It never returns an error, but subsequent calls to Write or Sum // will panic. io.Reader @@ -27,18 +41,115 @@ type ShakeHash interface { Clone() ShakeHash } +// cSHAKE specific context +type cshakeState struct { + *state // SHA-3 state context and Read/Write operations + + // initBlock is the cSHAKE specific initialization set of bytes. It is initialized + // by newCShake function and stores concatenation of N followed by S, encoded + // by the method specified in 3.3 of [1]. + // It is stored here in order for Reset() to be able to put context into + // initial state. + initBlock []byte +} + +func bytepad(data []byte, rate int) []byte { + out := make([]byte, 0, 9+len(data)+rate-1) + out = append(out, leftEncode(uint64(rate))...) + out = append(out, data...) + if padlen := rate - len(out)%rate; padlen < rate { + out = append(out, make([]byte, padlen)...) + } + return out +} + +func leftEncode(x uint64) []byte { + // Let n be the smallest positive integer for which 2^(8n) > x. + n := (bits.Len64(x) + 7) / 8 + if n == 0 { + n = 1 + } + // Return n || x with n as a byte and x an n bytes in big-endian order. + b := make([]byte, 9) + binary.BigEndian.PutUint64(b[1:], x) + b = b[9-n-1:] + b[0] = byte(n) + return b +} + +func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash { + c := cshakeState{state: &state{rate: rate, outputLen: outputLen, dsbyte: dsbyte}} + c.initBlock = make([]byte, 0, 9+len(N)+9+len(S)) // leftEncode returns max 9 bytes + c.initBlock = append(c.initBlock, leftEncode(uint64(len(N))*8)...) + c.initBlock = append(c.initBlock, N...) + c.initBlock = append(c.initBlock, leftEncode(uint64(len(S))*8)...) + c.initBlock = append(c.initBlock, S...) + c.Write(bytepad(c.initBlock, c.rate)) + return &c +} + +// Reset resets the hash to initial state. +func (c *cshakeState) Reset() { + c.state.Reset() + c.Write(bytepad(c.initBlock, c.rate)) +} + +// Clone returns copy of a cSHAKE context within its current state. +func (c *cshakeState) Clone() ShakeHash { + b := make([]byte, len(c.initBlock)) + copy(b, c.initBlock) + return &cshakeState{state: c.clone(), initBlock: b} +} + +// Clone returns copy of SHAKE context within its current state. +func (c *state) Clone() ShakeHash { + return c.clone() +} + +func (c *cshakeState) MarshalBinary() ([]byte, error) { + return c.AppendBinary(make([]byte, 0, marshaledSize+len(c.initBlock))) +} + +func (c *cshakeState) AppendBinary(b []byte) ([]byte, error) { + b, err := c.state.AppendBinary(b) + if err != nil { + return nil, err + } + b = append(b, c.initBlock...) + return b, nil +} + +func (c *cshakeState) UnmarshalBinary(b []byte) error { + if len(b) <= marshaledSize { + return errors.New("sha3: invalid hash state") + } + if err := c.state.UnmarshalBinary(b[:marshaledSize]); err != nil { + return err + } + c.initBlock = bytes.Clone(b[marshaledSize:]) + return nil +} + // NewShake128 creates a new SHAKE128 variable-output-length ShakeHash. // Its generic security strength is 128 bits against all attacks if at // least 32 bytes of its output are used. func NewShake128() ShakeHash { - return &shakeWrapper{sha3.NewSHAKE128(), 32, false, sha3.NewSHAKE128} + return newShake128() } // NewShake256 creates a new SHAKE256 variable-output-length ShakeHash. // Its generic security strength is 256 bits against all attacks if // at least 64 bytes of its output are used. func NewShake256() ShakeHash { - return &shakeWrapper{sha3.NewSHAKE256(), 64, false, sha3.NewSHAKE256} + return newShake256() +} + +func newShake128Generic() *state { + return &state{rate: rateK256, outputLen: 32, dsbyte: dsbyteShake} +} + +func newShake256Generic() *state { + return &state{rate: rateK512, outputLen: 64, dsbyte: dsbyteShake} } // NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash, @@ -48,9 +159,10 @@ func NewShake256() ShakeHash { // computations on same input with different S yield unrelated outputs. // When N and S are both empty, this is equivalent to NewShake128. func NewCShake128(N, S []byte) ShakeHash { - return &shakeWrapper{sha3.NewCSHAKE128(N, S), 32, false, func() *sha3.SHAKE { - return sha3.NewCSHAKE128(N, S) - }} + if len(N) == 0 && len(S) == 0 { + return NewShake128() + } + return newCShake(N, S, rateK256, 32, dsbyteCShake) } // NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash, @@ -60,9 +172,10 @@ func NewCShake128(N, S []byte) ShakeHash { // computations on same input with different S yield unrelated outputs. // When N and S are both empty, this is equivalent to NewShake256. func NewCShake256(N, S []byte) ShakeHash { - return &shakeWrapper{sha3.NewCSHAKE256(N, S), 64, false, func() *sha3.SHAKE { - return sha3.NewCSHAKE256(N, S) - }} + if len(N) == 0 && len(S) == 0 { + return NewShake256() + } + return newCShake(N, S, rateK512, 64, dsbyteCShake) } // ShakeSum128 writes an arbitrary-length digest of data into hash. @@ -78,42 +191,3 @@ func ShakeSum256(hash, data []byte) { h.Write(data) h.Read(hash) } - -// shakeWrapper adds the Size, Sum, and Clone methods to a sha3.SHAKE -// to implement the ShakeHash interface. -type shakeWrapper struct { - *sha3.SHAKE - outputLen int - squeezing bool - newSHAKE func() *sha3.SHAKE -} - -func (w *shakeWrapper) Read(p []byte) (n int, err error) { - w.squeezing = true - return w.SHAKE.Read(p) -} - -func (w *shakeWrapper) Clone() ShakeHash { - s := w.newSHAKE() - b, err := w.MarshalBinary() - if err != nil { - panic(err) // unreachable - } - if err := s.UnmarshalBinary(b); err != nil { - panic(err) // unreachable - } - return &shakeWrapper{s, w.outputLen, w.squeezing, w.newSHAKE} -} - -func (w *shakeWrapper) Size() int { return w.outputLen } - -func (w *shakeWrapper) Sum(b []byte) []byte { - if w.squeezing { - panic("sha3: Sum after Read") - } - out := make([]byte, w.outputLen) - // Clone the state so that we don't affect future Write calls. - s := w.Clone() - s.Read(out) - return append(b, out...) -} diff --git a/vendor/golang.org/x/crypto/sha3/shake_noasm.go b/vendor/golang.org/x/crypto/sha3/shake_noasm.go new file mode 100644 index 000000000000..4276ba4ab2c4 --- /dev/null +++ b/vendor/golang.org/x/crypto/sha3/shake_noasm.go @@ -0,0 +1,15 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !gc || purego || !s390x + +package sha3 + +func newShake128() *state { + return newShake128Generic() +} + +func newShake256() *state { + return newShake256Generic() +} diff --git a/vendor/golang.org/x/crypto/ssh/agent/client.go b/vendor/golang.org/x/crypto/ssh/agent/client.go index b357e18b0a15..37525e1a187b 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/client.go +++ b/vendor/golang.org/x/crypto/ssh/agent/client.go @@ -430,9 +430,8 @@ func (c *client) List() ([]*Key, error) { return keys, nil case *failureAgentMsg: return nil, errors.New("agent: failed to list keys") - default: - return nil, fmt.Errorf("agent: failed to list keys, unexpected message type %T", msg) } + panic("unreachable") } // Sign has the agent sign the data using a protocol 2 key as defined @@ -463,9 +462,8 @@ func (c *client) SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureFl return &sig, nil case *failureAgentMsg: return nil, errors.New("agent: failed to sign challenge") - default: - return nil, fmt.Errorf("agent: failed to sign challenge, unexpected message type %T", msg) } + panic("unreachable") } // unmarshal parses an agent message in packet, returning the parsed diff --git a/vendor/golang.org/x/crypto/ssh/agent/keyring.go b/vendor/golang.org/x/crypto/ssh/agent/keyring.go index d12987551007..c1b43610873f 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/keyring.go +++ b/vendor/golang.org/x/crypto/ssh/agent/keyring.go @@ -112,7 +112,7 @@ func (r *keyring) Unlock(passphrase []byte) error { } // expireKeysLocked removes expired keys from the keyring. If a key was added -// with a lifetimesecs constraint and seconds >= lifetimesecs seconds have +// with a lifetimesecs contraint and seconds >= lifetimesecs seconds have // elapsed, it is removed. The caller *must* be holding the keyring mutex. func (r *keyring) expireKeysLocked() { for _, k := range r.keys { diff --git a/vendor/golang.org/x/crypto/ssh/agent/server.go b/vendor/golang.org/x/crypto/ssh/agent/server.go index 4e8ff86b6192..88ce4da6c44e 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/server.go +++ b/vendor/golang.org/x/crypto/ssh/agent/server.go @@ -203,9 +203,6 @@ func parseConstraints(constraints []byte) (lifetimeSecs uint32, confirmBeforeUse for len(constraints) != 0 { switch constraints[0] { case agentConstrainLifetime: - if len(constraints) < 5 { - return 0, false, nil, io.ErrUnexpectedEOF - } lifetimeSecs = binary.BigEndian.Uint32(constraints[1:5]) constraints = constraints[5:] case agentConstrainConfirm: diff --git a/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go index 7554ed57a991..6a5b582aa91e 100644 --- a/vendor/golang.org/x/crypto/ssh/cipher.go +++ b/vendor/golang.org/x/crypto/ssh/cipher.go @@ -8,7 +8,6 @@ import ( "crypto/aes" "crypto/cipher" "crypto/des" - "crypto/fips140" "crypto/rc4" "crypto/subtle" "encoding/binary" @@ -16,7 +15,6 @@ import ( "fmt" "hash" "io" - "slices" "golang.org/x/crypto/chacha20" "golang.org/x/crypto/internal/poly1305" @@ -95,41 +93,41 @@ func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, } // cipherModes documents properties of supported ciphers. Ciphers not included -// are not supported and will not be negotiated, even if explicitly configured. -// When FIPS mode is enabled, only FIPS-approved algorithms are included. -var cipherModes = map[string]*cipherMode{} - -func init() { - cipherModes[CipherAES128CTR] = &cipherMode{16, aes.BlockSize, streamCipherMode(0, newAESCTR)} - cipherModes[CipherAES192CTR] = &cipherMode{24, aes.BlockSize, streamCipherMode(0, newAESCTR)} - cipherModes[CipherAES256CTR] = &cipherMode{32, aes.BlockSize, streamCipherMode(0, newAESCTR)} - // Use of GCM with arbitrary IVs is not allowed in FIPS 140-only mode, - // we'll wire it up to NewGCMForSSH in Go 1.26. - // - // For now it means we'll work with fips140=on but not fips140=only. - cipherModes[CipherAES128GCM] = &cipherMode{16, 12, newGCMCipher} - cipherModes[CipherAES256GCM] = &cipherMode{32, 12, newGCMCipher} - - if fips140.Enabled() { - defaultCiphers = slices.DeleteFunc(defaultCiphers, func(algo string) bool { - _, ok := cipherModes[algo] - return !ok - }) - return - } - - cipherModes[CipherChaCha20Poly1305] = &cipherMode{64, 0, newChaCha20Cipher} - // Insecure ciphers not included in the default configuration. - cipherModes[InsecureCipherRC4128] = &cipherMode{16, 0, streamCipherMode(1536, newRC4)} - cipherModes[InsecureCipherRC4256] = &cipherMode{32, 0, streamCipherMode(1536, newRC4)} - cipherModes[InsecureCipherRC4] = &cipherMode{16, 0, streamCipherMode(0, newRC4)} +// are not supported and will not be negotiated, even if explicitly requested in +// ClientConfig.Crypto.Ciphers. +var cipherModes = map[string]*cipherMode{ + // Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms + // are defined in the order specified in the RFC. + CipherAES128CTR: {16, aes.BlockSize, streamCipherMode(0, newAESCTR)}, + CipherAES192CTR: {24, aes.BlockSize, streamCipherMode(0, newAESCTR)}, + CipherAES256CTR: {32, aes.BlockSize, streamCipherMode(0, newAESCTR)}, + + // Ciphers from RFC 4345, which introduces security-improved arcfour ciphers. + // They are defined in the order specified in the RFC. + InsecureCipherRC4128: {16, 0, streamCipherMode(1536, newRC4)}, + InsecureCipherRC4256: {32, 0, streamCipherMode(1536, newRC4)}, + + // Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol. + // Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and + // RC4) has problems with weak keys, and should be used with caution." + // RFC 4345 introduces improved versions of Arcfour. + InsecureCipherRC4: {16, 0, streamCipherMode(0, newRC4)}, + + // AEAD ciphers + CipherAES128GCM: {16, 12, newGCMCipher}, + CipherAES256GCM: {32, 12, newGCMCipher}, + CipherChaCha20Poly1305: {64, 0, newChaCha20Cipher}, + // CBC mode is insecure and so is not included in the default config. // (See https://www.ieee-security.org/TC/SP2013/papers/4977a526.pdf). If absolutely // needed, it's possible to specify a custom Config to enable it. // You should expect that an active attacker can recover plaintext if // you do. - cipherModes[InsecureCipherAES128CBC] = &cipherMode{16, aes.BlockSize, newAESCBCCipher} - cipherModes[InsecureCipherTripleDESCBC] = &cipherMode{24, des.BlockSize, newTripleDESCBCCipher} + InsecureCipherAES128CBC: {16, aes.BlockSize, newAESCBCCipher}, + + // 3des-cbc is insecure and is not included in the default + // config. + InsecureCipherTripleDESCBC: {24, des.BlockSize, newTripleDESCBCCipher}, } // prefixLen is the length of the packet prefix that contains the packet length diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go index 3127e4990363..c12818fdc5c7 100644 --- a/vendor/golang.org/x/crypto/ssh/client_auth.go +++ b/vendor/golang.org/x/crypto/ssh/client_auth.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "io" - "slices" "strings" ) @@ -84,7 +83,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { // success return nil } else if ok == authFailure { - if m := auth.method(); !slices.Contains(tried, m) { + if m := auth.method(); !contains(tried, m) { tried = append(tried, m) } } @@ -98,7 +97,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { findNext: for _, a := range config.Auth { candidateMethod := a.method() - if slices.Contains(tried, candidateMethod) { + if contains(tried, candidateMethod) { continue } for _, meth := range methods { @@ -118,6 +117,15 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", tried) } +func contains(list []string, e string) bool { + for _, s := range list { + if s == e { + return true + } + } + return false +} + // An AuthMethod represents an instance of an RFC 4252 authentication method. type AuthMethod interface { // auth authenticates user over transport t. @@ -247,7 +255,7 @@ func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiA // Fallback to use if there is no "server-sig-algs" extension or a // common algorithm cannot be found. We use the public key format if the // MultiAlgorithmSigner supports it, otherwise we return an error. - if !slices.Contains(as.Algorithms(), underlyingAlgo(keyFormat)) { + if !contains(as.Algorithms(), underlyingAlgo(keyFormat)) { return "", fmt.Errorf("ssh: no common public key signature algorithm, server only supports %q for key type %q, signer only supports %v", underlyingAlgo(keyFormat), keyFormat, as.Algorithms()) } @@ -276,7 +284,7 @@ func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiA // Filter algorithms based on those supported by MultiAlgorithmSigner. var keyAlgos []string for _, algo := range algorithmsForKeyFormat(keyFormat) { - if slices.Contains(as.Algorithms(), underlyingAlgo(algo)) { + if contains(as.Algorithms(), underlyingAlgo(algo)) { keyAlgos = append(keyAlgos, algo) } } @@ -326,7 +334,7 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand // the key try to use the obtained algorithm as if "server-sig-algs" had // not been implemented if supported from the algorithm signer. if !ok && idx < origSignersLen && isRSACert(algo) && algo != CertAlgoRSAv01 { - if slices.Contains(as.Algorithms(), KeyAlgoRSA) { + if contains(as.Algorithms(), KeyAlgoRSA) { // We retry using the compat algorithm after all signers have // been tried normally. signers = append(signers, &multiAlgorithmSigner{ @@ -377,7 +385,7 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand // contain the "publickey" method, do not attempt to authenticate with any // other keys. According to RFC 4252 Section 7, the latter can occur when // additional authentication methods are required. - if success == authSuccess || !slices.Contains(methods, cb.method()) { + if success == authSuccess || !contains(methods, cb.method()) { return success, methods, err } } @@ -426,7 +434,7 @@ func confirmKeyAck(key PublicKey, c packetConn) (bool, error) { // servers send the key type instead. OpenSSH allows any algorithm // that matches the public key, so we do the same. // https://github.com/openssh/openssh-portable/blob/86bdd385/sshconnect2.c#L709 - if !slices.Contains(algorithmsForKeyFormat(key.Type()), msg.Algo) { + if !contains(algorithmsForKeyFormat(key.Type()), msg.Algo) { return false, nil } if !bytes.Equal(msg.PubKey, pubKey) { diff --git a/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go index 2e44e9c9ec62..8bfad16c413b 100644 --- a/vendor/golang.org/x/crypto/ssh/common.go +++ b/vendor/golang.org/x/crypto/ssh/common.go @@ -6,7 +6,6 @@ package ssh import ( "crypto" - "crypto/fips140" "crypto/rand" "fmt" "io" @@ -257,40 +256,6 @@ type Algorithms struct { PublicKeyAuths []string } -func init() { - if fips140.Enabled() { - defaultHostKeyAlgos = slices.DeleteFunc(defaultHostKeyAlgos, func(algo string) bool { - _, err := hashFunc(underlyingAlgo(algo)) - return err != nil - }) - defaultPubKeyAuthAlgos = slices.DeleteFunc(defaultPubKeyAuthAlgos, func(algo string) bool { - _, err := hashFunc(underlyingAlgo(algo)) - return err != nil - }) - } -} - -func hashFunc(format string) (crypto.Hash, error) { - switch format { - case KeyAlgoRSASHA256, KeyAlgoECDSA256, KeyAlgoSKED25519, KeyAlgoSKECDSA256: - return crypto.SHA256, nil - case KeyAlgoECDSA384: - return crypto.SHA384, nil - case KeyAlgoRSASHA512, KeyAlgoECDSA521: - return crypto.SHA512, nil - case KeyAlgoED25519: - // KeyAlgoED25519 doesn't pre-hash. - return 0, nil - case KeyAlgoRSA, InsecureKeyAlgoDSA: - if fips140.Enabled() { - return 0, fmt.Errorf("ssh: hash algorithm for format %q not allowed in FIPS 140 mode", format) - } - return crypto.SHA1, nil - default: - return 0, fmt.Errorf("ssh: hash algorithm for format %q not mapped", format) - } -} - // SupportedAlgorithms returns algorithms currently implemented by this package, // excluding those with security issues, which are returned by // InsecureAlgorithms. The algorithms listed here are in preference order. @@ -318,6 +283,21 @@ func InsecureAlgorithms() Algorithms { var supportedCompressions = []string{compressionNone} +// hashFuncs keeps the mapping of supported signature algorithms to their +// respective hashes needed for signing and verification. +var hashFuncs = map[string]crypto.Hash{ + KeyAlgoRSA: crypto.SHA1, + KeyAlgoRSASHA256: crypto.SHA256, + KeyAlgoRSASHA512: crypto.SHA512, + InsecureKeyAlgoDSA: crypto.SHA1, + KeyAlgoECDSA256: crypto.SHA256, + KeyAlgoECDSA384: crypto.SHA384, + KeyAlgoECDSA521: crypto.SHA512, + // KeyAlgoED25519 doesn't pre-hash. + KeyAlgoSKECDSA256: crypto.SHA256, + KeyAlgoSKED25519: crypto.SHA256, +} + // algorithmsForKeyFormat returns the supported signature algorithms for a given // public key format (PublicKey.Type), in order of preference. See RFC 8332, // Section 2. See also the note in sendKexInit on backwards compatibility. @@ -332,40 +312,11 @@ func algorithmsForKeyFormat(keyFormat string) []string { } } -// keyFormatForAlgorithm returns the key format corresponding to the given -// signature algorithm. It returns an empty string if the signature algorithm is -// invalid or unsupported. -func keyFormatForAlgorithm(sigAlgo string) string { - switch sigAlgo { - case KeyAlgoRSA, KeyAlgoRSASHA256, KeyAlgoRSASHA512: - return KeyAlgoRSA - case CertAlgoRSAv01, CertAlgoRSASHA256v01, CertAlgoRSASHA512v01: - return CertAlgoRSAv01 - case KeyAlgoED25519, - KeyAlgoSKED25519, - KeyAlgoSKECDSA256, - KeyAlgoECDSA256, - KeyAlgoECDSA384, - KeyAlgoECDSA521, - InsecureKeyAlgoDSA, - InsecureCertAlgoDSAv01, - CertAlgoECDSA256v01, - CertAlgoECDSA384v01, - CertAlgoECDSA521v01, - CertAlgoSKECDSA256v01, - CertAlgoED25519v01, - CertAlgoSKED25519v01: - return sigAlgo - default: - return "" - } -} - // isRSA returns whether algo is a supported RSA algorithm, including certificate // algorithms. func isRSA(algo string) bool { algos := algorithmsForKeyFormat(KeyAlgoRSA) - return slices.Contains(algos, underlyingAlgo(algo)) + return contains(algos, underlyingAlgo(algo)) } func isRSACert(algo string) bool { @@ -564,7 +515,7 @@ func (c *Config) SetDefaults() { if kexAlgoMap[k] != nil { // Ignore the KEX if we have no kexAlgoMap definition. kexs = append(kexs, k) - if k == KeyExchangeCurve25519 && !slices.Contains(c.KeyExchanges, keyExchangeCurve25519LibSSH) { + if k == KeyExchangeCurve25519 && !contains(c.KeyExchanges, keyExchangeCurve25519LibSSH) { kexs = append(kexs, keyExchangeCurve25519LibSSH) } } diff --git a/vendor/golang.org/x/crypto/ssh/doc.go b/vendor/golang.org/x/crypto/ssh/doc.go index 5b4de9effcb1..04ccce346176 100644 --- a/vendor/golang.org/x/crypto/ssh/doc.go +++ b/vendor/golang.org/x/crypto/ssh/doc.go @@ -17,18 +17,8 @@ References: [PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD [SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1 [SSH-CERTS]: https://datatracker.ietf.org/doc/html/draft-miller-ssh-cert-01 - [FIPS 140-3 mode]: https://go.dev/doc/security/fips140 This package does not fall under the stability promise of the Go language itself, so its API may be changed when pressing needs arise. - -# FIPS 140-3 mode - -When the program is in [FIPS 140-3 mode], this package behaves as if only SP -800-140C and SP 800-140D approved cipher suites, signature algorithms, -certificate public key types and sizes, and key exchange and derivation -algorithms were implemented. Others are silently ignored and not negotiated, or -rejected. This set may depend on the algorithms supported by the FIPS 140-3 Go -Cryptographic Module selected with GOFIPS140, and may change across Go versions. */ package ssh diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go index 4be3cbb6de31..a90bfe331c8c 100644 --- a/vendor/golang.org/x/crypto/ssh/handshake.go +++ b/vendor/golang.org/x/crypto/ssh/handshake.go @@ -10,7 +10,6 @@ import ( "io" "log" "net" - "slices" "strings" "sync" ) @@ -528,7 +527,7 @@ func (t *handshakeTransport) sendKexInit() error { switch s := k.(type) { case MultiAlgorithmSigner: for _, algo := range algorithmsForKeyFormat(keyFormat) { - if slices.Contains(s.Algorithms(), underlyingAlgo(algo)) { + if contains(s.Algorithms(), underlyingAlgo(algo)) { msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo) } } @@ -680,7 +679,7 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { return err } - if t.sessionID == nil && ((isClient && slices.Contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && slices.Contains(clientInit.KexAlgos, kexStrictClient))) { + if t.sessionID == nil && ((isClient && contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && contains(clientInit.KexAlgos, kexStrictClient))) { t.strictMode = true if err := t.conn.setStrictMode(); err != nil { return err @@ -737,7 +736,7 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { // On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO // message with the server-sig-algs extension if the client supports it. See // RFC 8308, Sections 2.4 and 3.1, and [PROTOCOL], Section 1.9. - if !isClient && firstKeyExchange && slices.Contains(clientInit.KexAlgos, "ext-info-c") { + if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") { supportedPubKeyAuthAlgosList := strings.Join(t.publicKeyAuthAlgorithms, ",") extInfo := &extInfoMsg{ NumExtensions: 2, @@ -791,7 +790,7 @@ func (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, a func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner { for _, k := range hostKeys { if s, ok := k.(MultiAlgorithmSigner); ok { - if !slices.Contains(s.Algorithms(), underlyingAlgo(algo)) { + if !contains(s.Algorithms(), underlyingAlgo(algo)) { continue } } diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go index 5f7fdd85142f..78aaf03103ea 100644 --- a/vendor/golang.org/x/crypto/ssh/kex.go +++ b/vendor/golang.org/x/crypto/ssh/kex.go @@ -8,14 +8,12 @@ import ( "crypto" "crypto/ecdsa" "crypto/elliptic" - "crypto/fips140" "crypto/rand" "encoding/binary" "errors" "fmt" "io" "math/big" - "slices" "golang.org/x/crypto/curve25519" ) @@ -397,27 +395,9 @@ func ecHash(curve elliptic.Curve) crypto.Hash { return crypto.SHA512 } -// kexAlgoMap defines the supported KEXs. KEXs not included are not supported -// and will not be negotiated, even if explicitly configured. When FIPS mode is -// enabled, only FIPS-approved algorithms are included. var kexAlgoMap = map[string]kexAlgorithm{} func init() { - // mlkem768x25519-sha256 we'll work with fips140=on but not fips140=only - // until Go 1.26. - kexAlgoMap[KeyExchangeMLKEM768X25519] = &mlkem768WithCurve25519sha256{} - kexAlgoMap[KeyExchangeECDHP521] = &ecdh{elliptic.P521()} - kexAlgoMap[KeyExchangeECDHP384] = &ecdh{elliptic.P384()} - kexAlgoMap[KeyExchangeECDHP256] = &ecdh{elliptic.P256()} - - if fips140.Enabled() { - defaultKexAlgos = slices.DeleteFunc(defaultKexAlgos, func(algo string) bool { - _, ok := kexAlgoMap[algo] - return !ok - }) - return - } - p, _ := new(big.Int).SetString(oakleyGroup2, 16) kexAlgoMap[InsecureKeyExchangeDH1SHA1] = &dhGroup{ g: new(big.Int).SetInt64(2), @@ -451,10 +431,14 @@ func init() { hashFunc: crypto.SHA512, } + kexAlgoMap[KeyExchangeECDHP521] = &ecdh{elliptic.P521()} + kexAlgoMap[KeyExchangeECDHP384] = &ecdh{elliptic.P384()} + kexAlgoMap[KeyExchangeECDHP256] = &ecdh{elliptic.P256()} kexAlgoMap[KeyExchangeCurve25519] = &curve25519sha256{} kexAlgoMap[keyExchangeCurve25519LibSSH] = &curve25519sha256{} kexAlgoMap[InsecureKeyExchangeDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1} kexAlgoMap[KeyExchangeDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256} + kexAlgoMap[KeyExchangeMLKEM768X25519] = &mlkem768WithCurve25519sha256{} } // curve25519sha256 implements the curve25519-sha256 (formerly known as diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go index 47a07539d90c..a28c0de50332 100644 --- a/vendor/golang.org/x/crypto/ssh/keys.go +++ b/vendor/golang.org/x/crypto/ssh/keys.go @@ -27,7 +27,6 @@ import ( "fmt" "io" "math/big" - "slices" "strings" "golang.org/x/crypto/ssh/internal/bcrypt_pbkdf" @@ -90,11 +89,6 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err } return cert, nil, nil } - if keyFormat := keyFormatForAlgorithm(algo); keyFormat != "" { - return nil, nil, fmt.Errorf("ssh: signature algorithm %q isn't a key format; key is malformed and should be re-encoded with type %q", - algo, keyFormat) - } - return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", algo) } @@ -197,10 +191,9 @@ func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey return "", nil, nil, "", nil, io.EOF } -// ParseAuthorizedKey parses a public key from an authorized_keys file used in -// OpenSSH according to the sshd(8) manual page. Invalid lines are ignored. +// ParseAuthorizedKey parses a public key from an authorized_keys +// file used in OpenSSH according to the sshd(8) manual page. func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) { - var lastErr error for len(in) > 0 { end := bytes.IndexByte(in, '\n') if end != -1 { @@ -229,8 +222,6 @@ func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []str if out, comment, err = parseAuthorizedKey(in[i:]); err == nil { return out, comment, options, rest, nil - } else { - lastErr = err } // No key type recognised. Maybe there's an options field at @@ -273,18 +264,12 @@ func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []str if out, comment, err = parseAuthorizedKey(in[i:]); err == nil { options = candidateOptions return out, comment, options, rest, nil - } else { - lastErr = err } in = rest continue } - if lastErr != nil { - return nil, "", nil, nil, fmt.Errorf("ssh: no key found; last parsing error for ignored line: %w", lastErr) - } - return nil, "", nil, nil, errors.New("ssh: no key found") } @@ -410,11 +395,11 @@ func NewSignerWithAlgorithms(signer AlgorithmSigner, algorithms []string) (Multi } for _, algo := range algorithms { - if !slices.Contains(supportedAlgos, algo) { + if !contains(supportedAlgos, algo) { return nil, fmt.Errorf("ssh: algorithm %q is not supported for key type %q", algo, signer.PublicKey().Type()) } - if !slices.Contains(signerAlgos, algo) { + if !contains(signerAlgos, algo) { return nil, fmt.Errorf("ssh: algorithm %q is restricted for the provided signer", algo) } } @@ -501,13 +486,10 @@ func (r *rsaPublicKey) Marshal() []byte { func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error { supportedAlgos := algorithmsForKeyFormat(r.Type()) - if !slices.Contains(supportedAlgos, sig.Format) { + if !contains(supportedAlgos, sig.Format) { return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type()) } - hash, err := hashFunc(sig.Format) - if err != nil { - return err - } + hash := hashFuncs[sig.Format] h := hash.New() h.Write(data) digest := h.Sum(nil) @@ -624,11 +606,7 @@ func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error { if sig.Format != k.Type() { return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type()) } - hash, err := hashFunc(sig.Format) - if err != nil { - return err - } - h := hash.New() + h := hashFuncs[sig.Format].New() h.Write(data) digest := h.Sum(nil) @@ -673,11 +651,7 @@ func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm) } - hash, err := hashFunc(k.PublicKey().Type()) - if err != nil { - return nil, err - } - h := hash.New() + h := hashFuncs[k.PublicKey().Type()].New() h.Write(data) digest := h.Sum(nil) r, s, err := dsa.Sign(rand, k.PrivateKey, digest) @@ -827,11 +801,8 @@ func (k *ecdsaPublicKey) Verify(data []byte, sig *Signature) error { if sig.Format != k.Type() { return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type()) } - hash, err := hashFunc(sig.Format) - if err != nil { - return err - } - h := hash.New() + + h := hashFuncs[sig.Format].New() h.Write(data) digest := h.Sum(nil) @@ -934,11 +905,8 @@ func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error { if sig.Format != k.Type() { return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type()) } - hash, err := hashFunc(sig.Format) - if err != nil { - return err - } - h := hash.New() + + h := hashFuncs[sig.Format].New() h.Write([]byte(k.application)) appDigest := h.Sum(nil) @@ -1041,11 +1009,7 @@ func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error { return fmt.Errorf("invalid size %d for Ed25519 public key", l) } - hash, err := hashFunc(sig.Format) - if err != nil { - return err - } - h := hash.New() + h := hashFuncs[sig.Format].New() h.Write([]byte(k.application)) appDigest := h.Sum(nil) @@ -1148,14 +1112,11 @@ func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm algorithm = s.pubKey.Type() } - if !slices.Contains(s.Algorithms(), algorithm) { + if !contains(s.Algorithms(), algorithm) { return nil, fmt.Errorf("ssh: unsupported signature algorithm %q for key format %q", algorithm, s.pubKey.Type()) } - hashFunc, err := hashFunc(algorithm) - if err != nil { - return nil, err - } + hashFunc := hashFuncs[algorithm] var digest []byte if hashFunc != 0 { h := hashFunc.New() @@ -1490,7 +1451,6 @@ type openSSHEncryptedPrivateKey struct { NumKeys uint32 PubKey []byte PrivKeyBlock []byte - Rest []byte `ssh:"rest"` } type openSSHPrivateKey struct { diff --git a/vendor/golang.org/x/crypto/ssh/mac.go b/vendor/golang.org/x/crypto/ssh/mac.go index 87d626fbbf7c..de2639d57f87 100644 --- a/vendor/golang.org/x/crypto/ssh/mac.go +++ b/vendor/golang.org/x/crypto/ssh/mac.go @@ -7,13 +7,11 @@ package ssh // Message authentication support import ( - "crypto/fips140" "crypto/hmac" "crypto/sha1" "crypto/sha256" "crypto/sha512" "hash" - "slices" ) type macMode struct { @@ -48,37 +46,23 @@ func (t truncatingMAC) Size() int { func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() } -// macModes defines the supported MACs. MACs not included are not supported -// and will not be negotiated, even if explicitly configured. When FIPS mode is -// enabled, only FIPS-approved algorithms are included. -var macModes = map[string]*macMode{} - -func init() { - macModes[HMACSHA512ETM] = &macMode{64, true, func(key []byte) hash.Hash { +var macModes = map[string]*macMode{ + HMACSHA512ETM: {64, true, func(key []byte) hash.Hash { return hmac.New(sha512.New, key) - }} - macModes[HMACSHA256ETM] = &macMode{32, true, func(key []byte) hash.Hash { + }}, + HMACSHA256ETM: {32, true, func(key []byte) hash.Hash { return hmac.New(sha256.New, key) - }} - macModes[HMACSHA512] = &macMode{64, false, func(key []byte) hash.Hash { + }}, + HMACSHA512: {64, false, func(key []byte) hash.Hash { return hmac.New(sha512.New, key) - }} - macModes[HMACSHA256] = &macMode{32, false, func(key []byte) hash.Hash { + }}, + HMACSHA256: {32, false, func(key []byte) hash.Hash { return hmac.New(sha256.New, key) - }} - - if fips140.Enabled() { - defaultMACs = slices.DeleteFunc(defaultMACs, func(algo string) bool { - _, ok := macModes[algo] - return !ok - }) - return - } - - macModes[HMACSHA1] = &macMode{20, false, func(key []byte) hash.Hash { + }}, + HMACSHA1: {20, false, func(key []byte) hash.Hash { return hmac.New(sha1.New, key) - }} - macModes[InsecureHMACSHA196] = &macMode{20, false, func(key []byte) hash.Hash { + }}, + InsecureHMACSHA196: {20, false, func(key []byte) hash.Hash { return truncatingMAC{12, hmac.New(sha1.New, key)} - }} + }}, } diff --git a/vendor/golang.org/x/crypto/ssh/messages.go b/vendor/golang.org/x/crypto/ssh/messages.go index ab22c3d38db8..251b9d06a324 100644 --- a/vendor/golang.org/x/crypto/ssh/messages.go +++ b/vendor/golang.org/x/crypto/ssh/messages.go @@ -792,7 +792,7 @@ func marshalString(to []byte, s []byte) []byte { return to[len(s):] } -var bigIntType = reflect.TypeFor[*big.Int]() +var bigIntType = reflect.TypeOf((*big.Int)(nil)) // Decode a packet into its corresponding message. func decode(packet []byte) (interface{}, error) { diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go index 064dcbaf5aef..98679ba5b6ed 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go @@ -10,7 +10,6 @@ import ( "fmt" "io" "net" - "slices" "strings" ) @@ -44,9 +43,6 @@ type Permissions struct { // pass data from the authentication callbacks to the server // application layer. Extensions map[string]string - - // ExtraData allows to store user defined data. - ExtraData map[any]any } type GSSAPIWithMICConfig struct { @@ -130,21 +126,6 @@ type ServerConfig struct { // Permissions.Extensions entry. PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error) - // VerifiedPublicKeyCallback, if non-nil, is called after a client - // successfully confirms having control over a key that was previously - // approved by PublicKeyCallback. The permissions object passed to the - // callback is the one returned by PublicKeyCallback for the given public - // key and its ownership is transferred to the callback. The returned - // Permissions object can be the same object, optionally modified, or a - // completely new object. If VerifiedPublicKeyCallback is non-nil, - // PublicKeyCallback is not allowed to return a PartialSuccessError, which - // can instead be returned by VerifiedPublicKeyCallback. - // - // VerifiedPublicKeyCallback does not affect which authentication methods - // are included in the list of methods that can be attempted by the client. - VerifiedPublicKeyCallback func(conn ConnMetadata, key PublicKey, permissions *Permissions, - signatureAlgorithm string) (*Permissions, error) - // KeyboardInteractiveCallback, if non-nil, is called when // keyboard-interactive authentication is selected (RFC // 4256). The client object's Challenge function should be @@ -265,7 +246,7 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha fullConf.PublicKeyAuthAlgorithms = defaultPubKeyAuthAlgos } else { for _, algo := range fullConf.PublicKeyAuthAlgorithms { - if !slices.Contains(SupportedAlgorithms().PublicKeyAuths, algo) && !slices.Contains(InsecureAlgorithms().PublicKeyAuths, algo) { + if !contains(SupportedAlgorithms().PublicKeyAuths, algo) && !contains(InsecureAlgorithms().PublicKeyAuths, algo) { c.Close() return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo) } @@ -650,7 +631,7 @@ userAuthLoop: return nil, parseError(msgUserAuthRequest) } algo := string(algoBytes) - if !slices.Contains(config.PublicKeyAuthAlgorithms, underlyingAlgo(algo)) { + if !contains(config.PublicKeyAuthAlgorithms, underlyingAlgo(algo)) { authErr = fmt.Errorf("ssh: algorithm %q not accepted", algo) break } @@ -671,9 +652,6 @@ userAuthLoop: candidate.pubKeyData = pubKeyData candidate.perms, candidate.result = authConfig.PublicKeyCallback(s, pubKey) _, isPartialSuccessError := candidate.result.(*PartialSuccessError) - if isPartialSuccessError && config.VerifiedPublicKeyCallback != nil { - return nil, errors.New("ssh: invalid library usage: PublicKeyCallback must not return partial success when VerifiedPublicKeyCallback is defined") - } if (candidate.result == nil || isPartialSuccessError) && candidate.perms != nil && @@ -717,7 +695,7 @@ userAuthLoop: // ssh-rsa-cert-v01@openssh.com algorithm with ssh-rsa public // key type. The algorithm and public key type must be // consistent: both must be certificate algorithms, or neither. - if !slices.Contains(algorithmsForKeyFormat(pubKey.Type()), algo) { + if !contains(algorithmsForKeyFormat(pubKey.Type()), algo) { authErr = fmt.Errorf("ssh: public key type %q not compatible with selected algorithm %q", pubKey.Type(), algo) break @@ -727,7 +705,7 @@ userAuthLoop: // algorithm name that corresponds to algo with // sig.Format. This is usually the same, but // for certs, the names differ. - if !slices.Contains(config.PublicKeyAuthAlgorithms, sig.Format) { + if !contains(config.PublicKeyAuthAlgorithms, sig.Format) { authErr = fmt.Errorf("ssh: algorithm %q not accepted", sig.Format) break } @@ -744,12 +722,6 @@ userAuthLoop: authErr = candidate.result perms = candidate.perms - if authErr == nil && config.VerifiedPublicKeyCallback != nil { - // Only call VerifiedPublicKeyCallback after the key has been accepted - // and successfully verified. If authErr is non-nil, the key is not - // considered verified and the callback must not run. - perms, authErr = config.VerifiedPublicKeyCallback(s, pubKey, perms, algo) - } } case "gssapi-with-mic": if authConfig.GSSAPIWithMICConfig == nil { diff --git a/vendor/golang.org/x/crypto/ssh/ssh_gss.go b/vendor/golang.org/x/crypto/ssh/ssh_gss.go index a6249a1227b5..24bd7c8e8304 100644 --- a/vendor/golang.org/x/crypto/ssh/ssh_gss.go +++ b/vendor/golang.org/x/crypto/ssh/ssh_gss.go @@ -106,13 +106,6 @@ func parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) { if !ok { return nil, errors.New("parse uint32 failed") } - // Each ASN.1 encoded OID must have a minimum - // of 2 bytes; 64 maximum mechanisms is an - // arbitrary, but reasonable ceiling. - const maxMechs = 64 - if n > maxMechs || int(n)*2 > len(rest) { - return nil, errors.New("invalid mechanism count") - } s := &userAuthRequestGSSAPI{ N: n, OIDS: make([]asn1.ObjectIdentifier, n), @@ -129,6 +122,7 @@ func parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) { if rest, err = asn1.Unmarshal(desiredMech, &s.OIDS[i]); err != nil { return nil, err } + } return s, nil } diff --git a/vendor/golang.org/x/crypto/ssh/streamlocal.go b/vendor/golang.org/x/crypto/ssh/streamlocal.go index 152470fcb796..b171b330bc38 100644 --- a/vendor/golang.org/x/crypto/ssh/streamlocal.go +++ b/vendor/golang.org/x/crypto/ssh/streamlocal.go @@ -44,7 +44,7 @@ func (c *Client) ListenUnix(socketPath string) (net.Listener, error) { if !ok { return nil, errors.New("ssh: streamlocal-forward@openssh.com request denied by peer") } - ch := c.forwards.add("unix", socketPath) + ch := c.forwards.add(&net.UnixAddr{Name: socketPath, Net: "unix"}) return &unixListener{socketPath, c, ch}, nil } @@ -96,7 +96,7 @@ func (l *unixListener) Accept() (net.Conn, error) { // Close closes the listener. func (l *unixListener) Close() error { // this also closes the listener. - l.conn.forwards.remove("unix", l.socketPath) + l.conn.forwards.remove(&net.UnixAddr{Name: l.socketPath, Net: "unix"}) m := streamLocalChannelForwardMsg{ l.socketPath, } diff --git a/vendor/golang.org/x/crypto/ssh/tcpip.go b/vendor/golang.org/x/crypto/ssh/tcpip.go index 78c41fe5a126..93d844f03516 100644 --- a/vendor/golang.org/x/crypto/ssh/tcpip.go +++ b/vendor/golang.org/x/crypto/ssh/tcpip.go @@ -11,7 +11,6 @@ import ( "io" "math/rand" "net" - "net/netip" "strconv" "strings" "sync" @@ -23,21 +22,14 @@ import ( // the returned net.Listener. The listener must be serviced, or the // SSH connection may hang. // N must be "tcp", "tcp4", "tcp6", or "unix". -// -// If the address is a hostname, it is sent to the remote peer as-is, without -// being resolved locally, and the Listener Addr method will return a zero IP. func (c *Client) Listen(n, addr string) (net.Listener, error) { switch n { case "tcp", "tcp4", "tcp6": - host, portStr, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } - port, err := strconv.ParseInt(portStr, 10, 32) + laddr, err := net.ResolveTCPAddr(n, addr) if err != nil { return nil, err } - return c.listenTCPInternal(host, int(port)) + return c.ListenTCP(laddr) case "unix": return c.ListenUnix(addr) default: @@ -110,24 +102,15 @@ func (c *Client) handleForwards() { // ListenTCP requests the remote peer open a listening socket // on laddr. Incoming connections will be available by calling // Accept on the returned net.Listener. -// -// ListenTCP accepts an IP address, to provide a hostname use [Client.Listen] -// with "tcp", "tcp4", or "tcp6" network instead. func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) { c.handleForwardsOnce.Do(c.handleForwards) if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) { return c.autoPortListenWorkaround(laddr) } - return c.listenTCPInternal(laddr.IP.String(), laddr.Port) -} - -func (c *Client) listenTCPInternal(host string, port int) (net.Listener, error) { - c.handleForwardsOnce.Do(c.handleForwards) - m := channelForwardMsg{ - host, - uint32(port), + laddr.IP.String(), + uint32(laddr.Port), } // send message ok, resp, err := c.SendRequest("tcpip-forward", true, Marshal(&m)) @@ -140,33 +123,20 @@ func (c *Client) listenTCPInternal(host string, port int) (net.Listener, error) // If the original port was 0, then the remote side will // supply a real port number in the response. - if port == 0 { + if laddr.Port == 0 { var p struct { Port uint32 } if err := Unmarshal(resp, &p); err != nil { return nil, err } - port = int(p.Port) - } - // Construct a local address placeholder for the remote listener. If the - // original host is an IP address, preserve it so that Listener.Addr() - // reports the same IP. If the host is a hostname or cannot be parsed as an - // IP, fall back to IPv4zero. The port field is always set, even if the - // original port was 0, because in that case the remote server will assign - // one, allowing callers to determine which port was selected. - ip := net.IPv4zero - if parsed, err := netip.ParseAddr(host); err == nil { - ip = net.IP(parsed.AsSlice()) - } - laddr := &net.TCPAddr{ - IP: ip, - Port: port, + laddr.Port = int(p.Port) } - addr := net.JoinHostPort(host, strconv.FormatInt(int64(port), 10)) - ch := c.forwards.add("tcp", addr) - return &tcpListener{laddr, addr, c, ch}, nil + // Register this forward, using the port number we obtained. + ch := c.forwards.add(laddr) + + return &tcpListener{laddr, c, ch}, nil } // forwardList stores a mapping between remote @@ -179,9 +149,8 @@ type forwardList struct { // forwardEntry represents an established mapping of a laddr on a // remote ssh server to a channel connected to a tcpListener. type forwardEntry struct { - addr string // host:port or socket path - network string // tcp or unix - c chan forward + laddr net.Addr + c chan forward } // forward represents an incoming forwarded tcpip connection. The @@ -192,13 +161,12 @@ type forward struct { raddr net.Addr // the raddr of the incoming connection } -func (l *forwardList) add(n, addr string) chan forward { +func (l *forwardList) add(addr net.Addr) chan forward { l.Lock() defer l.Unlock() f := forwardEntry{ - addr: addr, - network: n, - c: make(chan forward, 1), + laddr: addr, + c: make(chan forward, 1), } l.entries = append(l.entries, f) return f.c @@ -217,20 +185,19 @@ func parseTCPAddr(addr string, port uint32) (*net.TCPAddr, error) { if port == 0 || port > 65535 { return nil, fmt.Errorf("ssh: port number out of range: %d", port) } - ip, err := netip.ParseAddr(addr) - if err != nil { + ip := net.ParseIP(string(addr)) + if ip == nil { return nil, fmt.Errorf("ssh: cannot parse IP address %q", addr) } - return &net.TCPAddr{IP: net.IP(ip.AsSlice()), Port: int(port)}, nil + return &net.TCPAddr{IP: ip, Port: int(port)}, nil } func (l *forwardList) handleChannels(in <-chan NewChannel) { for ch := range in { var ( - addr string - network string - raddr net.Addr - err error + laddr net.Addr + raddr net.Addr + err error ) switch channelType := ch.ChannelType(); channelType { case "forwarded-tcpip": @@ -240,34 +207,40 @@ func (l *forwardList) handleChannels(in <-chan NewChannel) { continue } - // RFC 4254 section 7.2 specifies that incoming addresses should - // list the address that was connected, in string format. It is the - // same address used in the tcpip-forward request. The originator - // address is an IP address instead. - addr = net.JoinHostPort(payload.Addr, strconv.FormatUint(uint64(payload.Port), 10)) - + // RFC 4254 section 7.2 specifies that incoming + // addresses should list the address, in string + // format. It is implied that this should be an IP + // address, as it would be impossible to connect to it + // otherwise. + laddr, err = parseTCPAddr(payload.Addr, payload.Port) + if err != nil { + ch.Reject(ConnectionFailed, err.Error()) + continue + } raddr, err = parseTCPAddr(payload.OriginAddr, payload.OriginPort) if err != nil { ch.Reject(ConnectionFailed, err.Error()) continue } - network = "tcp" + case "forwarded-streamlocal@openssh.com": var payload forwardedStreamLocalPayload if err = Unmarshal(ch.ExtraData(), &payload); err != nil { ch.Reject(ConnectionFailed, "could not parse forwarded-streamlocal@openssh.com payload: "+err.Error()) continue } - addr = payload.SocketPath + laddr = &net.UnixAddr{ + Name: payload.SocketPath, + Net: "unix", + } raddr = &net.UnixAddr{ Name: "@", Net: "unix", } - network = "unix" default: panic(fmt.Errorf("ssh: unknown channel type %s", channelType)) } - if ok := l.forward(network, addr, raddr, ch); !ok { + if ok := l.forward(laddr, raddr, ch); !ok { // Section 7.2, implementations MUST reject spurious incoming // connections. ch.Reject(Prohibited, "no forward for address") @@ -279,11 +252,11 @@ func (l *forwardList) handleChannels(in <-chan NewChannel) { // remove removes the forward entry, and the channel feeding its // listener. -func (l *forwardList) remove(n, addr string) { +func (l *forwardList) remove(addr net.Addr) { l.Lock() defer l.Unlock() for i, f := range l.entries { - if n == f.network && addr == f.addr { + if addr.Network() == f.laddr.Network() && addr.String() == f.laddr.String() { l.entries = append(l.entries[:i], l.entries[i+1:]...) close(f.c) return @@ -301,11 +274,11 @@ func (l *forwardList) closeAll() { l.entries = nil } -func (l *forwardList) forward(n, addr string, raddr net.Addr, ch NewChannel) bool { +func (l *forwardList) forward(laddr, raddr net.Addr, ch NewChannel) bool { l.Lock() defer l.Unlock() for _, f := range l.entries { - if n == f.network && addr == f.addr { + if laddr.Network() == f.laddr.Network() && laddr.String() == f.laddr.String() { f.c <- forward{newCh: ch, raddr: raddr} return true } @@ -315,7 +288,6 @@ func (l *forwardList) forward(n, addr string, raddr net.Addr, ch NewChannel) boo type tcpListener struct { laddr *net.TCPAddr - addr string conn *Client in <-chan forward @@ -342,21 +314,13 @@ func (l *tcpListener) Accept() (net.Conn, error) { // Close closes the listener. func (l *tcpListener) Close() error { - host, port, err := net.SplitHostPort(l.addr) - if err != nil { - return err - } - rport, err := strconv.ParseUint(port, 10, 32) - if err != nil { - return err - } m := channelForwardMsg{ - host, - uint32(rport), + l.laddr.IP.String(), + uint32(l.laddr.Port), } // this also closes the listener. - l.conn.forwards.remove("tcp", l.addr) + l.conn.forwards.remove(l.laddr) ok, _, err := l.conn.SendRequest("cancel-tcpip-forward", true, Marshal(&m)) if err == nil && !ok { err = errors.New("ssh: cancel-tcpip-forward failed") diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go index fa3dd6a4299b..663619845c79 100644 --- a/vendor/golang.org/x/crypto/ssh/transport.go +++ b/vendor/golang.org/x/crypto/ssh/transport.go @@ -8,7 +8,6 @@ import ( "bufio" "bytes" "errors" - "fmt" "io" "log" ) @@ -255,9 +254,6 @@ var ( // (to setup server->client keys) or clientKeys (for client->server keys). func newPacketCipher(d direction, algs DirectionAlgorithms, kex *kexResult) (packetCipher, error) { cipherMode := cipherModes[algs.Cipher] - if cipherMode == nil { - return nil, fmt.Errorf("ssh: unsupported cipher %v", algs.Cipher) - } iv := make([]byte, cipherMode.ivSize) key := make([]byte, cipherMode.keySize) diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go index 24cea6882049..db1c95fab1d5 100644 --- a/vendor/golang.org/x/net/context/context.go +++ b/vendor/golang.org/x/net/context/context.go @@ -2,9 +2,44 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package context has been superseded by the standard library [context] package. +// Package context defines the Context type, which carries deadlines, +// cancellation signals, and other request-scoped values across API boundaries +// and between processes. +// As of Go 1.7 this package is available in the standard library under the +// name [context], and migrating to it can be done automatically with [go fix]. +// +// Incoming requests to a server should create a [Context], and outgoing +// calls to servers should accept a Context. The chain of function +// calls between them must propagate the Context, optionally replacing +// it with a derived Context created using [WithCancel], [WithDeadline], +// [WithTimeout], or [WithValue]. +// +// Programs that use Contexts should follow these rules to keep interfaces +// consistent across packages and enable static analysis tools to check context +// propagation: +// +// Do not store Contexts inside a struct type; instead, pass a Context +// explicitly to each function that needs it. This is discussed further in +// https://go.dev/blog/context-and-structs. The Context should be the first +// parameter, typically named ctx: +// +// func DoSomething(ctx context.Context, arg Arg) error { +// // ... use ctx ... +// } +// +// Do not pass a nil [Context], even if a function permits it. Pass [context.TODO] +// if you are unsure about which Context to use. +// +// Use context Values only for request-scoped data that transits processes and +// APIs, not for passing optional parameters to functions. // -// Deprecated: Use the standard library context package instead. +// The same Context may be passed to functions running in different goroutines; +// Contexts are safe for simultaneous use by multiple goroutines. +// +// See https://go.dev/blog/context for example code for a server that uses +// Contexts. +// +// [go fix]: https://go.dev/cmd/go#hdr-Update_packages_to_use_new_APIs package context import ( @@ -16,37 +51,36 @@ import ( // API boundaries. // // Context's methods may be called by multiple goroutines simultaneously. -// -//go:fix inline type Context = context.Context // Canceled is the error returned by [Context.Err] when the context is canceled // for some reason other than its deadline passing. -// -//go:fix inline var Canceled = context.Canceled // DeadlineExceeded is the error returned by [Context.Err] when the context is canceled // due to its deadline passing. -// -//go:fix inline var DeadlineExceeded = context.DeadlineExceeded // Background returns a non-nil, empty Context. It is never canceled, has no // values, and has no deadline. It is typically used by the main function, // initialization, and tests, and as the top-level Context for incoming // requests. -// -//go:fix inline -func Background() Context { return context.Background() } +func Background() Context { + return background +} // TODO returns a non-nil, empty Context. Code should use context.TODO when // it's unclear which Context to use or it is not yet available (because the // surrounding function has not yet been extended to accept a Context // parameter). -// -//go:fix inline -func TODO() Context { return context.TODO() } +func TODO() Context { + return todo +} + +var ( + background = context.Background() + todo = context.TODO() +) // A CancelFunc tells an operation to abandon its work. // A CancelFunc does not wait for the work to stop. @@ -61,8 +95,6 @@ type CancelFunc = context.CancelFunc // // Canceling this context releases resources associated with it, so code should // call cancel as soon as the operations running in this [Context] complete. -// -//go:fix inline func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { return context.WithCancel(parent) } @@ -76,8 +108,6 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { // // Canceling this context releases resources associated with it, so code should // call cancel as soon as the operations running in this [Context] complete. -// -//go:fix inline func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) { return context.WithDeadline(parent, d) } @@ -92,8 +122,6 @@ func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) { // defer cancel() // releases resources if slowOperation completes before timeout elapses // return slowOperation(ctx) // } -// -//go:fix inline func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { return context.WithTimeout(parent, timeout) } @@ -111,8 +139,6 @@ func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { // interface{}, context keys often have concrete type // struct{}. Alternatively, exported context key variables' static // type should be a pointer or interface. -// -//go:fix inline func WithValue(parent Context, key, val interface{}) Context { return context.WithValue(parent, key, val) } diff --git a/vendor/golang.org/x/net/html/escape.go b/vendor/golang.org/x/net/html/escape.go index 12f227370625..04c6bec21073 100644 --- a/vendor/golang.org/x/net/html/escape.go +++ b/vendor/golang.org/x/net/html/escape.go @@ -299,7 +299,7 @@ func escape(w writer, s string) error { case '\r': esc = " " default: - panic("html: unrecognized escape character") + panic("unrecognized escape character") } s = s[i+1:] if _, err := w.WriteString(esc); err != nil { diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go index 88fc0056a347..518ee4c94e74 100644 --- a/vendor/golang.org/x/net/html/parse.go +++ b/vendor/golang.org/x/net/html/parse.go @@ -136,7 +136,7 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int { return -1 } default: - panic(fmt.Sprintf("html: internal error: indexOfElementInScope unknown scope: %d", s)) + panic("unreachable") } } switch s { @@ -179,7 +179,7 @@ func (p *parser) clearStackToContext(s scope) { return } default: - panic(fmt.Sprintf("html: internal error: clearStackToContext unknown scope: %d", s)) + panic("unreachable") } } } @@ -231,14 +231,7 @@ func (p *parser) addChild(n *Node) { } if n.Type == ElementNode { - p.insertOpenElement(n) - } -} - -func (p *parser) insertOpenElement(n *Node) { - p.oe = append(p.oe, n) - if len(p.oe) > 512 { - panic("html: open stack of elements exceeds 512 nodes") + p.oe = append(p.oe, n) } } @@ -817,7 +810,7 @@ func afterHeadIM(p *parser) bool { p.im = inFramesetIM return true case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title: - p.insertOpenElement(p.head) + p.oe = append(p.oe, p.head) defer p.oe.remove(p.head) return inHeadIM(p) case a.Head: @@ -1685,7 +1678,7 @@ func inTableBodyIM(p *parser) bool { return inTableIM(p) } -// Section 13.2.6.4.14. +// Section 12.2.6.4.14. func inRowIM(p *parser) bool { switch p.tok.Type { case StartTagToken: @@ -1697,9 +1690,7 @@ func inRowIM(p *parser) bool { p.im = inCellIM return true case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead, a.Tr: - if p.elementInScope(tableScope, a.Tr) { - p.clearStackToContext(tableRowScope) - p.oe.pop() + if p.popUntil(tableScope, a.Tr) { p.im = inTableBodyIM return false } @@ -1709,28 +1700,22 @@ func inRowIM(p *parser) bool { case EndTagToken: switch p.tok.DataAtom { case a.Tr: - if p.elementInScope(tableScope, a.Tr) { - p.clearStackToContext(tableRowScope) - p.oe.pop() + if p.popUntil(tableScope, a.Tr) { p.im = inTableBodyIM return true } // Ignore the token. return true case a.Table: - if p.elementInScope(tableScope, a.Tr) { - p.clearStackToContext(tableRowScope) - p.oe.pop() + if p.popUntil(tableScope, a.Tr) { p.im = inTableBodyIM return false } // Ignore the token. return true case a.Tbody, a.Tfoot, a.Thead: - if p.elementInScope(tableScope, p.tok.DataAtom) && p.elementInScope(tableScope, a.Tr) { - p.clearStackToContext(tableRowScope) - p.oe.pop() - p.im = inTableBodyIM + if p.elementInScope(tableScope, p.tok.DataAtom) { + p.parseImpliedToken(EndTagToken, a.Tr, a.Tr.String()) return false } // Ignore the token. @@ -2237,20 +2222,16 @@ func parseForeignContent(p *parser) bool { p.acknowledgeSelfClosingTag() } case EndTagToken: - if strings.EqualFold(p.oe[len(p.oe)-1].Data, p.tok.Data) { - p.oe = p.oe[:len(p.oe)-1] - return true - } for i := len(p.oe) - 1; i >= 0; i-- { + if p.oe[i].Namespace == "" { + return p.im(p) + } if strings.EqualFold(p.oe[i].Data, p.tok.Data) { p.oe = p.oe[:i] - return true - } - if i > 0 && p.oe[i-1].Namespace == "" { break } } - return p.im(p) + return true default: // Ignore the token. } @@ -2331,13 +2312,9 @@ func (p *parser) parseCurrentToken() { } } -func (p *parser) parse() (err error) { - defer func() { - if panicErr := recover(); panicErr != nil { - err = fmt.Errorf("%s", panicErr) - } - }() +func (p *parser) parse() error { // Iterate until EOF. Any other error will cause an early return. + var err error for err != io.EOF { // CDATA sections are allowed only in foreign content. n := p.oe.top() @@ -2366,8 +2343,6 @@ func (p *parser) parse() (err error) { // s. Conversely, explicit s in r's data can be silently dropped, // with no corresponding node in the resulting tree. // -// Parse will reject HTML that is nested deeper than 512 elements. -// // The input is assumed to be UTF-8 encoded. func Parse(r io.Reader) (*Node, error) { return ParseWithOptions(r) diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go index 0157d89e1fda..e8c12334553d 100644 --- a/vendor/golang.org/x/net/html/render.go +++ b/vendor/golang.org/x/net/html/render.go @@ -184,7 +184,7 @@ func render1(w writer, n *Node) error { return err } - // Add initial newline where there is danger of a newline being ignored. + // Add initial newline where there is danger of a newline beging ignored. if c := n.FirstChild; c != nil && c.Type == TextNode && strings.HasPrefix(c.Data, "\n") { switch n.Data { case "pre", "listing", "textarea": diff --git a/vendor/golang.org/x/net/http2/config.go b/vendor/golang.org/x/net/http2/config.go index 8a7a89d016ed..ca645d9a1aff 100644 --- a/vendor/golang.org/x/net/http2/config.go +++ b/vendor/golang.org/x/net/http2/config.go @@ -27,7 +27,6 @@ import ( // - If the resulting value is zero or out of range, use a default. type http2Config struct { MaxConcurrentStreams uint32 - StrictMaxConcurrentRequests bool MaxDecoderHeaderTableSize uint32 MaxEncoderHeaderTableSize uint32 MaxReadFrameSize uint32 @@ -56,7 +55,7 @@ func configFromServer(h1 *http.Server, h2 *Server) http2Config { PermitProhibitedCipherSuites: h2.PermitProhibitedCipherSuites, CountError: h2.CountError, } - fillNetHTTPConfig(&conf, h1.HTTP2) + fillNetHTTPServerConfig(&conf, h1) setConfigDefaults(&conf, true) return conf } @@ -65,13 +64,12 @@ func configFromServer(h1 *http.Server, h2 *Server) http2Config { // (the net/http Transport). func configFromTransport(h2 *Transport) http2Config { conf := http2Config{ - StrictMaxConcurrentRequests: h2.StrictMaxConcurrentStreams, - MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize, - MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize, - MaxReadFrameSize: h2.MaxReadFrameSize, - SendPingTimeout: h2.ReadIdleTimeout, - PingTimeout: h2.PingTimeout, - WriteByteTimeout: h2.WriteByteTimeout, + MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize, + MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize, + MaxReadFrameSize: h2.MaxReadFrameSize, + SendPingTimeout: h2.ReadIdleTimeout, + PingTimeout: h2.PingTimeout, + WriteByteTimeout: h2.WriteByteTimeout, } // Unlike most config fields, where out-of-range values revert to the default, @@ -83,7 +81,7 @@ func configFromTransport(h2 *Transport) http2Config { } if h2.t1 != nil { - fillNetHTTPConfig(&conf, h2.t1.HTTP2) + fillNetHTTPTransportConfig(&conf, h2.t1) } setConfigDefaults(&conf, false) return conf @@ -122,48 +120,3 @@ func adjustHTTP1MaxHeaderSize(n int64) int64 { const typicalHeaders = 10 // conservative return n + typicalHeaders*perFieldOverhead } - -func fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) { - if h2 == nil { - return - } - if h2.MaxConcurrentStreams != 0 { - conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) - } - if http2ConfigStrictMaxConcurrentRequests(h2) { - conf.StrictMaxConcurrentRequests = true - } - if h2.MaxEncoderHeaderTableSize != 0 { - conf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize) - } - if h2.MaxDecoderHeaderTableSize != 0 { - conf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize) - } - if h2.MaxConcurrentStreams != 0 { - conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) - } - if h2.MaxReadFrameSize != 0 { - conf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize) - } - if h2.MaxReceiveBufferPerConnection != 0 { - conf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection) - } - if h2.MaxReceiveBufferPerStream != 0 { - conf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream) - } - if h2.SendPingTimeout != 0 { - conf.SendPingTimeout = h2.SendPingTimeout - } - if h2.PingTimeout != 0 { - conf.PingTimeout = h2.PingTimeout - } - if h2.WriteByteTimeout != 0 { - conf.WriteByteTimeout = h2.WriteByteTimeout - } - if h2.PermitProhibitedCipherSuites { - conf.PermitProhibitedCipherSuites = true - } - if h2.CountError != nil { - conf.CountError = h2.CountError - } -} diff --git a/vendor/golang.org/x/net/http2/config_go124.go b/vendor/golang.org/x/net/http2/config_go124.go new file mode 100644 index 000000000000..5b516c55fffd --- /dev/null +++ b/vendor/golang.org/x/net/http2/config_go124.go @@ -0,0 +1,61 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.24 + +package http2 + +import "net/http" + +// fillNetHTTPServerConfig sets fields in conf from srv.HTTP2. +func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) { + fillNetHTTPConfig(conf, srv.HTTP2) +} + +// fillNetHTTPTransportConfig sets fields in conf from tr.HTTP2. +func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) { + fillNetHTTPConfig(conf, tr.HTTP2) +} + +func fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) { + if h2 == nil { + return + } + if h2.MaxConcurrentStreams != 0 { + conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) + } + if h2.MaxEncoderHeaderTableSize != 0 { + conf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize) + } + if h2.MaxDecoderHeaderTableSize != 0 { + conf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize) + } + if h2.MaxConcurrentStreams != 0 { + conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) + } + if h2.MaxReadFrameSize != 0 { + conf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize) + } + if h2.MaxReceiveBufferPerConnection != 0 { + conf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection) + } + if h2.MaxReceiveBufferPerStream != 0 { + conf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream) + } + if h2.SendPingTimeout != 0 { + conf.SendPingTimeout = h2.SendPingTimeout + } + if h2.PingTimeout != 0 { + conf.PingTimeout = h2.PingTimeout + } + if h2.WriteByteTimeout != 0 { + conf.WriteByteTimeout = h2.WriteByteTimeout + } + if h2.PermitProhibitedCipherSuites { + conf.PermitProhibitedCipherSuites = true + } + if h2.CountError != nil { + conf.CountError = h2.CountError + } +} diff --git a/vendor/golang.org/x/net/http2/config_go125.go b/vendor/golang.org/x/net/http2/config_go125.go deleted file mode 100644 index b4373fe33c3d..000000000000 --- a/vendor/golang.org/x/net/http2/config_go125.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2025 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.26 - -package http2 - -import ( - "net/http" -) - -func http2ConfigStrictMaxConcurrentRequests(h2 *http.HTTP2Config) bool { - return false -} diff --git a/vendor/golang.org/x/net/http2/config_go126.go b/vendor/golang.org/x/net/http2/config_go126.go deleted file mode 100644 index 6b071c149d22..000000000000 --- a/vendor/golang.org/x/net/http2/config_go126.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2025 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.26 - -package http2 - -import ( - "net/http" -) - -func http2ConfigStrictMaxConcurrentRequests(h2 *http.HTTP2Config) bool { - return h2.StrictMaxConcurrentRequests -} diff --git a/vendor/golang.org/x/net/http2/config_pre_go124.go b/vendor/golang.org/x/net/http2/config_pre_go124.go new file mode 100644 index 000000000000..060fd6c64c6c --- /dev/null +++ b/vendor/golang.org/x/net/http2/config_pre_go124.go @@ -0,0 +1,16 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.24 + +package http2 + +import "net/http" + +// Pre-Go 1.24 fallback. +// The Server.HTTP2 and Transport.HTTP2 config fields were added in Go 1.24. + +func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) {} + +func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) {} diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index 9a4bd123c95e..db3264da8cc8 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -280,8 +280,6 @@ type Framer struct { // lastHeaderStream is non-zero if the last frame was an // unfinished HEADERS/CONTINUATION. lastHeaderStream uint32 - // lastFrameType holds the type of the last frame for verifying frame order. - lastFrameType FrameType maxReadSize uint32 headerBuf [frameHeaderLen]byte @@ -349,7 +347,7 @@ func (fr *Framer) maxHeaderListSize() uint32 { func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) { // Write the FrameHeader. f.wbuf = append(f.wbuf[:0], - 0, // 3 bytes of length, filled in endWrite + 0, // 3 bytes of length, filled in in endWrite 0, 0, byte(ftype), @@ -490,41 +488,30 @@ func terminalReadFrameError(err error) bool { return err != nil } -// ReadFrameHeader reads the header of the next frame. -// It reads the 9-byte fixed frame header, and does not read any portion of the -// frame payload. The caller is responsible for consuming the payload, either -// with ReadFrameForHeader or directly from the Framer's io.Reader. +// ReadFrame reads a single frame. The returned Frame is only valid +// until the next call to ReadFrame. // -// If the frame is larger than previously set with SetMaxReadFrameSize, it -// returns the frame header and ErrFrameTooLarge. +// If the frame is larger than previously set with SetMaxReadFrameSize, the +// returned error is ErrFrameTooLarge. Other errors may be of type +// ConnectionError, StreamError, or anything else from the underlying +// reader. // -// If the returned FrameHeader.StreamID is non-zero, it indicates the stream -// responsible for the error. -func (fr *Framer) ReadFrameHeader() (FrameHeader, error) { +// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID +// indicates the stream responsible for the error. +func (fr *Framer) ReadFrame() (Frame, error) { fr.errDetail = nil + if fr.lastFrame != nil { + fr.lastFrame.invalidate() + } fh, err := readFrameHeader(fr.headerBuf[:], fr.r) if err != nil { - return fh, err + return nil, err } if fh.Length > fr.maxReadSize { if fh == invalidHTTP1LookingFrameHeader() { - return fh, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", ErrFrameTooLarge) + return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", ErrFrameTooLarge) } - return fh, ErrFrameTooLarge - } - if err := fr.checkFrameOrder(fh); err != nil { - return fh, err - } - return fh, nil -} - -// ReadFrameForHeader reads the payload for the frame with the given FrameHeader. -// -// It behaves identically to ReadFrame, other than not checking the maximum -// frame size. -func (fr *Framer) ReadFrameForHeader(fh FrameHeader) (Frame, error) { - if fr.lastFrame != nil { - fr.lastFrame.invalidate() + return nil, ErrFrameTooLarge } payload := fr.getReadBuf(fh.Length) if _, err := io.ReadFull(fr.r, payload); err != nil { @@ -540,7 +527,9 @@ func (fr *Framer) ReadFrameForHeader(fh FrameHeader) (Frame, error) { } return nil, err } - fr.lastFrame = f + if err := fr.checkFrameOrder(f); err != nil { + return nil, err + } if fr.logReads { fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f)) } @@ -550,24 +539,6 @@ func (fr *Framer) ReadFrameForHeader(fh FrameHeader) (Frame, error) { return f, nil } -// ReadFrame reads a single frame. The returned Frame is only valid -// until the next call to ReadFrame or ReadFrameBodyForHeader. -// -// If the frame is larger than previously set with SetMaxReadFrameSize, the -// returned error is ErrFrameTooLarge. Other errors may be of type -// ConnectionError, StreamError, or anything else from the underlying -// reader. -// -// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID -// indicates the stream responsible for the error. -func (fr *Framer) ReadFrame() (Frame, error) { - fh, err := fr.ReadFrameHeader() - if err != nil { - return nil, err - } - return fr.ReadFrameForHeader(fh) -} - // connError returns ConnectionError(code) but first // stashes away a public reason to the caller can optionally relay it // to the peer before hanging up on them. This might help others debug @@ -580,19 +551,20 @@ func (fr *Framer) connError(code ErrCode, reason string) error { // checkFrameOrder reports an error if f is an invalid frame to return // next from ReadFrame. Mostly it checks whether HEADERS and // CONTINUATION frames are contiguous. -func (fr *Framer) checkFrameOrder(fh FrameHeader) error { - lastType := fr.lastFrameType - fr.lastFrameType = fh.Type +func (fr *Framer) checkFrameOrder(f Frame) error { + last := fr.lastFrame + fr.lastFrame = f if fr.AllowIllegalReads { return nil } + fh := f.Header() if fr.lastHeaderStream != 0 { if fh.Type != FrameContinuation { return fr.connError(ErrCodeProtocol, fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d", fh.Type, fh.StreamID, - lastType, fr.lastHeaderStream)) + last.Header().Type, fr.lastHeaderStream)) } if fh.StreamID != fr.lastHeaderStream { return fr.connError(ErrCodeProtocol, @@ -1180,16 +1152,7 @@ type PriorityFrame struct { PriorityParam } -var defaultRFC9218Priority = PriorityParam{ - incremental: 0, - urgency: 3, -} - -// Note that HTTP/2 has had two different prioritization schemes, and -// PriorityParam struct below is a superset of both schemes. The exported -// symbols are from RFC 7540 and the non-exported ones are from RFC 9218. - -// PriorityParam are the stream prioritization parameters. +// PriorityParam are the stream prioritzation parameters. type PriorityParam struct { // StreamDep is a 31-bit stream identifier for the // stream that this stream depends on. Zero means no @@ -1204,20 +1167,6 @@ type PriorityParam struct { // the spec, "Add one to the value to obtain a weight between // 1 and 256." Weight uint8 - - // "The urgency (u) parameter value is Integer (see Section 3.3.1 of - // [STRUCTURED-FIELDS]), between 0 and 7 inclusive, in descending order of - // priority. The default is 3." - urgency uint8 - - // "The incremental (i) parameter value is Boolean (see Section 3.3.6 of - // [STRUCTURED-FIELDS]). It indicates if an HTTP response can be processed - // incrementally, i.e., provide some meaningful output as chunks of the - // response arrive." - // - // We use uint8 (i.e. 0 is false, 1 is true) instead of bool so we can - // avoid unnecessary type conversions and because either type takes 1 byte. - incremental uint8 } func (p PriorityParam) IsZero() bool { diff --git a/vendor/golang.org/x/net/http2/gotrack.go b/vendor/golang.org/x/net/http2/gotrack.go index 9921ca096d39..9933c9f8c748 100644 --- a/vendor/golang.org/x/net/http2/gotrack.go +++ b/vendor/golang.org/x/net/http2/gotrack.go @@ -15,32 +15,21 @@ import ( "runtime" "strconv" "sync" - "sync/atomic" ) var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1" -// Setting DebugGoroutines to false during a test to disable goroutine debugging -// results in race detector complaints when a test leaves goroutines running before -// returning. Tests shouldn't do this, of course, but when they do it generally shows -// up as infrequent, hard-to-debug flakes. (See #66519.) -// -// Disable goroutine debugging during individual tests with an atomic bool. -// (Note that it's safe to enable/disable debugging mid-test, so the actual race condition -// here is harmless.) -var disableDebugGoroutines atomic.Bool - type goroutineLock uint64 func newGoroutineLock() goroutineLock { - if !DebugGoroutines || disableDebugGoroutines.Load() { + if !DebugGoroutines { return 0 } return goroutineLock(curGoroutineID()) } func (g goroutineLock) check() { - if !DebugGoroutines || disableDebugGoroutines.Load() { + if !DebugGoroutines { return } if curGoroutineID() != uint64(g) { @@ -49,7 +38,7 @@ func (g goroutineLock) check() { } func (g goroutineLock) checkNotOn() { - if !DebugGoroutines || disableDebugGoroutines.Load() { + if !DebugGoroutines { return } if curGoroutineID() == uint64(g) { diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index 105fe12fefaa..ea5ae629fde0 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -15,6 +15,7 @@ package http2 // import "golang.org/x/net/http2" import ( "bufio" + "context" "crypto/tls" "errors" "fmt" @@ -34,6 +35,7 @@ var ( VerboseLogs bool logFrameWrites bool logFrameReads bool + inTests bool // Enabling extended CONNECT by causes browsers to attempt to use // WebSockets-over-HTTP/2. This results in problems when the server's websocket @@ -253,13 +255,15 @@ func (cw closeWaiter) Wait() { // idle memory usage with many connections. type bufferedWriter struct { _ incomparable - conn net.Conn // immutable - bw *bufio.Writer // non-nil when data is buffered - byteTimeout time.Duration // immutable, WriteByteTimeout + group synctestGroupInterface // immutable + conn net.Conn // immutable + bw *bufio.Writer // non-nil when data is buffered + byteTimeout time.Duration // immutable, WriteByteTimeout } -func newBufferedWriter(conn net.Conn, timeout time.Duration) *bufferedWriter { +func newBufferedWriter(group synctestGroupInterface, conn net.Conn, timeout time.Duration) *bufferedWriter { return &bufferedWriter{ + group: group, conn: conn, byteTimeout: timeout, } @@ -310,18 +314,24 @@ func (w *bufferedWriter) Flush() error { type bufferedWriterTimeoutWriter bufferedWriter func (w *bufferedWriterTimeoutWriter) Write(p []byte) (n int, err error) { - return writeWithByteTimeout(w.conn, w.byteTimeout, p) + return writeWithByteTimeout(w.group, w.conn, w.byteTimeout, p) } // writeWithByteTimeout writes to conn. // If more than timeout passes without any bytes being written to the connection, // the write fails. -func writeWithByteTimeout(conn net.Conn, timeout time.Duration, p []byte) (n int, err error) { +func writeWithByteTimeout(group synctestGroupInterface, conn net.Conn, timeout time.Duration, p []byte) (n int, err error) { if timeout <= 0 { return conn.Write(p) } for { - conn.SetWriteDeadline(time.Now().Add(timeout)) + var now time.Time + if group == nil { + now = time.Now() + } else { + now = group.Now() + } + conn.SetWriteDeadline(now.Add(timeout)) nn, err := conn.Write(p[n:]) n += nn if n == len(p) || nn == 0 || !errors.Is(err, os.ErrDeadlineExceeded) { @@ -407,3 +417,14 @@ func (s *sorter) SortStrings(ss []string) { // makes that struct also non-comparable, and generally doesn't add // any size (as long as it's first). type incomparable [0]func() + +// synctestGroupInterface is the methods of synctestGroup used by Server and Transport. +// It's defined as an interface here to let us keep synctestGroup entirely test-only +// and not a part of non-test builds. +type synctestGroupInterface interface { + Join() + Now() time.Time + NewTimer(d time.Duration) timer + AfterFunc(d time.Duration, f func()) timer + ContextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) +} diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index bdc5520ebd3e..51fca38f61d7 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -176,15 +176,44 @@ type Server struct { // so that we don't embed a Mutex in this struct, which will make the // struct non-copyable, which might break some callers. state *serverInternalState + + // Synchronization group used for testing. + // Outside of tests, this is nil. + group synctestGroupInterface +} + +func (s *Server) markNewGoroutine() { + if s.group != nil { + s.group.Join() + } +} + +func (s *Server) now() time.Time { + if s.group != nil { + return s.group.Now() + } + return time.Now() +} + +// newTimer creates a new time.Timer, or a synthetic timer in tests. +func (s *Server) newTimer(d time.Duration) timer { + if s.group != nil { + return s.group.NewTimer(d) + } + return timeTimer{time.NewTimer(d)} +} + +// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. +func (s *Server) afterFunc(d time.Duration, f func()) timer { + if s.group != nil { + return s.group.AfterFunc(d, f) + } + return timeTimer{time.AfterFunc(d, f)} } type serverInternalState struct { mu sync.Mutex activeConns map[*serverConn]struct{} - - // Pool of error channels. This is per-Server rather than global - // because channels can't be reused across synctest bubbles. - errChanPool sync.Pool } func (s *serverInternalState) registerConn(sc *serverConn) { @@ -216,27 +245,6 @@ func (s *serverInternalState) startGracefulShutdown() { s.mu.Unlock() } -// Global error channel pool used for uninitialized Servers. -// We use a per-Server pool when possible to avoid using channels across synctest bubbles. -var errChanPool = sync.Pool{ - New: func() any { return make(chan error, 1) }, -} - -func (s *serverInternalState) getErrChan() chan error { - if s == nil { - return errChanPool.Get().(chan error) // Server used without calling ConfigureServer - } - return s.errChanPool.Get().(chan error) -} - -func (s *serverInternalState) putErrChan(ch chan error) { - if s == nil { - errChanPool.Put(ch) // Server used without calling ConfigureServer - return - } - s.errChanPool.Put(ch) -} - // ConfigureServer adds HTTP/2 support to a net/http Server. // // The configuration conf may be nil. @@ -249,10 +257,7 @@ func ConfigureServer(s *http.Server, conf *Server) error { if conf == nil { conf = new(Server) } - conf.state = &serverInternalState{ - activeConns: make(map[*serverConn]struct{}), - errChanPool: sync.Pool{New: func() any { return make(chan error, 1) }}, - } + conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})} if h1, h2 := s, conf; h2.IdleTimeout == 0 { if h1.IdleTimeout != 0 { h2.IdleTimeout = h1.IdleTimeout @@ -418,9 +423,6 @@ func (o *ServeConnOpts) handler() http.Handler { // // The opts parameter is optional. If nil, default values are used. func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { - if opts == nil { - opts = &ServeConnOpts{} - } s.serveConn(c, opts, nil) } @@ -436,7 +438,7 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon conn: c, baseCtx: baseCtx, remoteAddrStr: c.RemoteAddr().String(), - bw: newBufferedWriter(c, conf.WriteByteTimeout), + bw: newBufferedWriter(s.group, c, conf.WriteByteTimeout), handler: opts.handler(), streams: make(map[uint32]*stream), readFrameCh: make(chan readFrameResult), @@ -636,11 +638,11 @@ type serverConn struct { pingSent bool sentPingData [8]byte goAwayCode ErrCode - shutdownTimer *time.Timer // nil until used - idleTimer *time.Timer // nil if unused + shutdownTimer timer // nil until used + idleTimer timer // nil if unused readIdleTimeout time.Duration pingTimeout time.Duration - readIdleTimer *time.Timer // nil if unused + readIdleTimer timer // nil if unused // Owned by the writeFrameAsync goroutine: headerWriteBuf bytes.Buffer @@ -685,12 +687,12 @@ type stream struct { flow outflow // limits writing from Handler to client inflow inflow // what the client is allowed to POST/etc to us state streamState - resetQueued bool // RST_STREAM queued for write; set by sc.resetStream - gotTrailerHeader bool // HEADER frame for trailers was seen - wroteHeaders bool // whether we wrote headers (not status 100) - readDeadline *time.Timer // nil if unused - writeDeadline *time.Timer // nil if unused - closeErr error // set before cw is closed + resetQueued bool // RST_STREAM queued for write; set by sc.resetStream + gotTrailerHeader bool // HEADER frame for trailers was seen + wroteHeaders bool // whether we wrote headers (not status 100) + readDeadline timer // nil if unused + writeDeadline timer // nil if unused + closeErr error // set before cw is closed trailer http.Header // accumulated trailers reqTrailer http.Header // handler's Request.Trailer @@ -846,6 +848,7 @@ type readFrameResult struct { // consumer is done with the frame. // It's run on its own goroutine. func (sc *serverConn) readFrames() { + sc.srv.markNewGoroutine() gate := make(chan struct{}) gateDone := func() { gate <- struct{}{} } for { @@ -878,6 +881,7 @@ type frameWriteResult struct { // At most one goroutine can be running writeFrameAsync at a time per // serverConn. func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest, wd *writeData) { + sc.srv.markNewGoroutine() var err error if wd == nil { err = wr.write.writeFrame(sc) @@ -961,22 +965,22 @@ func (sc *serverConn) serve(conf http2Config) { sc.setConnState(http.StateIdle) if sc.srv.IdleTimeout > 0 { - sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) + sc.idleTimer = sc.srv.afterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) defer sc.idleTimer.Stop() } if conf.SendPingTimeout > 0 { sc.readIdleTimeout = conf.SendPingTimeout - sc.readIdleTimer = time.AfterFunc(conf.SendPingTimeout, sc.onReadIdleTimer) + sc.readIdleTimer = sc.srv.afterFunc(conf.SendPingTimeout, sc.onReadIdleTimer) defer sc.readIdleTimer.Stop() } go sc.readFrames() // closed by defer sc.conn.Close above - settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer) + settingsTimer := sc.srv.afterFunc(firstSettingsTimeout, sc.onSettingsTimer) defer settingsTimer.Stop() - lastFrameTime := time.Now() + lastFrameTime := sc.srv.now() loopNum := 0 for { loopNum++ @@ -990,7 +994,7 @@ func (sc *serverConn) serve(conf http2Config) { case res := <-sc.wroteFrameCh: sc.wroteFrame(res) case res := <-sc.readFrameCh: - lastFrameTime = time.Now() + lastFrameTime = sc.srv.now() // Process any written frames before reading new frames from the client since a // written frame could have triggered a new stream to be started. if sc.writingFrameAsync { @@ -1073,7 +1077,7 @@ func (sc *serverConn) handlePingTimer(lastFrameReadTime time.Time) { } pingAt := lastFrameReadTime.Add(sc.readIdleTimeout) - now := time.Now() + now := sc.srv.now() if pingAt.After(now) { // We received frames since arming the ping timer. // Reset it for the next possible timeout. @@ -1137,10 +1141,10 @@ func (sc *serverConn) readPreface() error { errc <- nil } }() - timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server? + timer := sc.srv.newTimer(prefaceTimeout) // TODO: configurable on *Server? defer timer.Stop() select { - case <-timer.C: + case <-timer.C(): return errPrefaceTimeout case err := <-errc: if err == nil { @@ -1152,6 +1156,10 @@ func (sc *serverConn) readPreface() error { } } +var errChanPool = sync.Pool{ + New: func() interface{} { return make(chan error, 1) }, +} + var writeDataPool = sync.Pool{ New: func() interface{} { return new(writeData) }, } @@ -1159,7 +1167,7 @@ var writeDataPool = sync.Pool{ // writeDataFromHandler writes DATA response frames from a handler on // the given stream. func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error { - ch := sc.srv.state.getErrChan() + ch := errChanPool.Get().(chan error) writeArg := writeDataPool.Get().(*writeData) *writeArg = writeData{stream.id, data, endStream} err := sc.writeFrameFromHandler(FrameWriteRequest{ @@ -1191,7 +1199,7 @@ func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStrea return errStreamClosed } } - sc.srv.state.putErrChan(ch) + errChanPool.Put(ch) if frameWriteDone { writeDataPool.Put(writeArg) } @@ -1505,7 +1513,7 @@ func (sc *serverConn) goAway(code ErrCode) { func (sc *serverConn) shutDownIn(d time.Duration) { sc.serveG.check() - sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer) + sc.shutdownTimer = sc.srv.afterFunc(d, sc.onShutdownTimer) } func (sc *serverConn) resetStream(se StreamError) { @@ -2110,7 +2118,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // (in Go 1.8), though. That's a more sane option anyway. if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) - st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) + st.readDeadline = sc.srv.afterFunc(sc.hs.ReadTimeout, st.onReadTimeout) } return sc.scheduleHandler(id, rw, req, handler) @@ -2208,7 +2216,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream st.flow.add(sc.initialStreamSendWindowSize) st.inflow.init(sc.initialStreamRecvWindowSize) if sc.hs.WriteTimeout > 0 { - st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) + st.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) } sc.streams[id] = st @@ -2397,6 +2405,7 @@ func (sc *serverConn) handlerDone() { // Run on its own goroutine. func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { + sc.srv.markNewGoroutine() defer sc.sendServeMsg(handlerDoneMsg) didPanic := true defer func() { @@ -2445,7 +2454,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro // waiting for this frame to be written, so an http.Flush mid-handler // writes out the correct value of keys, before a handler later potentially // mutates it. - errc = sc.srv.state.getErrChan() + errc = errChanPool.Get().(chan error) } if err := sc.writeFrameFromHandler(FrameWriteRequest{ write: headerData, @@ -2457,7 +2466,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro if errc != nil { select { case err := <-errc: - sc.srv.state.putErrChan(errc) + errChanPool.Put(errc) return err case <-sc.doneServing: return errClientDisconnected @@ -2564,7 +2573,7 @@ func (b *requestBody) Read(p []byte) (n int, err error) { if err == io.EOF { b.sawEOF = true } - if b.conn == nil { + if b.conn == nil && inTests { return } b.conn.noteBodyReadFromHandler(b.stream, n, err) @@ -2693,7 +2702,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { var date string if _, ok := rws.snapHeader["Date"]; !ok { // TODO(bradfitz): be faster here, like net/http? measure. - date = time.Now().UTC().Format(http.TimeFormat) + date = rws.conn.srv.now().UTC().Format(http.TimeFormat) } for _, v := range rws.snapHeader["Trailer"] { @@ -2815,7 +2824,7 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() { func (w *responseWriter) SetReadDeadline(deadline time.Time) error { st := w.rws.stream - if !deadline.IsZero() && deadline.Before(time.Now()) { + if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) { // If we're setting a deadline in the past, reset the stream immediately // so writes after SetWriteDeadline returns will fail. st.onReadTimeout() @@ -2831,9 +2840,9 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { if deadline.IsZero() { st.readDeadline = nil } else if st.readDeadline == nil { - st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout) + st.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout) } else { - st.readDeadline.Reset(deadline.Sub(time.Now())) + st.readDeadline.Reset(deadline.Sub(sc.srv.now())) } }) return nil @@ -2841,7 +2850,7 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error { func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { st := w.rws.stream - if !deadline.IsZero() && deadline.Before(time.Now()) { + if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) { // If we're setting a deadline in the past, reset the stream immediately // so writes after SetWriteDeadline returns will fail. st.onWriteTimeout() @@ -2857,9 +2866,9 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { if deadline.IsZero() { st.writeDeadline = nil } else if st.writeDeadline == nil { - st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout) + st.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout) } else { - st.writeDeadline.Reset(deadline.Sub(time.Now())) + st.writeDeadline.Reset(deadline.Sub(sc.srv.now())) } }) return nil @@ -3138,7 +3147,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error { method: opts.Method, url: u, header: cloneHeader(opts.Header), - done: sc.srv.state.getErrChan(), + done: errChanPool.Get().(chan error), } select { @@ -3155,7 +3164,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error { case <-st.cw: return errStreamClosed case err := <-msg.done: - sc.srv.state.putErrChan(msg.done) + errChanPool.Put(msg.done) return err } } diff --git a/vendor/golang.org/x/net/http2/timer.go b/vendor/golang.org/x/net/http2/timer.go new file mode 100644 index 000000000000..0b1c17b81296 --- /dev/null +++ b/vendor/golang.org/x/net/http2/timer.go @@ -0,0 +1,20 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package http2 + +import "time" + +// A timer is a time.Timer, as an interface which can be replaced in tests. +type timer = interface { + C() <-chan time.Time + Reset(d time.Duration) bool + Stop() bool +} + +// timeTimer adapts a time.Timer to the timer interface. +type timeTimer struct { + *time.Timer +} + +func (t timeTimer) C() <-chan time.Time { return t.Timer.C } diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 1965913e543b..f26356b9cd91 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -9,7 +9,6 @@ package http2 import ( "bufio" "bytes" - "compress/flate" "compress/gzip" "context" "crypto/rand" @@ -194,6 +193,50 @@ type Transport struct { type transportTestHooks struct { newclientconn func(*ClientConn) + group synctestGroupInterface +} + +func (t *Transport) markNewGoroutine() { + if t != nil && t.transportTestHooks != nil { + t.transportTestHooks.group.Join() + } +} + +func (t *Transport) now() time.Time { + if t != nil && t.transportTestHooks != nil { + return t.transportTestHooks.group.Now() + } + return time.Now() +} + +func (t *Transport) timeSince(when time.Time) time.Duration { + if t != nil && t.transportTestHooks != nil { + return t.now().Sub(when) + } + return time.Since(when) +} + +// newTimer creates a new time.Timer, or a synthetic timer in tests. +func (t *Transport) newTimer(d time.Duration) timer { + if t.transportTestHooks != nil { + return t.transportTestHooks.group.NewTimer(d) + } + return timeTimer{time.NewTimer(d)} +} + +// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. +func (t *Transport) afterFunc(d time.Duration, f func()) timer { + if t.transportTestHooks != nil { + return t.transportTestHooks.group.AfterFunc(d, f) + } + return timeTimer{time.AfterFunc(d, f)} +} + +func (t *Transport) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { + if t.transportTestHooks != nil { + return t.transportTestHooks.group.ContextWithTimeout(ctx, d) + } + return context.WithTimeout(ctx, d) } func (t *Transport) maxHeaderListSize() uint32 { @@ -323,7 +366,7 @@ type ClientConn struct { readerErr error // set before readerDone is closed idleTimeout time.Duration // or 0 for never - idleTimer *time.Timer + idleTimer timer mu sync.Mutex // guards following cond *sync.Cond // hold mu; broadcast on flow/closed changes @@ -356,7 +399,6 @@ type ClientConn struct { readIdleTimeout time.Duration pingTimeout time.Duration extendedConnectAllowed bool - strictMaxConcurrentStreams bool // rstStreamPingsBlocked works around an unfortunate gRPC behavior. // gRPC strictly limits the number of PING frames that it will receive. @@ -492,12 +534,14 @@ func (cs *clientStream) closeReqBodyLocked() { cs.reqBodyClosed = make(chan struct{}) reqBodyClosed := cs.reqBodyClosed go func() { + cs.cc.t.markNewGoroutine() cs.reqBody.Close() close(reqBodyClosed) }() } type stickyErrWriter struct { + group synctestGroupInterface conn net.Conn timeout time.Duration err *error @@ -507,7 +551,7 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) { if *sew.err != nil { return 0, *sew.err } - n, err = writeWithByteTimeout(sew.conn, sew.timeout, p) + n, err = writeWithByteTimeout(sew.group, sew.conn, sew.timeout, p) *sew.err = err return n, err } @@ -606,9 +650,9 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res backoff := float64(uint(1) << (uint(retry) - 1)) backoff += backoff * (0.1 * mathrand.Float64()) d := time.Second * time.Duration(backoff) - tm := time.NewTimer(d) + tm := t.newTimer(d) select { - case <-tm.C: + case <-tm.C(): t.vlogf("RoundTrip retrying after failure: %v", roundTripErr) continue case <-req.Context().Done(): @@ -655,7 +699,6 @@ var ( errClientConnUnusable = errors.New("http2: client conn not usable") errClientConnNotEstablished = errors.New("http2: client conn could not be established") errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY") - errClientConnForceClosed = errors.New("http2: client connection force closed via ClientConn.Close") ) // shouldRetryRequest is called by RoundTrip when a request fails to get @@ -786,8 +829,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro initialWindowSize: 65535, // spec default initialStreamRecvWindowSize: conf.MaxUploadBufferPerStream, maxConcurrentStreams: initialMaxConcurrentStreams, // "infinite", per spec. Use a smaller value until we have received server settings. - strictMaxConcurrentStreams: conf.StrictMaxConcurrentRequests, - peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead. + peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead. streams: make(map[uint32]*clientStream), singleUse: singleUse, seenSettingsChan: make(chan struct{}), @@ -796,11 +838,14 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro pingTimeout: conf.PingTimeout, pings: make(map[[8]byte]chan struct{}), reqHeaderMu: make(chan struct{}, 1), - lastActive: time.Now(), + lastActive: t.now(), } + var group synctestGroupInterface if t.transportTestHooks != nil { + t.markNewGoroutine() t.transportTestHooks.newclientconn(cc) c = cc.tconn + group = t.group } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) @@ -812,6 +857,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro // TODO: adjust this writer size to account for frame size + // MTU + crypto/tls record padding. cc.bw = bufio.NewWriter(stickyErrWriter{ + group: group, conn: c, timeout: conf.WriteByteTimeout, err: &cc.werr, @@ -860,7 +906,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro // Start the idle timer after the connection is fully initialized. if d := t.idleConnTimeout(); d != 0 { cc.idleTimeout = d - cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout) + cc.idleTimer = t.afterFunc(d, cc.onIdleTimeout) } go cc.readLoop() @@ -871,7 +917,7 @@ func (cc *ClientConn) healthCheck() { pingTimeout := cc.pingTimeout // We don't need to periodically ping in the health check, because the readLoop of ClientConn will // trigger the healthCheck again if there is no frame received. - ctx, cancel := context.WithTimeout(context.Background(), pingTimeout) + ctx, cancel := cc.t.contextWithTimeout(context.Background(), pingTimeout) defer cancel() cc.vlogf("http2: Transport sending health check") err := cc.Ping(ctx) @@ -1021,7 +1067,7 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { return } var maxConcurrentOkay bool - if cc.strictMaxConcurrentStreams { + if cc.t.StrictMaxConcurrentStreams { // We'll tell the caller we can take a new request to // prevent the caller from dialing a new TCP // connection, but then we'll block later before @@ -1074,7 +1120,7 @@ func (cc *ClientConn) tooIdleLocked() bool { // times are compared based on their wall time. We don't want // to reuse a connection that's been sitting idle during // VM/laptop suspend if monotonic time was also frozen. - return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && time.Since(cc.lastIdle.Round(0)) > cc.idleTimeout + return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && cc.t.timeSince(cc.lastIdle.Round(0)) > cc.idleTimeout } // onIdleTimeout is called from a time.AfterFunc goroutine. It will @@ -1140,6 +1186,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { done := make(chan struct{}) cancelled := false // guarded by cc.mu go func() { + cc.t.markNewGoroutine() cc.mu.Lock() defer cc.mu.Unlock() for { @@ -1210,7 +1257,8 @@ func (cc *ClientConn) closeForError(err error) { // // In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead. func (cc *ClientConn) Close() error { - cc.closeForError(errClientConnForceClosed) + err := errors.New("http2: client connection force closed via ClientConn.Close") + cc.closeForError(err) return nil } @@ -1379,6 +1427,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) // // It sends the request and performs post-request cleanup (closing Request.Body, etc.). func (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream)) { + cs.cc.t.markNewGoroutine() err := cs.writeRequest(req, streamf) cs.cleanupWriteRequest(err) } @@ -1509,9 +1558,9 @@ func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStre var respHeaderTimer <-chan time.Time var respHeaderRecv chan struct{} if d := cc.responseHeaderTimeout(); d != 0 { - timer := time.NewTimer(d) + timer := cc.t.newTimer(d) defer timer.Stop() - respHeaderTimer = timer.C + respHeaderTimer = timer.C() respHeaderRecv = cs.respHeaderRecv } // Wait until the peer half-closes its end of the stream, @@ -1704,7 +1753,7 @@ func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { // Return a fatal error which aborts the retry loop. return errClientConnNotEstablished } - cc.lastActive = time.Now() + cc.lastActive = cc.t.now() if cc.closed || !cc.canTakeNewRequestLocked() { return errClientConnUnusable } @@ -2043,10 +2092,10 @@ func (cc *ClientConn) forgetStreamID(id uint32) { if len(cc.streams) != slen-1 { panic("forgetting unknown stream id") } - cc.lastActive = time.Now() + cc.lastActive = cc.t.now() if len(cc.streams) == 0 && cc.idleTimer != nil { cc.idleTimer.Reset(cc.idleTimeout) - cc.lastIdle = time.Now() + cc.lastIdle = cc.t.now() } // Wake up writeRequestBody via clientStream.awaitFlowControl and // wake up RoundTrip if there is a pending request. @@ -2072,6 +2121,7 @@ type clientConnReadLoop struct { // readLoop runs in its own goroutine and reads and dispatches frames. func (cc *ClientConn) readLoop() { + cc.t.markNewGoroutine() rl := &clientConnReadLoop{cc: cc} defer rl.cleanup() cc.readerErr = rl.run() @@ -2138,9 +2188,9 @@ func (rl *clientConnReadLoop) cleanup() { if cc.idleTimeout > 0 && unusedWaitTime > cc.idleTimeout { unusedWaitTime = cc.idleTimeout } - idleTime := time.Now().Sub(cc.lastActive) + idleTime := cc.t.now().Sub(cc.lastActive) if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime && !cc.closedOnIdle { - cc.idleTimer = time.AfterFunc(unusedWaitTime-idleTime, func() { + cc.idleTimer = cc.t.afterFunc(unusedWaitTime-idleTime, func() { cc.t.connPool().MarkDead(cc) }) } else { @@ -2200,9 +2250,9 @@ func (rl *clientConnReadLoop) run() error { cc := rl.cc gotSettings := false readIdleTimeout := cc.readIdleTimeout - var t *time.Timer + var t timer if readIdleTimeout != 0 { - t = time.AfterFunc(readIdleTimeout, cc.healthCheck) + t = cc.t.afterFunc(readIdleTimeout, cc.healthCheck) } for { f, err := cc.fr.ReadFrame() @@ -2948,6 +2998,7 @@ func (cc *ClientConn) Ping(ctx context.Context) error { var pingError error errc := make(chan struct{}) go func() { + cc.t.markNewGoroutine() cc.wmu.Lock() defer cc.wmu.Unlock() if pingError = cc.fr.WritePing(false, p); pingError != nil { @@ -3077,102 +3128,35 @@ type erringRoundTripper struct{ err error } func (rt erringRoundTripper) RoundTripErr() error { return rt.err } func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err } -var errConcurrentReadOnResBody = errors.New("http2: concurrent read on response body") - // gzipReader wraps a response body so it can lazily -// get gzip.Reader from the pool on the first call to Read. -// After Close is called it puts gzip.Reader to the pool immediately -// if there is no Read in progress or later when Read completes. +// call gzip.NewReader on the first call to Read type gzipReader struct { _ incomparable body io.ReadCloser // underlying Response.Body - mu sync.Mutex // guards zr and zerr - zr *gzip.Reader // stores gzip reader from the pool between reads - zerr error // sticky gzip reader init error or sentinel value to detect concurrent read and read after close -} - -type eofReader struct{} - -func (eofReader) Read([]byte) (int, error) { return 0, io.EOF } -func (eofReader) ReadByte() (byte, error) { return 0, io.EOF } - -var gzipPool = sync.Pool{New: func() any { return new(gzip.Reader) }} - -// gzipPoolGet gets a gzip.Reader from the pool and resets it to read from r. -func gzipPoolGet(r io.Reader) (*gzip.Reader, error) { - zr := gzipPool.Get().(*gzip.Reader) - if err := zr.Reset(r); err != nil { - gzipPoolPut(zr) - return nil, err - } - return zr, nil -} - -// gzipPoolPut puts a gzip.Reader back into the pool. -func gzipPoolPut(zr *gzip.Reader) { - // Reset will allocate bufio.Reader if we pass it anything - // other than a flate.Reader, so ensure that it's getting one. - var r flate.Reader = eofReader{} - zr.Reset(r) - gzipPool.Put(zr) + zr *gzip.Reader // lazily-initialized gzip reader + zerr error // sticky error } -// acquire returns a gzip.Reader for reading response body. -// The reader must be released after use. -func (gz *gzipReader) acquire() (*gzip.Reader, error) { - gz.mu.Lock() - defer gz.mu.Unlock() +func (gz *gzipReader) Read(p []byte) (n int, err error) { if gz.zerr != nil { - return nil, gz.zerr + return 0, gz.zerr } if gz.zr == nil { - gz.zr, gz.zerr = gzipPoolGet(gz.body) - if gz.zerr != nil { - return nil, gz.zerr + gz.zr, err = gzip.NewReader(gz.body) + if err != nil { + gz.zerr = err + return 0, err } } - ret := gz.zr - gz.zr, gz.zerr = nil, errConcurrentReadOnResBody - return ret, nil -} - -// release returns the gzip.Reader to the pool if Close was called during Read. -func (gz *gzipReader) release(zr *gzip.Reader) { - gz.mu.Lock() - defer gz.mu.Unlock() - if gz.zerr == errConcurrentReadOnResBody { - gz.zr, gz.zerr = zr, nil - } else { // fs.ErrClosed - gzipPoolPut(zr) - } + return gz.zr.Read(p) } -// close returns the gzip.Reader to the pool immediately or -// signals release to do so after Read completes. -func (gz *gzipReader) close() { - gz.mu.Lock() - defer gz.mu.Unlock() - if gz.zerr == nil && gz.zr != nil { - gzipPoolPut(gz.zr) - gz.zr = nil +func (gz *gzipReader) Close() error { + if err := gz.body.Close(); err != nil { + return err } gz.zerr = fs.ErrClosed -} - -func (gz *gzipReader) Read(p []byte) (n int, err error) { - zr, err := gz.acquire() - if err != nil { - return 0, err - } - defer gz.release(zr) - - return zr.Read(p) -} - -func (gz *gzipReader) Close() error { - gz.close() - - return gz.body.Close() + return nil } type errorReader struct{ err error } @@ -3244,7 +3228,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { cc.mu.Lock() ci.WasIdle = len(cc.streams) == 0 && reused if ci.WasIdle && !cc.lastActive.IsZero() { - ci.IdleTime = time.Since(cc.lastActive) + ci.IdleTime = cc.t.timeSince(cc.lastActive) } cc.mu.Unlock() diff --git a/vendor/golang.org/x/net/http2/writesched.go b/vendor/golang.org/x/net/http2/writesched.go index 7de27be52509..cc893adc29af 100644 --- a/vendor/golang.org/x/net/http2/writesched.go +++ b/vendor/golang.org/x/net/http2/writesched.go @@ -42,8 +42,6 @@ type OpenStreamOptions struct { // PusherID is zero if the stream was initiated by the client. Otherwise, // PusherID names the stream that pushed the newly opened stream. PusherID uint32 - // priority is used to set the priority of the newly opened stream. - priority PriorityParam } // FrameWriteRequest is a request to write a frame. @@ -185,75 +183,45 @@ func (wr *FrameWriteRequest) replyToWriter(err error) { } // writeQueue is used by implementations of WriteScheduler. -// -// Each writeQueue contains a queue of FrameWriteRequests, meant to store all -// FrameWriteRequests associated with a given stream. This is implemented as a -// two-stage queue: currQueue[currPos:] and nextQueue. Removing an item is done -// by incrementing currPos of currQueue. Adding an item is done by appending it -// to the nextQueue. If currQueue is empty when trying to remove an item, we -// can swap currQueue and nextQueue to remedy the situation. -// This two-stage queue is analogous to the use of two lists in Okasaki's -// purely functional queue but without the overhead of reversing the list when -// swapping stages. -// -// writeQueue also contains prev and next, this can be used by implementations -// of WriteScheduler to construct data structures that represent the order of -// writing between different streams (e.g. circular linked list). type writeQueue struct { - currQueue []FrameWriteRequest - nextQueue []FrameWriteRequest - currPos int - + s []FrameWriteRequest prev, next *writeQueue } -func (q *writeQueue) empty() bool { - return (len(q.currQueue) - q.currPos + len(q.nextQueue)) == 0 -} +func (q *writeQueue) empty() bool { return len(q.s) == 0 } func (q *writeQueue) push(wr FrameWriteRequest) { - q.nextQueue = append(q.nextQueue, wr) + q.s = append(q.s, wr) } func (q *writeQueue) shift() FrameWriteRequest { - if q.empty() { + if len(q.s) == 0 { panic("invalid use of queue") } - if q.currPos >= len(q.currQueue) { - q.currQueue, q.currPos, q.nextQueue = q.nextQueue, 0, q.currQueue[:0] - } - wr := q.currQueue[q.currPos] - q.currQueue[q.currPos] = FrameWriteRequest{} - q.currPos++ + wr := q.s[0] + // TODO: less copy-happy queue. + copy(q.s, q.s[1:]) + q.s[len(q.s)-1] = FrameWriteRequest{} + q.s = q.s[:len(q.s)-1] return wr } -func (q *writeQueue) peek() *FrameWriteRequest { - if q.currPos < len(q.currQueue) { - return &q.currQueue[q.currPos] - } - if len(q.nextQueue) > 0 { - return &q.nextQueue[0] - } - return nil -} - // consume consumes up to n bytes from q.s[0]. If the frame is // entirely consumed, it is removed from the queue. If the frame // is partially consumed, the frame is kept with the consumed // bytes removed. Returns true iff any bytes were consumed. func (q *writeQueue) consume(n int32) (FrameWriteRequest, bool) { - if q.empty() { + if len(q.s) == 0 { return FrameWriteRequest{}, false } - consumed, rest, numresult := q.peek().Consume(n) + consumed, rest, numresult := q.s[0].Consume(n) switch numresult { case 0: return FrameWriteRequest{}, false case 1: q.shift() case 2: - *q.peek() = rest + q.s[0] = rest } return consumed, true } @@ -262,15 +230,10 @@ type writeQueuePool []*writeQueue // put inserts an unused writeQueue into the pool. func (p *writeQueuePool) put(q *writeQueue) { - for i := range q.currQueue { - q.currQueue[i] = FrameWriteRequest{} - } - for i := range q.nextQueue { - q.nextQueue[i] = FrameWriteRequest{} + for i := range q.s { + q.s[i] = FrameWriteRequest{} } - q.currQueue = q.currQueue[:0] - q.nextQueue = q.nextQueue[:0] - q.currPos = 0 + q.s = q.s[:0] *p = append(*p, q) } diff --git a/vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go b/vendor/golang.org/x/net/http2/writesched_priority.go similarity index 77% rename from vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go rename to vendor/golang.org/x/net/http2/writesched_priority.go index 4e33c29a2445..f6783339d11e 100644 --- a/vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go +++ b/vendor/golang.org/x/net/http2/writesched_priority.go @@ -11,7 +11,7 @@ import ( ) // RFC 7540, Section 5.3.5: the default weight is 16. -const priorityDefaultWeightRFC7540 = 15 // 16 = 15 + 1 +const priorityDefaultWeight = 15 // 16 = 15 + 1 // PriorityWriteSchedulerConfig configures a priorityWriteScheduler. type PriorityWriteSchedulerConfig struct { @@ -66,8 +66,8 @@ func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler } } - ws := &priorityWriteSchedulerRFC7540{ - nodes: make(map[uint32]*priorityNodeRFC7540), + ws := &priorityWriteScheduler{ + nodes: make(map[uint32]*priorityNode), maxClosedNodesInTree: cfg.MaxClosedNodesInTree, maxIdleNodesInTree: cfg.MaxIdleNodesInTree, enableWriteThrottle: cfg.ThrottleOutOfOrderWrites, @@ -81,32 +81,32 @@ func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler return ws } -type priorityNodeStateRFC7540 int +type priorityNodeState int const ( - priorityNodeOpenRFC7540 priorityNodeStateRFC7540 = iota - priorityNodeClosedRFC7540 - priorityNodeIdleRFC7540 + priorityNodeOpen priorityNodeState = iota + priorityNodeClosed + priorityNodeIdle ) -// priorityNodeRFC7540 is a node in an HTTP/2 priority tree. +// priorityNode is a node in an HTTP/2 priority tree. // Each node is associated with a single stream ID. // See RFC 7540, Section 5.3. -type priorityNodeRFC7540 struct { - q writeQueue // queue of pending frames to write - id uint32 // id of the stream, or 0 for the root of the tree - weight uint8 // the actual weight is weight+1, so the value is in [1,256] - state priorityNodeStateRFC7540 // open | closed | idle - bytes int64 // number of bytes written by this node, or 0 if closed - subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree +type priorityNode struct { + q writeQueue // queue of pending frames to write + id uint32 // id of the stream, or 0 for the root of the tree + weight uint8 // the actual weight is weight+1, so the value is in [1,256] + state priorityNodeState // open | closed | idle + bytes int64 // number of bytes written by this node, or 0 if closed + subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree // These links form the priority tree. - parent *priorityNodeRFC7540 - kids *priorityNodeRFC7540 // start of the kids list - prev, next *priorityNodeRFC7540 // doubly-linked list of siblings + parent *priorityNode + kids *priorityNode // start of the kids list + prev, next *priorityNode // doubly-linked list of siblings } -func (n *priorityNodeRFC7540) setParent(parent *priorityNodeRFC7540) { +func (n *priorityNode) setParent(parent *priorityNode) { if n == parent { panic("setParent to self") } @@ -141,7 +141,7 @@ func (n *priorityNodeRFC7540) setParent(parent *priorityNodeRFC7540) { } } -func (n *priorityNodeRFC7540) addBytes(b int64) { +func (n *priorityNode) addBytes(b int64) { n.bytes += b for ; n != nil; n = n.parent { n.subtreeBytes += b @@ -154,7 +154,7 @@ func (n *priorityNodeRFC7540) addBytes(b int64) { // // f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true // if any ancestor p of n is still open (ignoring the root node). -func (n *priorityNodeRFC7540) walkReadyInOrder(openParent bool, tmp *[]*priorityNodeRFC7540, f func(*priorityNodeRFC7540, bool) bool) bool { +func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f func(*priorityNode, bool) bool) bool { if !n.q.empty() && f(n, openParent) { return true } @@ -165,7 +165,7 @@ func (n *priorityNodeRFC7540) walkReadyInOrder(openParent bool, tmp *[]*priority // Don't consider the root "open" when updating openParent since // we can't send data frames on the root stream (only control frames). if n.id != 0 { - openParent = openParent || (n.state == priorityNodeOpenRFC7540) + openParent = openParent || (n.state == priorityNodeOpen) } // Common case: only one kid or all kids have the same weight. @@ -195,7 +195,7 @@ func (n *priorityNodeRFC7540) walkReadyInOrder(openParent bool, tmp *[]*priority *tmp = append(*tmp, n.kids) n.kids.setParent(nil) } - sort.Sort(sortPriorityNodeSiblingsRFC7540(*tmp)) + sort.Sort(sortPriorityNodeSiblings(*tmp)) for i := len(*tmp) - 1; i >= 0; i-- { (*tmp)[i].setParent(n) // setParent inserts at the head of n.kids } @@ -207,15 +207,15 @@ func (n *priorityNodeRFC7540) walkReadyInOrder(openParent bool, tmp *[]*priority return false } -type sortPriorityNodeSiblingsRFC7540 []*priorityNodeRFC7540 +type sortPriorityNodeSiblings []*priorityNode -func (z sortPriorityNodeSiblingsRFC7540) Len() int { return len(z) } -func (z sortPriorityNodeSiblingsRFC7540) Swap(i, k int) { z[i], z[k] = z[k], z[i] } -func (z sortPriorityNodeSiblingsRFC7540) Less(i, k int) bool { +func (z sortPriorityNodeSiblings) Len() int { return len(z) } +func (z sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] } +func (z sortPriorityNodeSiblings) Less(i, k int) bool { // Prefer the subtree that has sent fewer bytes relative to its weight. // See sections 5.3.2 and 5.3.4. - wi, bi := float64(z[i].weight)+1, float64(z[i].subtreeBytes) - wk, bk := float64(z[k].weight)+1, float64(z[k].subtreeBytes) + wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes) + wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes) if bi == 0 && bk == 0 { return wi >= wk } @@ -225,13 +225,13 @@ func (z sortPriorityNodeSiblingsRFC7540) Less(i, k int) bool { return bi/bk <= wi/wk } -type priorityWriteSchedulerRFC7540 struct { +type priorityWriteScheduler struct { // root is the root of the priority tree, where root.id = 0. // The root queues control frames that are not associated with any stream. - root priorityNodeRFC7540 + root priorityNode // nodes maps stream ids to priority tree nodes. - nodes map[uint32]*priorityNodeRFC7540 + nodes map[uint32]*priorityNode // maxID is the maximum stream id in nodes. maxID uint32 @@ -239,7 +239,7 @@ type priorityWriteSchedulerRFC7540 struct { // lists of nodes that have been closed or are idle, but are kept in // the tree for improved prioritization. When the lengths exceed either // maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded. - closedNodes, idleNodes []*priorityNodeRFC7540 + closedNodes, idleNodes []*priorityNode // From the config. maxClosedNodesInTree int @@ -248,19 +248,19 @@ type priorityWriteSchedulerRFC7540 struct { enableWriteThrottle bool // tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations. - tmp []*priorityNodeRFC7540 + tmp []*priorityNode // pool of empty queues for reuse. queuePool writeQueuePool } -func (ws *priorityWriteSchedulerRFC7540) OpenStream(streamID uint32, options OpenStreamOptions) { +func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) { // The stream may be currently idle but cannot be opened or closed. if curr := ws.nodes[streamID]; curr != nil { - if curr.state != priorityNodeIdleRFC7540 { + if curr.state != priorityNodeIdle { panic(fmt.Sprintf("stream %d already opened", streamID)) } - curr.state = priorityNodeOpenRFC7540 + curr.state = priorityNodeOpen return } @@ -272,11 +272,11 @@ func (ws *priorityWriteSchedulerRFC7540) OpenStream(streamID uint32, options Ope if parent == nil { parent = &ws.root } - n := &priorityNodeRFC7540{ + n := &priorityNode{ q: *ws.queuePool.get(), id: streamID, - weight: priorityDefaultWeightRFC7540, - state: priorityNodeOpenRFC7540, + weight: priorityDefaultWeight, + state: priorityNodeOpen, } n.setParent(parent) ws.nodes[streamID] = n @@ -285,23 +285,24 @@ func (ws *priorityWriteSchedulerRFC7540) OpenStream(streamID uint32, options Ope } } -func (ws *priorityWriteSchedulerRFC7540) CloseStream(streamID uint32) { +func (ws *priorityWriteScheduler) CloseStream(streamID uint32) { if streamID == 0 { panic("violation of WriteScheduler interface: cannot close stream 0") } if ws.nodes[streamID] == nil { panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID)) } - if ws.nodes[streamID].state != priorityNodeOpenRFC7540 { + if ws.nodes[streamID].state != priorityNodeOpen { panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID)) } n := ws.nodes[streamID] - n.state = priorityNodeClosedRFC7540 + n.state = priorityNodeClosed n.addBytes(-n.bytes) q := n.q ws.queuePool.put(&q) + n.q.s = nil if ws.maxClosedNodesInTree > 0 { ws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n) } else { @@ -309,7 +310,7 @@ func (ws *priorityWriteSchedulerRFC7540) CloseStream(streamID uint32) { } } -func (ws *priorityWriteSchedulerRFC7540) AdjustStream(streamID uint32, priority PriorityParam) { +func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) { if streamID == 0 { panic("adjustPriority on root") } @@ -323,11 +324,11 @@ func (ws *priorityWriteSchedulerRFC7540) AdjustStream(streamID uint32, priority return } ws.maxID = streamID - n = &priorityNodeRFC7540{ + n = &priorityNode{ q: *ws.queuePool.get(), id: streamID, - weight: priorityDefaultWeightRFC7540, - state: priorityNodeIdleRFC7540, + weight: priorityDefaultWeight, + state: priorityNodeIdle, } n.setParent(&ws.root) ws.nodes[streamID] = n @@ -339,7 +340,7 @@ func (ws *priorityWriteSchedulerRFC7540) AdjustStream(streamID uint32, priority parent := ws.nodes[priority.StreamDep] if parent == nil { n.setParent(&ws.root) - n.weight = priorityDefaultWeightRFC7540 + n.weight = priorityDefaultWeight return } @@ -380,8 +381,8 @@ func (ws *priorityWriteSchedulerRFC7540) AdjustStream(streamID uint32, priority n.weight = priority.Weight } -func (ws *priorityWriteSchedulerRFC7540) Push(wr FrameWriteRequest) { - var n *priorityNodeRFC7540 +func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) { + var n *priorityNode if wr.isControl() { n = &ws.root } else { @@ -400,8 +401,8 @@ func (ws *priorityWriteSchedulerRFC7540) Push(wr FrameWriteRequest) { n.q.push(wr) } -func (ws *priorityWriteSchedulerRFC7540) Pop() (wr FrameWriteRequest, ok bool) { - ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNodeRFC7540, openParent bool) bool { +func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) { + ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNode, openParent bool) bool { limit := int32(math.MaxInt32) if openParent { limit = ws.writeThrottleLimit @@ -427,7 +428,7 @@ func (ws *priorityWriteSchedulerRFC7540) Pop() (wr FrameWriteRequest, ok bool) { return wr, ok } -func (ws *priorityWriteSchedulerRFC7540) addClosedOrIdleNode(list *[]*priorityNodeRFC7540, maxSize int, n *priorityNodeRFC7540) { +func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, maxSize int, n *priorityNode) { if maxSize == 0 { return } @@ -441,7 +442,7 @@ func (ws *priorityWriteSchedulerRFC7540) addClosedOrIdleNode(list *[]*priorityNo *list = append(*list, n) } -func (ws *priorityWriteSchedulerRFC7540) removeNode(n *priorityNodeRFC7540) { +func (ws *priorityWriteScheduler) removeNode(n *priorityNode) { for n.kids != nil { n.kids.setParent(n.parent) } diff --git a/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go b/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go deleted file mode 100644 index cb4cadc32d79..000000000000 --- a/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright 2025 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http2 - -import ( - "fmt" - "math" -) - -type streamMetadata struct { - location *writeQueue - priority PriorityParam -} - -type priorityWriteSchedulerRFC9218 struct { - // control contains control frames (SETTINGS, PING, etc.). - control writeQueue - - // heads contain the head of a circular list of streams. - // We put these heads within a nested array that represents urgency and - // incremental, as defined in - // https://www.rfc-editor.org/rfc/rfc9218.html#name-priority-parameters. - // 8 represents u=0 up to u=7, and 2 represents i=false and i=true. - heads [8][2]*writeQueue - - // streams contains a mapping between each stream ID and their metadata, so - // we can quickly locate them when needing to, for example, adjust their - // priority. - streams map[uint32]streamMetadata - - // queuePool are empty queues for reuse. - queuePool writeQueuePool - - // prioritizeIncremental is used to determine whether we should prioritize - // incremental streams or not, when urgency is the same in a given Pop() - // call. - prioritizeIncremental bool -} - -func newPriorityWriteSchedulerRFC9218() WriteScheduler { - ws := &priorityWriteSchedulerRFC9218{ - streams: make(map[uint32]streamMetadata), - } - return ws -} - -func (ws *priorityWriteSchedulerRFC9218) OpenStream(streamID uint32, opt OpenStreamOptions) { - if ws.streams[streamID].location != nil { - panic(fmt.Errorf("stream %d already opened", streamID)) - } - q := ws.queuePool.get() - ws.streams[streamID] = streamMetadata{ - location: q, - priority: opt.priority, - } - - u, i := opt.priority.urgency, opt.priority.incremental - if ws.heads[u][i] == nil { - ws.heads[u][i] = q - q.next = q - q.prev = q - } else { - // Queues are stored in a ring. - // Insert the new stream before ws.head, putting it at the end of the list. - q.prev = ws.heads[u][i].prev - q.next = ws.heads[u][i] - q.prev.next = q - q.next.prev = q - } -} - -func (ws *priorityWriteSchedulerRFC9218) CloseStream(streamID uint32) { - metadata := ws.streams[streamID] - q, u, i := metadata.location, metadata.priority.urgency, metadata.priority.incremental - if q == nil { - return - } - if q.next == q { - // This was the only open stream. - ws.heads[u][i] = nil - } else { - q.prev.next = q.next - q.next.prev = q.prev - if ws.heads[u][i] == q { - ws.heads[u][i] = q.next - } - } - delete(ws.streams, streamID) - ws.queuePool.put(q) -} - -func (ws *priorityWriteSchedulerRFC9218) AdjustStream(streamID uint32, priority PriorityParam) { - metadata := ws.streams[streamID] - q, u, i := metadata.location, metadata.priority.urgency, metadata.priority.incremental - if q == nil { - return - } - - // Remove stream from current location. - if q.next == q { - // This was the only open stream. - ws.heads[u][i] = nil - } else { - q.prev.next = q.next - q.next.prev = q.prev - if ws.heads[u][i] == q { - ws.heads[u][i] = q.next - } - } - - // Insert stream to the new queue. - u, i = priority.urgency, priority.incremental - if ws.heads[u][i] == nil { - ws.heads[u][i] = q - q.next = q - q.prev = q - } else { - // Queues are stored in a ring. - // Insert the new stream before ws.head, putting it at the end of the list. - q.prev = ws.heads[u][i].prev - q.next = ws.heads[u][i] - q.prev.next = q - q.next.prev = q - } - - // Update the metadata. - ws.streams[streamID] = streamMetadata{ - location: q, - priority: priority, - } -} - -func (ws *priorityWriteSchedulerRFC9218) Push(wr FrameWriteRequest) { - if wr.isControl() { - ws.control.push(wr) - return - } - q := ws.streams[wr.StreamID()].location - if q == nil { - // This is a closed stream. - // wr should not be a HEADERS or DATA frame. - // We push the request onto the control queue. - if wr.DataSize() > 0 { - panic("add DATA on non-open stream") - } - ws.control.push(wr) - return - } - q.push(wr) -} - -func (ws *priorityWriteSchedulerRFC9218) Pop() (FrameWriteRequest, bool) { - // Control and RST_STREAM frames first. - if !ws.control.empty() { - return ws.control.shift(), true - } - - // On the next Pop(), we want to prioritize incremental if we prioritized - // non-incremental request of the same urgency this time. Vice-versa. - // i.e. when there are incremental and non-incremental requests at the same - // priority, we give 50% of our bandwidth to the incremental ones in - // aggregate and 50% to the first non-incremental one (since - // non-incremental streams do not use round-robin writes). - ws.prioritizeIncremental = !ws.prioritizeIncremental - - // Always prioritize lowest u (i.e. highest urgency level). - for u := range ws.heads { - for i := range ws.heads[u] { - // When we want to prioritize incremental, we try to pop i=true - // first before i=false when u is the same. - if ws.prioritizeIncremental { - i = (i + 1) % 2 - } - q := ws.heads[u][i] - if q == nil { - continue - } - for { - if wr, ok := q.consume(math.MaxInt32); ok { - if i == 1 { - // For incremental streams, we update head to q.next so - // we can round-robin between multiple streams that can - // immediately benefit from partial writes. - ws.heads[u][i] = q.next - } else { - // For non-incremental streams, we try to finish one to - // completion rather than doing round-robin. However, - // we update head here so that if q.consume() is !ok - // (e.g. the stream has no more frame to consume), head - // is updated to the next q that has frames to consume - // on future iterations. This way, we do not prioritize - // writing to unavailable stream on next Pop() calls, - // preventing head-of-line blocking. - ws.heads[u][i] = q - } - return wr, true - } - q = q.next - if q == ws.heads[u][i] { - break - } - } - - } - } - return FrameWriteRequest{}, false -} diff --git a/vendor/golang.org/x/net/http2/writesched_roundrobin.go b/vendor/golang.org/x/net/http2/writesched_roundrobin.go index 737cff9ecbd8..54fe86322d2f 100644 --- a/vendor/golang.org/x/net/http2/writesched_roundrobin.go +++ b/vendor/golang.org/x/net/http2/writesched_roundrobin.go @@ -25,7 +25,7 @@ type roundRobinWriteScheduler struct { } // newRoundRobinWriteScheduler constructs a new write scheduler. -// The round robin scheduler prioritizes control frames +// The round robin scheduler priorizes control frames // like SETTINGS and PING over DATA frames. // When there are no control frames to send, it performs a round-robin // selection from the ready streams. diff --git a/vendor/golang.org/x/net/internal/httpcommon/request.go b/vendor/golang.org/x/net/internal/httpcommon/request.go index 1e10f89ebf71..4b705531793c 100644 --- a/vendor/golang.org/x/net/internal/httpcommon/request.go +++ b/vendor/golang.org/x/net/internal/httpcommon/request.go @@ -51,7 +51,7 @@ type EncodeHeadersParam struct { DefaultUserAgent string } -// EncodeHeadersResult is the result of EncodeHeaders. +// EncodeHeadersParam is the result of EncodeHeaders. type EncodeHeadersResult struct { HasBody bool HasTrailers bool @@ -399,7 +399,7 @@ type ServerRequestResult struct { // If the request should be rejected, this is a short string suitable for passing // to the http2 package's CountError function. - // It might be a bit odd to return errors this way rather than returning an error, + // It might be a bit odd to return errors this way rather than returing an error, // but this ensures we don't forget to include a CountError reason. InvalidReason string } diff --git a/vendor/golang.org/x/net/internal/socks/socks.go b/vendor/golang.org/x/net/internal/socks/socks.go index 8eedb84cecc5..84fcc32b634b 100644 --- a/vendor/golang.org/x/net/internal/socks/socks.go +++ b/vendor/golang.org/x/net/internal/socks/socks.go @@ -297,7 +297,7 @@ func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, b = append(b, up.Username...) b = append(b, byte(len(up.Password))) b = append(b, up.Password...) - // TODO(mikio): handle IO deadlines and cancellation if + // TODO(mikio): handle IO deadlines and cancelation if // necessary if _, err := rw.Write(b); err != nil { return err diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index 2f45dbc86e53..1d8cffae8cfc 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Package errgroup provides synchronization, error propagation, and Context -// cancellation for groups of goroutines working on subtasks of a common task. +// cancelation for groups of goroutines working on subtasks of a common task. // // [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks // returning errors. diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go index 34c9ae76efd4..63541994ef03 100644 --- a/vendor/golang.org/x/sys/cpu/cpu.go +++ b/vendor/golang.org/x/sys/cpu/cpu.go @@ -92,9 +92,6 @@ var ARM64 struct { HasSHA2 bool // SHA2 hardware implementation HasCRC32 bool // CRC32 hardware implementation HasATOMICS bool // Atomic memory operation instruction set - HasHPDS bool // Hierarchical permission disables in translations tables - HasLOR bool // Limited ordering regions - HasPAN bool // Privileged access never HasFPHP bool // Half precision floating-point instruction set HasASIMDHP bool // Advanced SIMD half precision instruction set HasCPUID bool // CPUID identification scheme registers diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_arm64.go index f449c679fe46..af2aa99f9f06 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.go @@ -65,10 +65,10 @@ func setMinimalFeatures() { func readARM64Registers() { Initialized = true - parseARM64SystemRegisters(getisar0(), getisar1(), getmmfr1(), getpfr0()) + parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0()) } -func parseARM64SystemRegisters(isar0, isar1, mmfr1, pfr0 uint64) { +func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) { // ID_AA64ISAR0_EL1 switch extractBits(isar0, 4, 7) { case 1: @@ -152,22 +152,6 @@ func parseARM64SystemRegisters(isar0, isar1, mmfr1, pfr0 uint64) { ARM64.HasI8MM = true } - // ID_AA64MMFR1_EL1 - switch extractBits(mmfr1, 12, 15) { - case 1, 2: - ARM64.HasHPDS = true - } - - switch extractBits(mmfr1, 16, 19) { - case 1: - ARM64.HasLOR = true - } - - switch extractBits(mmfr1, 20, 23) { - case 1, 2, 3: - ARM64.HasPAN = true - } - // ID_AA64PFR0_EL1 switch extractBits(pfr0, 16, 19) { case 0: diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.s b/vendor/golang.org/x/sys/cpu/cpu_arm64.s index a4f24b3b0c8f..22cc99844a75 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_arm64.s +++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.s @@ -9,34 +9,31 @@ // func getisar0() uint64 TEXT ·getisar0(SB),NOSPLIT,$0-8 // get Instruction Set Attributes 0 into x0 - MRS ID_AA64ISAR0_EL1, R0 + // mrs x0, ID_AA64ISAR0_EL1 = d5380600 + WORD $0xd5380600 MOVD R0, ret+0(FP) RET // func getisar1() uint64 TEXT ·getisar1(SB),NOSPLIT,$0-8 // get Instruction Set Attributes 1 into x0 - MRS ID_AA64ISAR1_EL1, R0 - MOVD R0, ret+0(FP) - RET - -// func getmmfr1() uint64 -TEXT ·getmmfr1(SB),NOSPLIT,$0-8 - // get Memory Model Feature Register 1 into x0 - MRS ID_AA64MMFR1_EL1, R0 + // mrs x0, ID_AA64ISAR1_EL1 = d5380620 + WORD $0xd5380620 MOVD R0, ret+0(FP) RET // func getpfr0() uint64 TEXT ·getpfr0(SB),NOSPLIT,$0-8 // get Processor Feature Register 0 into x0 - MRS ID_AA64PFR0_EL1, R0 + // mrs x0, ID_AA64PFR0_EL1 = d5380400 + WORD $0xd5380400 MOVD R0, ret+0(FP) RET // func getzfr0() uint64 TEXT ·getzfr0(SB),NOSPLIT,$0-8 // get SVE Feature Register 0 into x0 - MRS ID_AA64ZFR0_EL1, R0 + // mrs x0, ID_AA64ZFR0_EL1 = d5380480 + WORD $0xd5380480 MOVD R0, ret+0(FP) RET diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go index e3fc5a8d31ca..6ac6e1efb208 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go @@ -8,6 +8,5 @@ package cpu func getisar0() uint64 func getisar1() uint64 -func getmmfr1() uint64 func getpfr0() uint64 func getzfr0() uint64 diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go index 8df2079e15f9..7f1946780bd3 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go @@ -8,5 +8,4 @@ package cpu func getisar0() uint64 { return 0 } func getisar1() uint64 { return 0 } -func getmmfr1() uint64 { return 0 } func getpfr0() uint64 { return 0 } diff --git a/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go index 19aea0633e8e..ebfb3fc8e76d 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go @@ -167,7 +167,7 @@ func doinit() { setMinimalFeatures() return } - parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64mmfr1, cpuid.aa64pfr0) + parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0) Initialized = true } diff --git a/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go index 87fd3a778076..85b64d5ccb73 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go @@ -59,7 +59,7 @@ func doinit() { if !ok { return } - parseARM64SystemRegisters(isar0, isar1, 0, 0) + parseARM64SystemRegisters(isar0, isar1, 0) Initialized = true } diff --git a/vendor/golang.org/x/sys/unix/affinity_linux.go b/vendor/golang.org/x/sys/unix/affinity_linux.go index 3ea470387bcf..3c7a6d6e2f1d 100644 --- a/vendor/golang.org/x/sys/unix/affinity_linux.go +++ b/vendor/golang.org/x/sys/unix/affinity_linux.go @@ -41,15 +41,6 @@ func (s *CPUSet) Zero() { clear(s[:]) } -// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity] -// will silently ignore any invalid CPU bits in [CPUSet] so this is an -// efficient way of resetting the CPU affinity of a process. -func (s *CPUSet) Fill() { - for i := range s { - s[i] = ^cpuMask(0) - } -} - func cpuBitsIndex(cpu int) int { return cpu / _NCPUBITS } diff --git a/vendor/golang.org/x/sys/unix/fdset.go b/vendor/golang.org/x/sys/unix/fdset.go index 62ed12645f48..9e83d18cd042 100644 --- a/vendor/golang.org/x/sys/unix/fdset.go +++ b/vendor/golang.org/x/sys/unix/fdset.go @@ -23,5 +23,7 @@ func (fds *FdSet) IsSet(fd int) bool { // Zero clears the set fds. func (fds *FdSet) Zero() { - clear(fds.Bits[:]) + for i := range fds.Bits { + fds.Bits[i] = 0 + } } diff --git a/vendor/golang.org/x/sys/unix/ifreq_linux.go b/vendor/golang.org/x/sys/unix/ifreq_linux.go index 309f5a2b0c76..848840ae4c75 100644 --- a/vendor/golang.org/x/sys/unix/ifreq_linux.go +++ b/vendor/golang.org/x/sys/unix/ifreq_linux.go @@ -111,7 +111,9 @@ func (ifr *Ifreq) SetUint32(v uint32) { // clear zeroes the ifreq's union field to prevent trailing garbage data from // being sent to the kernel if an ifreq is reused. func (ifr *Ifreq) clear() { - clear(ifr.raw.Ifru[:]) + for i := range ifr.raw.Ifru { + ifr.raw.Ifru[i] = 0 + } } // TODO(mdlayher): export as IfreqData? For now we can provide helpers such as diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh index d0ed61191292..e6f31d374df5 100644 --- a/vendor/golang.org/x/sys/unix/mkall.sh +++ b/vendor/golang.org/x/sys/unix/mkall.sh @@ -49,7 +49,6 @@ esac if [[ "$GOOS" = "linux" ]]; then # Use the Docker-based build system # Files generated through docker (use $cmd so you can Ctl-C the build or run) - set -e $cmd docker build --tag generate:$GOOS $GOOS $cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && pwd):/build generate:$GOOS exit diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 42517077c437..d1c8b2640ebd 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -226,7 +226,6 @@ struct ltchars { #include #include #include -#include #include #include #include @@ -530,7 +529,6 @@ ccflags="$@" $2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ || $2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ || $2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ || - $2 ~ /^(DT|EI|ELF|EV|NN|NT|PF|SHF|SHN|SHT|STB|STT|VER)_/ || $2 ~ /^O?XTABS$/ || $2 ~ /^TC[IO](ON|OFF)$/ || $2 ~ /^IN_/ || diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 06c0eea6fb6a..4958a657085b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -801,7 +801,9 @@ func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) { // one. The kernel expects SID to be in network byte order. binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID) copy(sa.raw[8:14], sa.Remote) - clear(sa.raw[14 : 14+IFNAMSIZ]) + for i := 14; i < 14+IFNAMSIZ; i++ { + sa.raw[i] = 0 + } copy(sa.raw[14:], sa.Dev) return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil } @@ -2643,9 +2645,3 @@ func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) { //sys Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error) //sys Mseal(b []byte, flags uint) (err error) - -//sys setMemPolicy(mode int, mask *CPUSet, size int) (err error) = SYS_SET_MEMPOLICY - -func SetMemPolicy(mode int, mask *CPUSet) error { - return setMemPolicy(mode, mask, _CPU_SETSIZE) -} diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go index 34a467697304..88162099af54 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -248,23 +248,6 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { return Statvfs1(path, buf, ST_WAIT) } -func Getvfsstat(buf []Statvfs_t, flags int) (n int, err error) { - var ( - _p0 unsafe.Pointer - bufsize uintptr - ) - if len(buf) > 0 { - _p0 = unsafe.Pointer(&buf[0]) - bufsize = unsafe.Sizeof(Statvfs_t{}) * uintptr(len(buf)) - } - r0, _, e1 := Syscall(SYS_GETVFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = e1 - } - return -} - /* * Exposed directly */ diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index d0a75da572c9..b6db27d937c8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -853,86 +853,20 @@ const ( DM_VERSION_MAJOR = 0x4 DM_VERSION_MINOR = 0x32 DM_VERSION_PATCHLEVEL = 0x0 - DT_ADDRRNGHI = 0x6ffffeff - DT_ADDRRNGLO = 0x6ffffe00 DT_BLK = 0x6 DT_CHR = 0x2 - DT_DEBUG = 0x15 DT_DIR = 0x4 - DT_ENCODING = 0x20 DT_FIFO = 0x1 - DT_FINI = 0xd - DT_FLAGS_1 = 0x6ffffffb - DT_GNU_HASH = 0x6ffffef5 - DT_HASH = 0x4 - DT_HIOS = 0x6ffff000 - DT_HIPROC = 0x7fffffff - DT_INIT = 0xc - DT_JMPREL = 0x17 DT_LNK = 0xa - DT_LOOS = 0x6000000d - DT_LOPROC = 0x70000000 - DT_NEEDED = 0x1 - DT_NULL = 0x0 - DT_PLTGOT = 0x3 - DT_PLTREL = 0x14 - DT_PLTRELSZ = 0x2 DT_REG = 0x8 - DT_REL = 0x11 - DT_RELA = 0x7 - DT_RELACOUNT = 0x6ffffff9 - DT_RELAENT = 0x9 - DT_RELASZ = 0x8 - DT_RELCOUNT = 0x6ffffffa - DT_RELENT = 0x13 - DT_RELSZ = 0x12 - DT_RPATH = 0xf DT_SOCK = 0xc - DT_SONAME = 0xe - DT_STRSZ = 0xa - DT_STRTAB = 0x5 - DT_SYMBOLIC = 0x10 - DT_SYMENT = 0xb - DT_SYMTAB = 0x6 - DT_TEXTREL = 0x16 DT_UNKNOWN = 0x0 - DT_VALRNGHI = 0x6ffffdff - DT_VALRNGLO = 0x6ffffd00 - DT_VERDEF = 0x6ffffffc - DT_VERDEFNUM = 0x6ffffffd - DT_VERNEED = 0x6ffffffe - DT_VERNEEDNUM = 0x6fffffff - DT_VERSYM = 0x6ffffff0 DT_WHT = 0xe ECHO = 0x8 ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_SEMAPHORE = 0x1 EFIVARFS_MAGIC = 0xde5e81e4 EFS_SUPER_MAGIC = 0x414a53 - EI_CLASS = 0x4 - EI_DATA = 0x5 - EI_MAG0 = 0x0 - EI_MAG1 = 0x1 - EI_MAG2 = 0x2 - EI_MAG3 = 0x3 - EI_NIDENT = 0x10 - EI_OSABI = 0x7 - EI_PAD = 0x8 - EI_VERSION = 0x6 - ELFCLASS32 = 0x1 - ELFCLASS64 = 0x2 - ELFCLASSNONE = 0x0 - ELFCLASSNUM = 0x3 - ELFDATA2LSB = 0x1 - ELFDATA2MSB = 0x2 - ELFDATANONE = 0x0 - ELFMAG = "\177ELF" - ELFMAG0 = 0x7f - ELFMAG1 = 'E' - ELFMAG2 = 'L' - ELFMAG3 = 'F' - ELFOSABI_LINUX = 0x3 - ELFOSABI_NONE = 0x0 EM_386 = 0x3 EM_486 = 0x6 EM_68K = 0x4 @@ -1218,24 +1152,14 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 - ET_CORE = 0x4 - ET_DYN = 0x3 - ET_EXEC = 0x2 - ET_HIPROC = 0xffff - ET_LOPROC = 0xff00 - ET_NONE = 0x0 - ET_REL = 0x1 EV_ABS = 0x3 EV_CNT = 0x20 - EV_CURRENT = 0x1 EV_FF = 0x15 EV_FF_STATUS = 0x17 EV_KEY = 0x1 EV_LED = 0x11 EV_MAX = 0x1f EV_MSC = 0x4 - EV_NONE = 0x0 - EV_NUM = 0x2 EV_PWR = 0x16 EV_REL = 0x2 EV_REP = 0x14 @@ -2352,167 +2276,7 @@ const ( NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 - NN_386_IOPERM = "LINUX" - NN_386_TLS = "LINUX" - NN_ARC_V2 = "LINUX" - NN_ARM_FPMR = "LINUX" - NN_ARM_GCS = "LINUX" - NN_ARM_HW_BREAK = "LINUX" - NN_ARM_HW_WATCH = "LINUX" - NN_ARM_PACA_KEYS = "LINUX" - NN_ARM_PACG_KEYS = "LINUX" - NN_ARM_PAC_ENABLED_KEYS = "LINUX" - NN_ARM_PAC_MASK = "LINUX" - NN_ARM_POE = "LINUX" - NN_ARM_SSVE = "LINUX" - NN_ARM_SVE = "LINUX" - NN_ARM_SYSTEM_CALL = "LINUX" - NN_ARM_TAGGED_ADDR_CTRL = "LINUX" - NN_ARM_TLS = "LINUX" - NN_ARM_VFP = "LINUX" - NN_ARM_ZA = "LINUX" - NN_ARM_ZT = "LINUX" - NN_AUXV = "CORE" - NN_FILE = "CORE" - NN_GNU_PROPERTY_TYPE_0 = "GNU" - NN_LOONGARCH_CPUCFG = "LINUX" - NN_LOONGARCH_CSR = "LINUX" - NN_LOONGARCH_HW_BREAK = "LINUX" - NN_LOONGARCH_HW_WATCH = "LINUX" - NN_LOONGARCH_LASX = "LINUX" - NN_LOONGARCH_LBT = "LINUX" - NN_LOONGARCH_LSX = "LINUX" - NN_MIPS_DSP = "LINUX" - NN_MIPS_FP_MODE = "LINUX" - NN_MIPS_MSA = "LINUX" - NN_PPC_DEXCR = "LINUX" - NN_PPC_DSCR = "LINUX" - NN_PPC_EBB = "LINUX" - NN_PPC_HASHKEYR = "LINUX" - NN_PPC_PKEY = "LINUX" - NN_PPC_PMU = "LINUX" - NN_PPC_PPR = "LINUX" - NN_PPC_SPE = "LINUX" - NN_PPC_TAR = "LINUX" - NN_PPC_TM_CDSCR = "LINUX" - NN_PPC_TM_CFPR = "LINUX" - NN_PPC_TM_CGPR = "LINUX" - NN_PPC_TM_CPPR = "LINUX" - NN_PPC_TM_CTAR = "LINUX" - NN_PPC_TM_CVMX = "LINUX" - NN_PPC_TM_CVSX = "LINUX" - NN_PPC_TM_SPR = "LINUX" - NN_PPC_VMX = "LINUX" - NN_PPC_VSX = "LINUX" - NN_PRFPREG = "CORE" - NN_PRPSINFO = "CORE" - NN_PRSTATUS = "CORE" - NN_PRXFPREG = "LINUX" - NN_RISCV_CSR = "LINUX" - NN_RISCV_TAGGED_ADDR_CTRL = "LINUX" - NN_RISCV_VECTOR = "LINUX" - NN_S390_CTRS = "LINUX" - NN_S390_GS_BC = "LINUX" - NN_S390_GS_CB = "LINUX" - NN_S390_HIGH_GPRS = "LINUX" - NN_S390_LAST_BREAK = "LINUX" - NN_S390_PREFIX = "LINUX" - NN_S390_PV_CPU_DATA = "LINUX" - NN_S390_RI_CB = "LINUX" - NN_S390_SYSTEM_CALL = "LINUX" - NN_S390_TDB = "LINUX" - NN_S390_TIMER = "LINUX" - NN_S390_TODCMP = "LINUX" - NN_S390_TODPREG = "LINUX" - NN_S390_VXRS_HIGH = "LINUX" - NN_S390_VXRS_LOW = "LINUX" - NN_SIGINFO = "CORE" - NN_TASKSTRUCT = "CORE" - NN_VMCOREDD = "LINUX" - NN_X86_SHSTK = "LINUX" - NN_X86_XSAVE_LAYOUT = "LINUX" - NN_X86_XSTATE = "LINUX" NSFS_MAGIC = 0x6e736673 - NT_386_IOPERM = 0x201 - NT_386_TLS = 0x200 - NT_ARC_V2 = 0x600 - NT_ARM_FPMR = 0x40e - NT_ARM_GCS = 0x410 - NT_ARM_HW_BREAK = 0x402 - NT_ARM_HW_WATCH = 0x403 - NT_ARM_PACA_KEYS = 0x407 - NT_ARM_PACG_KEYS = 0x408 - NT_ARM_PAC_ENABLED_KEYS = 0x40a - NT_ARM_PAC_MASK = 0x406 - NT_ARM_POE = 0x40f - NT_ARM_SSVE = 0x40b - NT_ARM_SVE = 0x405 - NT_ARM_SYSTEM_CALL = 0x404 - NT_ARM_TAGGED_ADDR_CTRL = 0x409 - NT_ARM_TLS = 0x401 - NT_ARM_VFP = 0x400 - NT_ARM_ZA = 0x40c - NT_ARM_ZT = 0x40d - NT_AUXV = 0x6 - NT_FILE = 0x46494c45 - NT_GNU_PROPERTY_TYPE_0 = 0x5 - NT_LOONGARCH_CPUCFG = 0xa00 - NT_LOONGARCH_CSR = 0xa01 - NT_LOONGARCH_HW_BREAK = 0xa05 - NT_LOONGARCH_HW_WATCH = 0xa06 - NT_LOONGARCH_LASX = 0xa03 - NT_LOONGARCH_LBT = 0xa04 - NT_LOONGARCH_LSX = 0xa02 - NT_MIPS_DSP = 0x800 - NT_MIPS_FP_MODE = 0x801 - NT_MIPS_MSA = 0x802 - NT_PPC_DEXCR = 0x111 - NT_PPC_DSCR = 0x105 - NT_PPC_EBB = 0x106 - NT_PPC_HASHKEYR = 0x112 - NT_PPC_PKEY = 0x110 - NT_PPC_PMU = 0x107 - NT_PPC_PPR = 0x104 - NT_PPC_SPE = 0x101 - NT_PPC_TAR = 0x103 - NT_PPC_TM_CDSCR = 0x10f - NT_PPC_TM_CFPR = 0x109 - NT_PPC_TM_CGPR = 0x108 - NT_PPC_TM_CPPR = 0x10e - NT_PPC_TM_CTAR = 0x10d - NT_PPC_TM_CVMX = 0x10a - NT_PPC_TM_CVSX = 0x10b - NT_PPC_TM_SPR = 0x10c - NT_PPC_VMX = 0x100 - NT_PPC_VSX = 0x102 - NT_PRFPREG = 0x2 - NT_PRPSINFO = 0x3 - NT_PRSTATUS = 0x1 - NT_PRXFPREG = 0x46e62b7f - NT_RISCV_CSR = 0x900 - NT_RISCV_TAGGED_ADDR_CTRL = 0x902 - NT_RISCV_VECTOR = 0x901 - NT_S390_CTRS = 0x304 - NT_S390_GS_BC = 0x30c - NT_S390_GS_CB = 0x30b - NT_S390_HIGH_GPRS = 0x300 - NT_S390_LAST_BREAK = 0x306 - NT_S390_PREFIX = 0x305 - NT_S390_PV_CPU_DATA = 0x30e - NT_S390_RI_CB = 0x30d - NT_S390_SYSTEM_CALL = 0x307 - NT_S390_TDB = 0x308 - NT_S390_TIMER = 0x301 - NT_S390_TODCMP = 0x302 - NT_S390_TODPREG = 0x303 - NT_S390_VXRS_HIGH = 0x30a - NT_S390_VXRS_LOW = 0x309 - NT_SIGINFO = 0x53494749 - NT_TASKSTRUCT = 0x4 - NT_VMCOREDD = 0x700 - NT_X86_SHSTK = 0x204 - NT_X86_XSAVE_LAYOUT = 0x205 - NT_X86_XSTATE = 0x202 OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 @@ -2699,59 +2463,6 @@ const ( PERF_RECORD_MISC_USER = 0x2 PERF_SAMPLE_BRANCH_PLM_ALL = 0x7 PERF_SAMPLE_WEIGHT_TYPE = 0x1004000 - PF_ALG = 0x26 - PF_APPLETALK = 0x5 - PF_ASH = 0x12 - PF_ATMPVC = 0x8 - PF_ATMSVC = 0x14 - PF_AX25 = 0x3 - PF_BLUETOOTH = 0x1f - PF_BRIDGE = 0x7 - PF_CAIF = 0x25 - PF_CAN = 0x1d - PF_DECnet = 0xc - PF_ECONET = 0x13 - PF_FILE = 0x1 - PF_IB = 0x1b - PF_IEEE802154 = 0x24 - PF_INET = 0x2 - PF_INET6 = 0xa - PF_IPX = 0x4 - PF_IRDA = 0x17 - PF_ISDN = 0x22 - PF_IUCV = 0x20 - PF_KCM = 0x29 - PF_KEY = 0xf - PF_LLC = 0x1a - PF_LOCAL = 0x1 - PF_MAX = 0x2e - PF_MCTP = 0x2d - PF_MPLS = 0x1c - PF_NETBEUI = 0xd - PF_NETLINK = 0x10 - PF_NETROM = 0x6 - PF_NFC = 0x27 - PF_PACKET = 0x11 - PF_PHONET = 0x23 - PF_PPPOX = 0x18 - PF_QIPCRTR = 0x2a - PF_R = 0x4 - PF_RDS = 0x15 - PF_ROSE = 0xb - PF_ROUTE = 0x10 - PF_RXRPC = 0x21 - PF_SECURITY = 0xe - PF_SMC = 0x2b - PF_SNA = 0x16 - PF_TIPC = 0x1e - PF_UNIX = 0x1 - PF_UNSPEC = 0x0 - PF_VSOCK = 0x28 - PF_W = 0x2 - PF_WANPIPE = 0x19 - PF_X = 0x1 - PF_X25 = 0x9 - PF_XDP = 0x2c PID_FS_MAGIC = 0x50494446 PIPEFS_MAGIC = 0x50495045 PPPIOCGNPMODE = 0xc008744c @@ -3047,23 +2758,6 @@ const ( PTRACE_SYSCALL_INFO_NONE = 0x0 PTRACE_SYSCALL_INFO_SECCOMP = 0x3 PTRACE_TRACEME = 0x0 - PT_AARCH64_MEMTAG_MTE = 0x70000002 - PT_DYNAMIC = 0x2 - PT_GNU_EH_FRAME = 0x6474e550 - PT_GNU_PROPERTY = 0x6474e553 - PT_GNU_RELRO = 0x6474e552 - PT_GNU_STACK = 0x6474e551 - PT_HIOS = 0x6fffffff - PT_HIPROC = 0x7fffffff - PT_INTERP = 0x3 - PT_LOAD = 0x1 - PT_LOOS = 0x60000000 - PT_LOPROC = 0x70000000 - PT_NOTE = 0x4 - PT_NULL = 0x0 - PT_PHDR = 0x6 - PT_SHLIB = 0x5 - PT_TLS = 0x7 P_ALL = 0x0 P_PGID = 0x2 P_PID = 0x1 @@ -3397,47 +3091,6 @@ const ( SEEK_MAX = 0x4 SEEK_SET = 0x0 SELINUX_MAGIC = 0xf97cff8c - SHF_ALLOC = 0x2 - SHF_EXCLUDE = 0x8000000 - SHF_EXECINSTR = 0x4 - SHF_GROUP = 0x200 - SHF_INFO_LINK = 0x40 - SHF_LINK_ORDER = 0x80 - SHF_MASKOS = 0xff00000 - SHF_MASKPROC = 0xf0000000 - SHF_MERGE = 0x10 - SHF_ORDERED = 0x4000000 - SHF_OS_NONCONFORMING = 0x100 - SHF_RELA_LIVEPATCH = 0x100000 - SHF_RO_AFTER_INIT = 0x200000 - SHF_STRINGS = 0x20 - SHF_TLS = 0x400 - SHF_WRITE = 0x1 - SHN_ABS = 0xfff1 - SHN_COMMON = 0xfff2 - SHN_HIPROC = 0xff1f - SHN_HIRESERVE = 0xffff - SHN_LIVEPATCH = 0xff20 - SHN_LOPROC = 0xff00 - SHN_LORESERVE = 0xff00 - SHN_UNDEF = 0x0 - SHT_DYNAMIC = 0x6 - SHT_DYNSYM = 0xb - SHT_HASH = 0x5 - SHT_HIPROC = 0x7fffffff - SHT_HIUSER = 0xffffffff - SHT_LOPROC = 0x70000000 - SHT_LOUSER = 0x80000000 - SHT_NOBITS = 0x8 - SHT_NOTE = 0x7 - SHT_NULL = 0x0 - SHT_NUM = 0xc - SHT_PROGBITS = 0x1 - SHT_REL = 0x9 - SHT_RELA = 0x4 - SHT_SHLIB = 0xa - SHT_STRTAB = 0x3 - SHT_SYMTAB = 0x2 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -3664,16 +3317,6 @@ const ( STATX_UID = 0x8 STATX_WRITE_ATOMIC = 0x10000 STATX__RESERVED = 0x80000000 - STB_GLOBAL = 0x1 - STB_LOCAL = 0x0 - STB_WEAK = 0x2 - STT_COMMON = 0x5 - STT_FILE = 0x4 - STT_FUNC = 0x2 - STT_NOTYPE = 0x0 - STT_OBJECT = 0x1 - STT_SECTION = 0x3 - STT_TLS = 0x6 SYNC_FILE_RANGE_WAIT_AFTER = 0x4 SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 SYNC_FILE_RANGE_WRITE = 0x2 @@ -3910,8 +3553,6 @@ const ( UTIME_OMIT = 0x3ffffffe V9FS_MAGIC = 0x1021997 VERASE = 0x2 - VER_FLG_BASE = 0x1 - VER_FLG_WEAK = 0x2 VINTR = 0x0 VKILL = 0x3 VLNEXT = 0xf diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 8935d10a31ce..5cc1e8eb2f35 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -2238,13 +2238,3 @@ func Mseal(b []byte, flags uint) (err error) { } return } - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func setMemPolicy(mode int, mask *CPUSet, size int) (err error) { - _, _, e1 := Syscall(SYS_SET_MEMPOLICY, uintptr(mode), uintptr(unsafe.Pointer(mask)), uintptr(size)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index c1a467017198..944e75a11cb1 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -3590,8 +3590,6 @@ type Nhmsg struct { Flags uint32 } -const SizeofNhmsg = 0x8 - type NexthopGrp struct { Id uint32 Weight uint8 @@ -3599,8 +3597,6 @@ type NexthopGrp struct { Resvd2 uint16 } -const SizeofNexthopGrp = 0x8 - const ( NHA_UNSPEC = 0x0 NHA_ID = 0x1 @@ -6336,30 +6332,3 @@ type SockDiagReq struct { } const RTM_NEWNVLAN = 0x70 - -const ( - MPOL_BIND = 0x2 - MPOL_DEFAULT = 0x0 - MPOL_F_ADDR = 0x2 - MPOL_F_MEMS_ALLOWED = 0x4 - MPOL_F_MOF = 0x8 - MPOL_F_MORON = 0x10 - MPOL_F_NODE = 0x1 - MPOL_F_NUMA_BALANCING = 0x2000 - MPOL_F_RELATIVE_NODES = 0x4000 - MPOL_F_SHARED = 0x1 - MPOL_F_STATIC_NODES = 0x8000 - MPOL_INTERLEAVE = 0x3 - MPOL_LOCAL = 0x4 - MPOL_MAX = 0x7 - MPOL_MF_INTERNAL = 0x10 - MPOL_MF_LAZY = 0x8 - MPOL_MF_MOVE_ALL = 0x4 - MPOL_MF_MOVE = 0x2 - MPOL_MF_STRICT = 0x1 - MPOL_MF_VALID = 0x7 - MPOL_MODE_FLAGS = 0xe000 - MPOL_PREFERRED = 0x1 - MPOL_PREFERRED_MANY = 0x5 - MPOL_WEIGHTED_INTERLEAVE = 0x6 -) diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 69439df2a468..640f6b153f00 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -321,8 +321,6 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW -//sys GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) = kernel32.GetNumberOfConsoleInputEvents -//sys FlushConsoleInputBuffer(console Handle) (err error) = kernel32.FlushConsoleInputBuffer //sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole //sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot //sys Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW @@ -892,12 +890,8 @@ const socket_error = uintptr(^uint32(0)) //sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar //sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx //sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex -//sys GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) = iphlpapi.GetIpForwardEntry2 -//sys GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) = iphlpapi.GetIpForwardTable2 //sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry -//sys FreeMibTable(memory unsafe.Pointer) = iphlpapi.FreeMibTable //sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange -//sys NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyRouteChange2 //sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange //sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2 @@ -920,17 +914,6 @@ type RawSockaddrInet6 struct { Scope_id uint32 } -// RawSockaddrInet is a union that contains an IPv4, an IPv6 address, or an address family. See -// https://learn.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-sockaddr_inet. -// -// A [*RawSockaddrInet] may be converted to a [*RawSockaddrInet4] or [*RawSockaddrInet6] using -// unsafe, depending on the address family. -type RawSockaddrInet struct { - Family uint16 - Port uint16 - Data [6]uint32 -} - type RawSockaddr struct { Family uint16 Data [14]int8 diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 6e4f50eb4835..993a2297dbe1 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -65,22 +65,6 @@ var signals = [...]string{ 15: "terminated", } -// File flags for [os.OpenFile]. The O_ prefix is used to indicate -// that these flags are specific to the OpenFile function. -const ( - O_FILE_FLAG_OPEN_NO_RECALL = FILE_FLAG_OPEN_NO_RECALL - O_FILE_FLAG_OPEN_REPARSE_POINT = FILE_FLAG_OPEN_REPARSE_POINT - O_FILE_FLAG_SESSION_AWARE = FILE_FLAG_SESSION_AWARE - O_FILE_FLAG_POSIX_SEMANTICS = FILE_FLAG_POSIX_SEMANTICS - O_FILE_FLAG_BACKUP_SEMANTICS = FILE_FLAG_BACKUP_SEMANTICS - O_FILE_FLAG_DELETE_ON_CLOSE = FILE_FLAG_DELETE_ON_CLOSE - O_FILE_FLAG_SEQUENTIAL_SCAN = FILE_FLAG_SEQUENTIAL_SCAN - O_FILE_FLAG_RANDOM_ACCESS = FILE_FLAG_RANDOM_ACCESS - O_FILE_FLAG_NO_BUFFERING = FILE_FLAG_NO_BUFFERING - O_FILE_FLAG_OVERLAPPED = FILE_FLAG_OVERLAPPED - O_FILE_FLAG_WRITE_THROUGH = FILE_FLAG_WRITE_THROUGH -) - const ( FILE_READ_DATA = 0x00000001 FILE_READ_ATTRIBUTES = 0x00000080 @@ -2320,82 +2304,6 @@ type MibIfRow2 struct { OutQLen uint64 } -// IP_ADDRESS_PREFIX stores an IP address prefix. See -// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-ip_address_prefix. -type IpAddressPrefix struct { - Prefix RawSockaddrInet - PrefixLength uint8 -} - -// NL_ROUTE_ORIGIN enumeration from nldef.h or -// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_origin. -const ( - NlroManual = 0 - NlroWellKnown = 1 - NlroDHCP = 2 - NlroRouterAdvertisement = 3 - Nlro6to4 = 4 -) - -// NL_ROUTE_ORIGIN enumeration from nldef.h or -// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_protocol. -const ( - MIB_IPPROTO_OTHER = 1 - MIB_IPPROTO_LOCAL = 2 - MIB_IPPROTO_NETMGMT = 3 - MIB_IPPROTO_ICMP = 4 - MIB_IPPROTO_EGP = 5 - MIB_IPPROTO_GGP = 6 - MIB_IPPROTO_HELLO = 7 - MIB_IPPROTO_RIP = 8 - MIB_IPPROTO_IS_IS = 9 - MIB_IPPROTO_ES_IS = 10 - MIB_IPPROTO_CISCO = 11 - MIB_IPPROTO_BBN = 12 - MIB_IPPROTO_OSPF = 13 - MIB_IPPROTO_BGP = 14 - MIB_IPPROTO_IDPR = 15 - MIB_IPPROTO_EIGRP = 16 - MIB_IPPROTO_DVMRP = 17 - MIB_IPPROTO_RPL = 18 - MIB_IPPROTO_DHCP = 19 - MIB_IPPROTO_NT_AUTOSTATIC = 10002 - MIB_IPPROTO_NT_STATIC = 10006 - MIB_IPPROTO_NT_STATIC_NON_DOD = 10007 -) - -// MIB_IPFORWARD_ROW2 stores information about an IP route entry. See -// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_row2. -type MibIpForwardRow2 struct { - InterfaceLuid uint64 - InterfaceIndex uint32 - DestinationPrefix IpAddressPrefix - NextHop RawSockaddrInet - SitePrefixLength uint8 - ValidLifetime uint32 - PreferredLifetime uint32 - Metric uint32 - Protocol uint32 - Loopback uint8 - AutoconfigureAddress uint8 - Publish uint8 - Immortal uint8 - Age uint32 - Origin uint32 -} - -// MIB_IPFORWARD_TABLE2 contains a table of IP route entries. See -// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_table2. -type MibIpForwardTable2 struct { - NumEntries uint32 - Table [1]MibIpForwardRow2 -} - -// Rows returns the IP route entries in the table. -func (t *MibIpForwardTable2) Rows() []MibIpForwardRow2 { - return unsafe.Slice(&t.Table[0], t.NumEntries) -} - // MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See // https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row. type MibUnicastIpAddressRow struct { diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index f25b7308a1f3..641a5f4b775a 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -182,17 +182,13 @@ var ( procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute") procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2") - procFreeMibTable = modiphlpapi.NewProc("FreeMibTable") procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx") procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex") - procGetIpForwardEntry2 = modiphlpapi.NewProc("GetIpForwardEntry2") - procGetIpForwardTable2 = modiphlpapi.NewProc("GetIpForwardTable2") procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry") procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange") - procNotifyRouteChange2 = modiphlpapi.NewProc("NotifyRouteChange2") procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange") procAddDllDirectory = modkernel32.NewProc("AddDllDirectory") procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") @@ -242,7 +238,6 @@ var ( procFindResourceW = modkernel32.NewProc("FindResourceW") procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") procFindVolumeMountPointClose = modkernel32.NewProc("FindVolumeMountPointClose") - procFlushConsoleInputBuffer = modkernel32.NewProc("FlushConsoleInputBuffer") procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers") procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile") procFormatMessageW = modkernel32.NewProc("FormatMessageW") @@ -289,7 +284,6 @@ var ( procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId") - procGetNumberOfConsoleInputEvents = modkernel32.NewProc("GetNumberOfConsoleInputEvents") procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") procGetProcAddress = modkernel32.NewProc("GetProcAddress") @@ -1628,11 +1622,6 @@ func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) { return } -func FreeMibTable(memory unsafe.Pointer) { - syscall.SyscallN(procFreeMibTable.Addr(), uintptr(memory)) - return -} - func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { r0, _, _ := syscall.SyscallN(procGetAdaptersAddresses.Addr(), uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer))) if r0 != 0 { @@ -1673,22 +1662,6 @@ func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { return } -func GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) { - r0, _, _ := syscall.SyscallN(procGetIpForwardEntry2.Addr(), uintptr(unsafe.Pointer(row))) - if r0 != 0 { - errcode = syscall.Errno(r0) - } - return -} - -func GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) { - r0, _, _ := syscall.SyscallN(procGetIpForwardTable2.Addr(), uintptr(family), uintptr(unsafe.Pointer(table))) - if r0 != 0 { - errcode = syscall.Errno(r0) - } - return -} - func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) { r0, _, _ := syscall.SyscallN(procGetUnicastIpAddressEntry.Addr(), uintptr(unsafe.Pointer(row))) if r0 != 0 { @@ -1709,18 +1682,6 @@ func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsa return } -func NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { - var _p0 uint32 - if initialNotification { - _p0 = 1 - } - r0, _, _ := syscall.SyscallN(procNotifyRouteChange2.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) - if r0 != 0 { - errcode = syscall.Errno(r0) - } - return -} - func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { var _p0 uint32 if initialNotification { @@ -2150,14 +2111,6 @@ func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { return } -func FlushConsoleInputBuffer(console Handle) (err error) { - r1, _, e1 := syscall.SyscallN(procFlushConsoleInputBuffer.Addr(), uintptr(console)) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - func FlushFileBuffers(handle Handle) (err error) { r1, _, e1 := syscall.SyscallN(procFlushFileBuffers.Addr(), uintptr(handle)) if r1 == 0 { @@ -2528,14 +2481,6 @@ func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err erro return } -func GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) { - r1, _, e1 := syscall.SyscallN(procGetNumberOfConsoleInputEvents.Addr(), uintptr(console), uintptr(unsafe.Pointer(numevents))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) { var _p0 uint32 if wait { diff --git a/vendor/golang.org/x/term/terminal.go b/vendor/golang.org/x/term/terminal.go index 9255449b9b32..bddb2e2aebd4 100644 --- a/vendor/golang.org/x/term/terminal.go +++ b/vendor/golang.org/x/term/terminal.go @@ -413,7 +413,7 @@ func (t *Terminal) eraseNPreviousChars(n int) { } } -// countToLeftWord returns the number of characters from the cursor to the +// countToLeftWord returns then number of characters from the cursor to the // start of the previous word. func (t *Terminal) countToLeftWord() int { if t.pos == 0 { @@ -438,7 +438,7 @@ func (t *Terminal) countToLeftWord() int { return t.pos - pos } -// countToRightWord returns the number of characters from the cursor to the +// countToRightWord returns then number of characters from the cursor to the // start of the next word. func (t *Terminal) countToRightWord() int { pos := t.pos @@ -478,7 +478,7 @@ func visualLength(runes []rune) int { return length } -// historyAt unlocks the terminal and relocks it while calling History.At. +// histroryAt unlocks the terminal and relocks it while calling History.At. func (t *Terminal) historyAt(idx int) (string, bool) { t.lock.Unlock() // Unlock to avoid deadlock if History methods use the output writer. defer t.lock.Lock() // panic in At (or Len) protection. diff --git a/vendor/golang.org/x/text/unicode/bidi/core.go b/vendor/golang.org/x/text/unicode/bidi/core.go index fb8273236dde..9d2ae547b5ed 100644 --- a/vendor/golang.org/x/text/unicode/bidi/core.go +++ b/vendor/golang.org/x/text/unicode/bidi/core.go @@ -427,6 +427,13 @@ type isolatingRunSequence struct { func (i *isolatingRunSequence) Len() int { return len(i.indexes) } +func maxLevel(a, b level) level { + if a > b { + return a + } + return b +} + // Rule X10, second bullet: Determine the start-of-sequence (sos) and end-of-sequence (eos) types, // either L or R, for each isolating run sequence. func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence { @@ -467,8 +474,8 @@ func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence { indexes: indexes, types: types, level: level, - sos: typeForLevel(max(prevLevel, level)), - eos: typeForLevel(max(succLevel, level)), + sos: typeForLevel(maxLevel(prevLevel, level)), + eos: typeForLevel(maxLevel(succLevel, level)), } } diff --git a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go index 7e72d3c284b8..31c8d2f24096 100644 --- a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go +++ b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go @@ -40,7 +40,7 @@ type Cursor struct { // Root returns a cursor for the virtual root node, // whose children are the files provided to [New]. // -// Its [Cursor.Node] method return nil. +// Its [Cursor.Node] and [Cursor.Stack] methods return nil. func (in *Inspector) Root() Cursor { return Cursor{in, -1} } diff --git a/vendor/modules.txt b/vendor/modules.txt index d94d720beade..cfb7d1d4ef67 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -46,12 +46,6 @@ cloud.google.com/go/storage/experimental cloud.google.com/go/storage/internal cloud.google.com/go/storage/internal/apiv2 cloud.google.com/go/storage/internal/apiv2/storagepb -# cyphar.com/go-pathrs v0.2.1 -## explicit; go 1.18 -cyphar.com/go-pathrs -cyphar.com/go-pathrs/internal/fdutils -cyphar.com/go-pathrs/internal/libpathrs -cyphar.com/go-pathrs/procfs # git.sr.ht/~sbinet/gg v0.5.0 ## explicit; go 1.19 git.sr.ht/~sbinet/gg @@ -532,20 +526,9 @@ github.com/coreos/go-systemd/v22/journal ## explicit; go 1.18 github.com/coreos/stream-metadata-go/stream github.com/coreos/stream-metadata-go/stream/rhcos -# github.com/cyphar/filepath-securejoin v0.6.0 => github.com/wangke19/filepath-securejoin-1 v0.6.2-0.20260309113322-d8b3e820b3d6 +# github.com/cyphar/filepath-securejoin v0.4.1 ## explicit; go 1.18 github.com/cyphar/filepath-securejoin -github.com/cyphar/filepath-securejoin/internal/consts -github.com/cyphar/filepath-securejoin/pathrs-lite -github.com/cyphar/filepath-securejoin/pathrs-lite/internal -github.com/cyphar/filepath-securejoin/pathrs-lite/internal/assert -github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd -github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat -github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs -github.com/cyphar/filepath-securejoin/pathrs-lite/internal/kernelversion -github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux -github.com/cyphar/filepath-securejoin/pathrs-lite/internal/procfs -github.com/cyphar/filepath-securejoin/pathrs-lite/procfs # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew @@ -1437,7 +1420,7 @@ github.com/opencontainers/runc/libcontainer/utils # github.com/opencontainers/runtime-spec v1.2.0 ## explicit github.com/opencontainers/runtime-spec/specs-go -# github.com/opencontainers/selinux v1.13.0 +# github.com/opencontainers/selinux v1.11.1 ## explicit; go 1.19 github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label @@ -1466,7 +1449,7 @@ github.com/openshift-kni/commatrix/pkg/matrix-diff github.com/openshift-kni/commatrix/pkg/mcp github.com/openshift-kni/commatrix/pkg/types github.com/openshift-kni/commatrix/pkg/utils -# github.com/openshift/api v0.0.0-20260212193555-c06ab675261f +# github.com/openshift/api v0.0.0-20260114133223-6ab113cb7368 ## explicit; go 1.24.0 github.com/openshift/api github.com/openshift/api/annotations @@ -1488,8 +1471,6 @@ github.com/openshift/api/config/v1alpha1 github.com/openshift/api/config/v1alpha2 github.com/openshift/api/console github.com/openshift/api/console/v1 -github.com/openshift/api/etcd -github.com/openshift/api/etcd/v1alpha1 github.com/openshift/api/features github.com/openshift/api/helm github.com/openshift/api/helm/v1beta1 @@ -1722,7 +1703,7 @@ github.com/openshift/client-go/user/informers/externalversions/internalinterface github.com/openshift/client-go/user/informers/externalversions/user github.com/openshift/client-go/user/informers/externalversions/user/v1 github.com/openshift/client-go/user/listers/user/v1 -# github.com/openshift/library-go v0.0.0-20260223145824-7b234b47a906 +# github.com/openshift/library-go v0.0.0-20251015151611-6fc7a74b67c5 ## explicit; go 1.24.0 github.com/openshift/library-go/pkg/apiserver/admission/admissionrestconfig github.com/openshift/library-go/pkg/apiserver/admission/admissiontimeout @@ -2244,7 +2225,7 @@ go.yaml.in/yaml/v2 # go.yaml.in/yaml/v3 v3.0.4 ## explicit; go 1.16 go.yaml.in/yaml/v3 -# golang.org/x/crypto v0.45.0 +# golang.org/x/crypto v0.42.0 ## explicit; go 1.24.0 golang.org/x/crypto/argon2 golang.org/x/crypto/bcrypt @@ -2297,14 +2278,14 @@ golang.org/x/image/math/fixed golang.org/x/image/tiff golang.org/x/image/tiff/lzw golang.org/x/image/vector -# golang.org/x/mod v0.29.0 -## explicit; go 1.24.0 +# golang.org/x/mod v0.27.0 +## explicit; go 1.23.0 golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.47.0 -## explicit; go 1.24.0 +# golang.org/x/net v0.43.0 +## explicit; go 1.23.0 golang.org/x/net/context golang.org/x/net/html golang.org/x/net/html/atom @@ -2332,12 +2313,12 @@ golang.org/x/oauth2/google/internal/stsexchange golang.org/x/oauth2/internal golang.org/x/oauth2/jws golang.org/x/oauth2/jwt -# golang.org/x/sync v0.18.0 +# golang.org/x/sync v0.17.0 ## explicit; go 1.24.0 golang.org/x/sync/errgroup golang.org/x/sync/semaphore golang.org/x/sync/singleflight -# golang.org/x/sys v0.38.0 +# golang.org/x/sys v0.36.0 ## explicit; go 1.24.0 golang.org/x/sys/cpu golang.org/x/sys/plan9 @@ -2346,10 +2327,10 @@ golang.org/x/sys/windows golang.org/x/sys/windows/registry golang.org/x/sys/windows/svc golang.org/x/sys/windows/svc/mgr -# golang.org/x/term v0.37.0 +# golang.org/x/term v0.35.0 ## explicit; go 1.24.0 golang.org/x/term -# golang.org/x/text v0.31.0 +# golang.org/x/text v0.29.0 ## explicit; go 1.24.0 golang.org/x/text/encoding golang.org/x/text/encoding/charmap @@ -2382,8 +2363,8 @@ golang.org/x/text/unicode/norm # golang.org/x/time v0.12.0 ## explicit; go 1.23.0 golang.org/x/time/rate -# golang.org/x/tools v0.38.0 -## explicit; go 1.24.0 +# golang.org/x/tools v0.36.0 +## explicit; go 1.23.0 golang.org/x/tools/container/intsets golang.org/x/tools/cover golang.org/x/tools/go/ast/edge @@ -4923,7 +4904,6 @@ sigs.k8s.io/structured-merge-diff/v6/value sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 sigs.k8s.io/yaml/kyaml -# github.com/cyphar/filepath-securejoin => github.com/wangke19/filepath-securejoin-1 v0.6.2-0.20260309113322-d8b3e820b3d6 # github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 # go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 # k8s.io/api => github.com/openshift/kubernetes/staging/src/k8s.io/api v0.0.0-20251017123720-96593f323733