mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 17:30:00 +00:00
Merge pull request #16354 from mdshuai/valid-supplemental-groups
Auto commit by PR queue bot
This commit is contained in:
commit
170c03a85f
@ -19,6 +19,7 @@ package validation
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@ -58,6 +59,7 @@ var DNS1123LabelErrorMsg string = fmt.Sprintf(`must be a DNS label (at most %d c
|
|||||||
var DNS952LabelErrorMsg string = fmt.Sprintf(`must be a DNS 952 label (at most %d characters, matching regex %s): e.g. "my-name"`, validation.DNS952LabelMaxLength, validation.DNS952LabelFmt)
|
var DNS952LabelErrorMsg string = fmt.Sprintf(`must be a DNS 952 label (at most %d characters, matching regex %s): e.g. "my-name"`, validation.DNS952LabelMaxLength, validation.DNS952LabelFmt)
|
||||||
var pdPartitionErrorMsg string = InclusiveRangeErrorMsg(1, 255)
|
var pdPartitionErrorMsg string = InclusiveRangeErrorMsg(1, 255)
|
||||||
var PortRangeErrorMsg string = InclusiveRangeErrorMsg(1, 65535)
|
var PortRangeErrorMsg string = InclusiveRangeErrorMsg(1, 65535)
|
||||||
|
var IdRangeErrorMsg string = InclusiveRangeErrorMsg(0, math.MaxInt32)
|
||||||
var PortNameErrorMsg string = fmt.Sprintf(`must be an IANA_SVC_NAME (at most 15 characters, matching regex %s, it must contain at least one letter [a-z], and hyphens cannot be adjacent to other hyphens): e.g. "http"`, validation.IdentifierNoHyphensBeginEndFmt)
|
var PortNameErrorMsg string = fmt.Sprintf(`must be an IANA_SVC_NAME (at most 15 characters, matching regex %s, it must contain at least one letter [a-z], and hyphens cannot be adjacent to other hyphens): e.g. "http"`, validation.IdentifierNoHyphensBeginEndFmt)
|
||||||
|
|
||||||
const totalAnnotationSizeLimitB int = 256 * (1 << 10) // 256 kB
|
const totalAnnotationSizeLimitB int = 256 * (1 << 10) // 256 kB
|
||||||
@ -1309,6 +1311,18 @@ func ValidatePodSecurityContext(securityContext *api.PodSecurityContext, spec *a
|
|||||||
|
|
||||||
if securityContext != nil {
|
if securityContext != nil {
|
||||||
allErrs = append(allErrs, validateHostNetwork(securityContext.HostNetwork, spec.Containers, specPath.Child("containers"))...)
|
allErrs = append(allErrs, validateHostNetwork(securityContext.HostNetwork, spec.Containers, specPath.Child("containers"))...)
|
||||||
|
if securityContext.FSGroup != nil && !validation.IsValidGroupId(*securityContext.FSGroup) {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("fsGroup"), *(securityContext.FSGroup), IdRangeErrorMsg))
|
||||||
|
}
|
||||||
|
if securityContext.RunAsUser != nil && !validation.IsValidUserId(*securityContext.RunAsUser) {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("runAsUser"), *(securityContext.RunAsUser), IdRangeErrorMsg))
|
||||||
|
}
|
||||||
|
for i, gid := range securityContext.SupplementalGroups {
|
||||||
|
if !validation.IsValidGroupId(gid) {
|
||||||
|
supplementalGroup := fmt.Sprintf(`supplementalGroups[%d]`, i)
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath.Child(supplementalGroup), gid, IdRangeErrorMsg))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return allErrs
|
return allErrs
|
||||||
|
@ -1392,6 +1392,8 @@ func TestValidateDNSPolicy(t *testing.T) {
|
|||||||
|
|
||||||
func TestValidatePodSpec(t *testing.T) {
|
func TestValidatePodSpec(t *testing.T) {
|
||||||
activeDeadlineSeconds := int64(30)
|
activeDeadlineSeconds := int64(30)
|
||||||
|
minID := int64(0)
|
||||||
|
maxID := int64(2147483647)
|
||||||
successCases := []api.PodSpec{
|
successCases := []api.PodSpec{
|
||||||
{ // Populate basic fields, leave defaults for most.
|
{ // Populate basic fields, leave defaults for most.
|
||||||
Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}},
|
Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}},
|
||||||
@ -1425,6 +1427,26 @@ func TestValidatePodSpec(t *testing.T) {
|
|||||||
RestartPolicy: api.RestartPolicyAlways,
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
DNSPolicy: api.DNSClusterFirst,
|
DNSPolicy: api.DNSClusterFirst,
|
||||||
},
|
},
|
||||||
|
{ // Populate RunAsUser SupplementalGroups FSGroup with minID 0
|
||||||
|
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||||
|
SecurityContext: &api.PodSecurityContext{
|
||||||
|
SupplementalGroups: []int64{minID},
|
||||||
|
RunAsUser: &minID,
|
||||||
|
FSGroup: &minID,
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
|
DNSPolicy: api.DNSClusterFirst,
|
||||||
|
},
|
||||||
|
{ // Populate RunAsUser SupplementalGroups FSGroup with maxID 2147483647
|
||||||
|
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||||
|
SecurityContext: &api.PodSecurityContext{
|
||||||
|
SupplementalGroups: []int64{maxID},
|
||||||
|
RunAsUser: &maxID,
|
||||||
|
FSGroup: &maxID,
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
|
DNSPolicy: api.DNSClusterFirst,
|
||||||
|
},
|
||||||
{ // Populate HostIPC.
|
{ // Populate HostIPC.
|
||||||
SecurityContext: &api.PodSecurityContext{
|
SecurityContext: &api.PodSecurityContext{
|
||||||
HostIPC: true,
|
HostIPC: true,
|
||||||
@ -1451,6 +1473,8 @@ func TestValidatePodSpec(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
activeDeadlineSeconds = int64(0)
|
activeDeadlineSeconds = int64(0)
|
||||||
|
minID = int64(-1)
|
||||||
|
maxID = int64(2147483648)
|
||||||
failureCases := map[string]api.PodSpec{
|
failureCases := map[string]api.PodSpec{
|
||||||
"bad volume": {
|
"bad volume": {
|
||||||
Volumes: []api.Volume{{}},
|
Volumes: []api.Volume{{}},
|
||||||
@ -1495,6 +1519,60 @@ func TestValidatePodSpec(t *testing.T) {
|
|||||||
RestartPolicy: api.RestartPolicyAlways,
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
DNSPolicy: api.DNSClusterFirst,
|
DNSPolicy: api.DNSClusterFirst,
|
||||||
},
|
},
|
||||||
|
"bad supplementalGroups large than math.MaxInt32": {
|
||||||
|
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||||
|
SecurityContext: &api.PodSecurityContext{
|
||||||
|
HostNetwork: false,
|
||||||
|
SupplementalGroups: []int64{maxID, 1234},
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
|
DNSPolicy: api.DNSClusterFirst,
|
||||||
|
},
|
||||||
|
"bad supplementalGroups less than 0": {
|
||||||
|
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||||
|
SecurityContext: &api.PodSecurityContext{
|
||||||
|
HostNetwork: false,
|
||||||
|
SupplementalGroups: []int64{minID, 1234},
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
|
DNSPolicy: api.DNSClusterFirst,
|
||||||
|
},
|
||||||
|
"bad runAsUser large than math.MaxInt32": {
|
||||||
|
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||||
|
SecurityContext: &api.PodSecurityContext{
|
||||||
|
HostNetwork: false,
|
||||||
|
RunAsUser: &maxID,
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
|
DNSPolicy: api.DNSClusterFirst,
|
||||||
|
},
|
||||||
|
"bad runAsUser less than 0": {
|
||||||
|
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||||
|
SecurityContext: &api.PodSecurityContext{
|
||||||
|
HostNetwork: false,
|
||||||
|
RunAsUser: &minID,
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
|
DNSPolicy: api.DNSClusterFirst,
|
||||||
|
},
|
||||||
|
"bad fsGroup large than math.MaxInt32": {
|
||||||
|
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||||
|
SecurityContext: &api.PodSecurityContext{
|
||||||
|
HostNetwork: false,
|
||||||
|
FSGroup: &maxID,
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
|
DNSPolicy: api.DNSClusterFirst,
|
||||||
|
},
|
||||||
|
"bad fsGroup less than 0": {
|
||||||
|
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||||
|
SecurityContext: &api.PodSecurityContext{
|
||||||
|
HostNetwork: false,
|
||||||
|
FSGroup: &minID,
|
||||||
|
},
|
||||||
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
|
DNSPolicy: api.DNSClusterFirst,
|
||||||
|
},
|
||||||
"bad-active-deadline-seconds": {
|
"bad-active-deadline-seconds": {
|
||||||
Volumes: []api.Volume{
|
Volumes: []api.Volume{
|
||||||
{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
|
{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package validation
|
package validation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
@ -105,6 +106,25 @@ func IsValidPortNum(port int) bool {
|
|||||||
return 0 < port && port < 65536
|
return 0 < port && port < 65536
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now in libcontainer UID/GID limits is 0 ~ 1<<31 - 1
|
||||||
|
// TODO: once we have a type for UID/GID we should make these that type.
|
||||||
|
const (
|
||||||
|
minUserID = 0
|
||||||
|
maxUserID = math.MaxInt32
|
||||||
|
minGroupID = 0
|
||||||
|
maxGroupID = math.MaxInt32
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsValidGroupId tests that the argument is a valid gids.
|
||||||
|
func IsValidGroupId(gid int64) bool {
|
||||||
|
return minGroupID <= gid && gid <= maxGroupID
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsValidUserId tests that the argument is a valid uids.
|
||||||
|
func IsValidUserId(uid int64) bool {
|
||||||
|
return minUserID <= uid && uid <= maxUserID
|
||||||
|
}
|
||||||
|
|
||||||
const doubleHyphensFmt string = ".*(--).*"
|
const doubleHyphensFmt string = ".*(--).*"
|
||||||
|
|
||||||
var doubleHyphensRegexp = regexp.MustCompile("^" + doubleHyphensFmt + "$")
|
var doubleHyphensRegexp = regexp.MustCompile("^" + doubleHyphensFmt + "$")
|
||||||
|
@ -154,6 +154,38 @@ func TestIsValidPortNum(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsValidGroupId(t *testing.T) {
|
||||||
|
goodValues := []int64{0, 1, 1000, 65535, 2147483647}
|
||||||
|
for _, val := range goodValues {
|
||||||
|
if !IsValidGroupId(val) {
|
||||||
|
t.Errorf("expected true for '%d'", val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
badValues := []int64{-1, -1003, 2147483648, 4147483647}
|
||||||
|
for _, val := range badValues {
|
||||||
|
if IsValidGroupId(val) {
|
||||||
|
t.Errorf("expected false for '%d'", val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsValidUserId(t *testing.T) {
|
||||||
|
goodValues := []int64{0, 1, 1000, 65535, 2147483647}
|
||||||
|
for _, val := range goodValues {
|
||||||
|
if !IsValidUserId(val) {
|
||||||
|
t.Errorf("expected true for '%d'", val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
badValues := []int64{-1, -1003, 2147483648, 4147483647}
|
||||||
|
for _, val := range badValues {
|
||||||
|
if IsValidUserId(val) {
|
||||||
|
t.Errorf("expected false for '%d'", val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestIsValidPortName(t *testing.T) {
|
func TestIsValidPortName(t *testing.T) {
|
||||||
goodValues := []string{"telnet", "re-mail-ck", "pop3", "a", "a-1", "1-a", "a-1-b-2-c", "1-a-2-b-3"}
|
goodValues := []string{"telnet", "re-mail-ck", "pop3", "a", "a-1", "1-a", "a-1-b-2-c", "1-a-2-b-3"}
|
||||||
for _, val := range goodValues {
|
for _, val := range goodValues {
|
||||||
|
Loading…
Reference in New Issue
Block a user