lsm.rs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. use assert_matches::assert_matches;
  2. use aya::{
  3. Btf, Ebpf,
  4. programs::{Lsm, LsmCgroup, ProgramError, ProgramType},
  5. sys::{SyscallError, is_program_supported},
  6. };
  7. use crate::utils::Cgroup;
  8. macro_rules! expect_permission_denied {
  9. ($result:expr) => {
  10. let result = $result;
  11. if !std::fs::read_to_string("/sys/kernel/security/lsm").unwrap().contains("bpf") {
  12. assert_matches!(result, Ok(_));
  13. } else {
  14. assert_matches!(result, Err(e) => assert_eq!(
  15. e.kind(), std::io::ErrorKind::PermissionDenied)
  16. );
  17. }
  18. };
  19. }
  20. #[test]
  21. fn lsm() {
  22. let btf = Btf::from_sys_fs().unwrap();
  23. let mut bpf: Ebpf = Ebpf::load(crate::TEST).unwrap();
  24. let prog = bpf.program_mut("test_lsm").unwrap();
  25. let prog: &mut Lsm = prog.try_into().unwrap();
  26. prog.load("socket_bind", &btf).unwrap();
  27. assert_matches!(std::net::TcpListener::bind("127.0.0.1:0"), Ok(_));
  28. let link_id = {
  29. let result = prog.attach();
  30. if !is_program_supported(ProgramType::Lsm).unwrap() {
  31. assert_matches!(result, Err(ProgramError::SyscallError(SyscallError { call, io_error })) => {
  32. assert_eq!(call, "bpf_raw_tracepoint_open");
  33. assert_eq!(io_error.raw_os_error(), Some(524));
  34. });
  35. eprintln!("skipping test - LSM programs not supported");
  36. return;
  37. }
  38. result.unwrap()
  39. };
  40. expect_permission_denied!(std::net::TcpListener::bind("127.0.0.1:0"));
  41. prog.detach(link_id).unwrap();
  42. assert_matches!(std::net::TcpListener::bind("127.0.0.1:0"), Ok(_));
  43. }
  44. #[test]
  45. fn lsm_cgroup() {
  46. let mut bpf: Ebpf = Ebpf::load(crate::TEST).unwrap();
  47. let prog = bpf.program_mut("test_lsm_cgroup").unwrap();
  48. let prog: &mut LsmCgroup = prog.try_into().unwrap();
  49. let btf = Btf::from_sys_fs().expect("could not get btf from sys");
  50. prog.load("socket_bind", &btf).unwrap();
  51. assert_matches!(std::net::TcpListener::bind("127.0.0.1:0"), Ok(_));
  52. let pid = std::process::id();
  53. let root = Cgroup::root();
  54. let cgroup = root.create_child("aya-test-lsm-cgroup");
  55. let link_id = {
  56. let result = prog.attach(cgroup.fd());
  57. if !is_program_supported(ProgramType::Lsm).unwrap() {
  58. assert_matches!(result, Err(ProgramError::SyscallError(SyscallError { call, io_error })) => {
  59. assert_eq!(call, "bpf_link_create");
  60. assert_eq!(io_error.raw_os_error(), Some(524));
  61. });
  62. eprintln!("skipping test - LSM programs not supported");
  63. return;
  64. }
  65. result.unwrap()
  66. };
  67. let cgroup = cgroup.into_cgroup();
  68. cgroup.write_pid(pid);
  69. expect_permission_denied!(std::net::TcpListener::bind("127.0.0.1:0"));
  70. root.write_pid(pid);
  71. assert_matches!(std::net::TcpListener::bind("127.0.0.1:0"), Ok(_));
  72. cgroup.write_pid(pid);
  73. expect_permission_denied!(std::net::TcpListener::bind("127.0.0.1:0"));
  74. prog.detach(link_id).unwrap();
  75. assert_matches!(std::net::TcpListener::bind("127.0.0.1:0"), Ok(_));
  76. }