Skip to content

Commit

Permalink
genpolicy: fix validation of env variables sourced from metadata.name…
Browse files Browse the repository at this point in the history
…space

Use $(sandbox-namespace) wildcard in case none is specified in yaml. If wildcard is present, compare
input against annotation value.

Fixes regression introduced in #273
where samples that use metadata.namespace env var were no longer working.

Signed-off-by: Saul Paredes <[email protected]>
  • Loading branch information
Redent0r committed Jan 16, 2025
1 parent 6e3fd0a commit 962689b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 32 deletions.
77 changes: 46 additions & 31 deletions src/tools/genpolicy/rules.rego
Original file line number Diff line number Diff line change
Expand Up @@ -251,19 +251,17 @@ allow_by_anno(p_oci, i_oci, p_storages, i_storages) {
print("allow_by_anno 2: i_s_name =", i_s_name, "p_s_name =", p_s_name)

allow_sandbox_name(p_s_name, i_s_name)
allow_by_sandbox_name(p_oci, i_oci, p_storages, i_storages, i_s_name)
allow_by_sandbox_name(p_oci, i_oci, p_storages, i_storages)

print("allow_by_anno 2: true")
}

allow_by_sandbox_name(p_oci, i_oci, p_storages, i_storages, s_name) {
allow_by_sandbox_name(p_oci, i_oci, p_storages, i_storages) {
print("allow_by_sandbox_name: start")

i_namespace := i_oci.Annotations[S_NAMESPACE_KEY]

allow_by_container_types(p_oci, i_oci, s_name, i_namespace)
allow_by_container_types(p_oci, i_oci)
allow_by_bundle_or_sandbox_id(p_oci, i_oci, p_storages, i_storages)
allow_process(p_oci.Process, i_oci.Process, s_name)
allow_process(p_oci, i_oci)

print("allow_by_sandbox_name: true")
}
Expand All @@ -289,13 +287,15 @@ allow_sandbox_name(p_s_name, i_s_name) {
# expected type - either a "sandbox" or a "container". Then, validate
# other annotations based on the actual "sandbox" or "container" value
# from the input container.
allow_by_container_types(p_oci, i_oci, s_name, s_namespace) {
allow_by_container_types(p_oci, i_oci) {
print("allow_by_container_types: checking io.kubernetes.cri.container-type")

c_type := "io.kubernetes.cri.container-type"

p_cri_type := p_oci.Annotations[c_type]
i_cri_type := i_oci.Annotations[c_type]
s_name := i_oci.Annotations[S_NAME_KEY]
s_namespace := i_oci.Annotations[S_NAMESPACE_KEY]
print("allow_by_container_types: p_cri_type =", p_cri_type, "i_cri_type =", i_cri_type)
p_cri_type == i_cri_type

Expand Down Expand Up @@ -557,26 +557,29 @@ allow_by_bundle_or_sandbox_id(p_oci, i_oci, p_storages, i_storages) {
print("allow_by_bundle_or_sandbox_id: true")
}

allow_process_common(p_process, i_process, s_name) {
allow_process_common(p_oci, i_oci) {
p_process := p_oci.Process
i_process := i_oci.Process
print("allow_process_common: p_process =", p_process)
print("allow_process_common: i_process = ", i_process)
print("allow_process_common: s_name =", s_name)

p_process.Cwd == i_process.Cwd
p_process.NoNewPrivileges == i_process.NoNewPrivileges

allow_user(p_process, i_process)
allow_env(p_process, i_process, s_name)
allow_env(p_oci, i_oci)

print("allow_process_common: true")
}

# Compare the OCI Process field of a policy container with the input OCI Process from a CreateContainerRequest
allow_process(p_process, i_process, s_name) {
allow_process(p_oci, i_oci) {
print("allow_process: start")

p_process := p_oci.Process
i_process := i_oci.Process
s_name := i_oci.Annotations[S_NAME_KEY]
allow_args(p_process, i_process, s_name)
allow_process_common(p_process, i_process, s_name)
allow_process_common(p_oci, i_oci)
allow_caps(p_process.Capabilities, i_process.Capabilities)
p_process.Terminal == i_process.Terminal

Expand Down Expand Up @@ -675,28 +678,29 @@ allow_arg(i, i_arg, p_process, s_name) {
}

# OCI process.Env field
allow_env(p_process, i_process, s_name) {
print("allow_env: p env =", p_process.Env)
print("allow_env: i env =", i_process.Env)
allow_env(p_oci, i_oci) {
print("allow_env: p env =", p_oci.Process.Env)
print("allow_env: i env =", i_oci.Process.Env)

every i_var in i_process.Env {
every i_var in i_oci.Process.Env {
print("allow_env: i_var =", i_var)
allow_var(p_process, i_process, i_var, s_name)
allow_var(p_oci, i_oci, i_var)
}

print("allow_env: true")
}

# Allow input env variables that are present in the policy data too.
allow_var(p_process, i_process, i_var, s_name) {
some p_var in p_process.Env
allow_var(p_oci, i_oci, i_var) {
some p_var in p_oci.Process.Env
p_var == i_var
print("allow_var 1: true")
}

# Match input with one of the policy variables, after substituting $(sandbox-name).
allow_var(p_process, i_process, i_var, s_name) {
some p_var in p_process.Env
allow_var(p_oci, i_oci, i_var) {
s_name = i_oci.Annotations[S_NAME_KEY]
some p_var in p_oci.Process.Env
p_var2 := replace(p_var, "$(sandbox-name)", s_name)

print("allow_var 2: p_var2 =", p_var2)
Expand All @@ -706,7 +710,7 @@ allow_var(p_process, i_process, i_var, s_name) {
}

# Allow input env variables that match with a request_defaults regex.
allow_var(p_process, i_process, i_var, s_name) {
allow_var(p_oci, i_oci, i_var) {
some p_regex1 in policy_data.request_defaults.CreateContainerRequest.allow_env_regex
p_regex2 := replace(p_regex1, "$(ipv4_a)", policy_data.common.ipv4_a)
p_regex3 := replace(p_regex2, "$(ip_p)", policy_data.common.ip_p)
Expand All @@ -720,23 +724,23 @@ allow_var(p_process, i_process, i_var, s_name) {
}

# Allow fieldRef "fieldPath: status.podIP" values.
allow_var(p_process, i_process, i_var, s_name) {
allow_var(p_oci, i_oci, i_var) {
name_value := split(i_var, "=")
count(name_value) == 2
is_ip(name_value[1])

some p_var in p_process.Env
some p_var in p_oci.Process.Env
allow_pod_ip_var(name_value[0], p_var)

print("allow_var 4: true")
}

# Allow common fieldRef variables.
allow_var(p_process, i_process, i_var, s_name) {
allow_var(p_oci, i_oci, i_var) {
name_value := split(i_var, "=")
count(name_value) == 2

some p_var in p_process.Env
some p_var in p_oci.Process.Env
p_name_value := split(p_var, "=")
count(p_name_value) == 2

Expand All @@ -751,23 +755,23 @@ allow_var(p_process, i_process, i_var, s_name) {
}

# Allow fieldRef "fieldPath: status.hostIP" values.
allow_var(p_process, i_process, i_var, s_name) {
allow_var(p_oci, i_oci, i_var) {
name_value := split(i_var, "=")
count(name_value) == 2
is_ip(name_value[1])

some p_var in p_process.Env
some p_var in p_oci.Process.Env
allow_host_ip_var(name_value[0], p_var)

print("allow_var 6: true")
}

# Allow resourceFieldRef values (e.g., "limits.cpu").
allow_var(p_process, i_process, i_var, s_name) {
allow_var(p_oci, i_oci, i_var) {
name_value := split(i_var, "=")
count(name_value) == 2

some p_var in p_process.Env
some p_var in p_oci.Process.Env
p_name_value := split(p_var, "=")
count(p_name_value) == 2

Expand All @@ -781,6 +785,17 @@ allow_var(p_process, i_process, i_var, s_name) {
print("allow_var 7: true")
}

allow_var(p_oci, i_oci, i_var) {
s_namespace = i_oci.Annotations[S_NAMESPACE_KEY]
some p_var in p_oci.Process.Env
p_var2 := replace(p_var, "$(sandbox-namespace)", s_namespace)

print("allow_var 8: p_var8 =", p_var2)
p_var2 == i_var

print("allow_var 8: true")
}

allow_pod_ip_var(var_name, p_var) {
print("allow_pod_ip_var: var_name =", var_name, "p_var =", p_var)

Expand Down
8 changes: 7 additions & 1 deletion src/tools/genpolicy/src/pod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,13 @@ impl EnvVar {
let path: &str = &field_ref.fieldPath;
match path {
"metadata.name" => return "$(sandbox-name)".to_string(),
"metadata.namespace" => return namespace.to_string(),
"metadata.namespace" => {
return if namespace.is_empty() {
"$(sandbox-namespace)".to_string()
} else {
namespace.to_string()
};
}
"metadata.uid" => return "$(pod-uid)".to_string(),
"status.hostIP" => return "$(host-ip)".to_string(),
"status.podIP" => return "$(pod-ip)".to_string(),
Expand Down

0 comments on commit 962689b

Please sign in to comment.