@@ -829,3 +829,183 @@ var _ = Describe("validateDRA", func() {
829829 Expect (validateDRA (mod , minValidKubeVersion )).NotTo (HaveOccurred ())
830830 })
831831})
832+
833+ var _ = Describe ("validateDevicePluginVolumes" , func () {
834+ It ("should accept nil DevicePlugin" , func () {
835+ Expect (validateDevicePluginVolumes (nil )).NotTo (HaveOccurred ())
836+ })
837+
838+ It ("should accept DevicePlugin with no volumes" , func () {
839+ dp := & kmmv1beta1.DevicePluginSpec {
840+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
841+ }
842+ Expect (validateDevicePluginVolumes (dp )).NotTo (HaveOccurred ())
843+ })
844+
845+ It ("should accept non-hostPath volumes" , func () {
846+ dp := & kmmv1beta1.DevicePluginSpec {
847+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
848+ Volumes : []v1.Volume {
849+ {
850+ Name : "config" ,
851+ VolumeSource : v1.VolumeSource {
852+ ConfigMap : & v1.ConfigMapVolumeSource {
853+ LocalObjectReference : v1.LocalObjectReference {Name : "my-cm" },
854+ },
855+ },
856+ },
857+ },
858+ }
859+ Expect (validateDevicePluginVolumes (dp )).NotTo (HaveOccurred ())
860+ })
861+
862+ It ("should accept hostPath volumes under /dev" , func () {
863+ dp := & kmmv1beta1.DevicePluginSpec {
864+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
865+ Volumes : []v1.Volume {
866+ {
867+ Name : "dev-vfio" ,
868+ VolumeSource : v1.VolumeSource {
869+ HostPath : & v1.HostPathVolumeSource {Path : "/dev/vfio" },
870+ },
871+ },
872+ },
873+ }
874+ Expect (validateDevicePluginVolumes (dp )).NotTo (HaveOccurred ())
875+ })
876+
877+ It ("should accept hostPath volumes equal to /dev" , func () {
878+ dp := & kmmv1beta1.DevicePluginSpec {
879+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
880+ Volumes : []v1.Volume {
881+ {
882+ Name : "dev" ,
883+ VolumeSource : v1.VolumeSource {
884+ HostPath : & v1.HostPathVolumeSource {Path : "/dev" },
885+ },
886+ },
887+ },
888+ }
889+ Expect (validateDevicePluginVolumes (dp )).NotTo (HaveOccurred ())
890+ })
891+
892+ It ("should accept hostPath volumes under /sys" , func () {
893+ dp := & kmmv1beta1.DevicePluginSpec {
894+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
895+ Volumes : []v1.Volume {
896+ {
897+ Name : "sys-class" ,
898+ VolumeSource : v1.VolumeSource {
899+ HostPath : & v1.HostPathVolumeSource {Path : "/sys/class/net" },
900+ },
901+ },
902+ },
903+ }
904+ Expect (validateDevicePluginVolumes (dp )).NotTo (HaveOccurred ())
905+ })
906+
907+ It ("should accept hostPath volumes under /var" , func () {
908+ dp := & kmmv1beta1.DevicePluginSpec {
909+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
910+ Volumes : []v1.Volume {
911+ {
912+ Name : "var-lib" ,
913+ VolumeSource : v1.VolumeSource {
914+ HostPath : & v1.HostPathVolumeSource {Path : "/var/lib/kubelet/device-plugins" },
915+ },
916+ },
917+ },
918+ }
919+ Expect (validateDevicePluginVolumes (dp )).NotTo (HaveOccurred ())
920+ })
921+
922+ It ("should accept hostPath volumes under /opt" , func () {
923+ dp := & kmmv1beta1.DevicePluginSpec {
924+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
925+ Volumes : []v1.Volume {
926+ {
927+ Name : "opt-lib" ,
928+ VolumeSource : v1.VolumeSource {
929+ HostPath : & v1.HostPathVolumeSource {Path : "/opt/lib/firmware" },
930+ },
931+ },
932+ },
933+ }
934+ Expect (validateDevicePluginVolumes (dp )).NotTo (HaveOccurred ())
935+ })
936+
937+ It ("should reject hostPath volumes outside allowed paths" , func () {
938+ dp := & kmmv1beta1.DevicePluginSpec {
939+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
940+ Volumes : []v1.Volume {
941+ {
942+ Name : "root" ,
943+ VolumeSource : v1.VolumeSource {
944+ HostPath : & v1.HostPathVolumeSource {Path : "/" },
945+ },
946+ },
947+ },
948+ }
949+ Expect (validateDevicePluginVolumes (dp )).To (MatchError (ContainSubstring ("not allowed" )))
950+ })
951+
952+ It ("should reject hostPath volumes under /etc" , func () {
953+ dp := & kmmv1beta1.DevicePluginSpec {
954+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
955+ Volumes : []v1.Volume {
956+ {
957+ Name : "etc" ,
958+ VolumeSource : v1.VolumeSource {
959+ HostPath : & v1.HostPathVolumeSource {Path : "/etc/config" },
960+ },
961+ },
962+ },
963+ }
964+ Expect (validateDevicePluginVolumes (dp )).To (MatchError (ContainSubstring ("not allowed" )))
965+ })
966+
967+ It ("should reject hostPath with prefix trick like /devious" , func () {
968+ dp := & kmmv1beta1.DevicePluginSpec {
969+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
970+ Volumes : []v1.Volume {
971+ {
972+ Name : "tricky" ,
973+ VolumeSource : v1.VolumeSource {
974+ HostPath : & v1.HostPathVolumeSource {Path : "/devious" },
975+ },
976+ },
977+ },
978+ }
979+ Expect (validateDevicePluginVolumes (dp )).To (MatchError (ContainSubstring ("not allowed" )))
980+ })
981+
982+ It ("should reject hostPath with path traversal like /dev/../etc" , func () {
983+ dp := & kmmv1beta1.DevicePluginSpec {
984+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
985+ Volumes : []v1.Volume {
986+ {
987+ Name : "traversal" ,
988+ VolumeSource : v1.VolumeSource {
989+ HostPath : & v1.HostPathVolumeSource {Path : "/dev/../etc/shadow" },
990+ },
991+ },
992+ },
993+ }
994+ Expect (validateDevicePluginVolumes (dp )).To (MatchError (ContainSubstring ("not allowed" )))
995+ })
996+
997+ It ("should accept hostPath with redundant slashes under /sys" , func () {
998+ dp := & kmmv1beta1.DevicePluginSpec {
999+ Container : kmmv1beta1.DevicePluginContainerSpec {Image : "img:tag" },
1000+ Volumes : []v1.Volume {
1001+ {
1002+ Name : "sys-clean" ,
1003+ VolumeSource : v1.VolumeSource {
1004+ HostPath : & v1.HostPathVolumeSource {Path : "/sys//class//net" },
1005+ },
1006+ },
1007+ },
1008+ }
1009+ Expect (validateDevicePluginVolumes (dp )).NotTo (HaveOccurred ())
1010+ })
1011+ })
0 commit comments