;; Selinux is deny by default. So we must explicitly allow access to everything weechat needs, ;; including system libraries, the dynamic loader, xdg directories and more. ;; reserve ports for irc purposes (block irc (portcon "tcp" 6667 port_context) (portcon "tcp" 6697 port_context) (blockinherit .net.port.unreserved.template)) ;; define our weechat namespace (block weechat ;; most or all things have a template defined that we can use ;; rarely do we write policy "from scratch", this includes subjects which are ;; what we are creating here (blockinherit .subj.template) ;; authorize sys.role to access the subj domain (roletype .sys.role subj) ;; allow signaling ourself (allow subj self (process (fork sigchld sigkill signal signull sigstop))) ;; allow setattr and getattr on our own files (allow subj self (file (setattr getattr))) ;; allow reading and executing our own binary (/usr/bin/weechat) ;; also allow a type transition from .sys.subj to .weechat.subj (call .weechat.exec.subj_type_transition (.sys.subj subj)) (call .weechat.exec.entrypoint_file_files (subj)) (call .weechat.exec.mapexecute_file_files (subj)) (call .weechat.exec.read_file_files (subj)) ;; nearly full access to our own data files (call .weechat.data.search_file_dirs (subj)) (call .weechat.data.create_file_dirs (subj)) (call .weechat.data.create_file_files (subj)) (call .weechat.data.delete_file_files (subj)) (call .weechat.data.readwrite_file_files (subj)) (call .weechat.data.rename_file_files (subj)) (call .weechat.data.addname_file_dirs (subj)) (call .weechat.data.deletename_file_dirs (subj)) (call .weechat.data.rename_file_dirs (subj)) ;; same as above, nearly full access to our runtime files (call .weechat.run.search_file_dirs (subj)) (call .weechat.run.create_file_dirs (subj)) (call .weechat.run.create_file_files (subj)) (call .weechat.run.delete_file_files (subj)) (call .weechat.run.readwrite_file_files (subj)) (call .weechat.run.rename_file_files (subj)) (call .weechat.run.addname_file_dirs (subj)) (call .weechat.run.deletename_file_dirs (subj)) (call .weechat.run.rename_file_dirs (subj)) ;; allow using unix sockets so long as they are the same type as ourself (allow subj self (unix_dgram_socket (create sendto read write))) ;; allowing using the network but only irc ports specifically (allow subj self create_tcp_socket) (call irc.nameconnect_port_tcp_sockets (subj)) ;; You need to be able to traverse directories before you can access files. ;; Each parent dir needs to be traversable, so we have to allow traversing root. (call .root.search_file_dirs (subj)) ;; allow access to procfs (call .proc.read_fs_lnk_files (subj)) (call .proc.search_fs_dirs (subj)) ;; allow access to sysfs (call .sys.search_fs_dirs (subj)) (call .sys.read_fs_files (subj)) ;; use system libraries (call .lib.search_file_dirs (subj)) (call .lib.read_file_files (subj)) (call .lib.mapexecute_file_files (subj)) (call .lib.read_file_lnk_files (subj)) ;; read /etc (call .conf.search_file_dirs (subj)) (call .conf.read_file_files (subj)) (call .conf.read_file_lnk_files (subj)) ;; The dynamic loader is currently labeled .conf.file, and we need to be able to map and exec it. ;; This is something you probably want to fix when writing your own policy on top of dssp5. (call .conf.mapexecute_file_files (subj)) ;; use ssl certs (call .cert.search_file_dirs (subj)) (call .cert.read_file_files (subj)) ;; use terminal (call .sys.use_subj_fds (subj)) (call .dev.readwriteinherited_file_chr_files (subj)) (call .ptytermdev.readwriteinherited_all_chr_files (subj)) ;; read /usr/share (call .data.search_file_dirs (subj)) (call .data.read_file_files (subj)) ;; traverse /home (call .home.search_file_dirs (subj)) ;; allow creating dirs in ~/.config (call .xdg.config.home.search_file_dirs (subj)) (call .xdg.config.home.create_file_dirs (subj)) (call .xdg.config.home.addname_file_dirs (subj)) ;; allow creating dirs in ~/.cache (call .xdg.cache.home.search_file_dirs (subj)) (call .xdg.cache.home.create_file_dirs (subj)) (call .xdg.cache.home.addname_file_dirs (subj)) ;; allow creating dirs in ~/.local/share (call .xdg.share.home.search_file_dirs (subj)) (call .xdg.share.home.create_file_dirs (subj)) (call .xdg.share.home.addname_file_dirs (subj)) ;; allow creating dirs in ~/.local/state (call .xdg.state.home.search_file_dirs (subj)) (call .xdg.state.home.create_file_dirs (subj)) (call .xdg.state.home.addname_file_dirs (subj)) ;; allow creating files in the runtime directory (call .run.search_file_dirs (subj)) (call .run.create_file_dirs (subj)) (block exec (blockinherit .file.exec.template) ;; Label the weechat executable itself. ;; This along with some macros we called earlier cause executing weechat to transition to ;; the weechat.subj context. (filecon "/usr/bin/weechat" file file_context)) (block data ;; This macro will be called at some point and is what makes the files and directories ;; weechat creates in ~/.config and such transition to .weechat.data.file type from ;; .home.file. (macro xdg_file_type_transition_file ((type ARG1) (class ARG2) (name ARG3)) (call .xdg.config.home.file_type_transition (ARG1 file ARG2 ARG3)) (call .xdg.cache.home.file_type_transition (ARG1 file ARG2 ARG3)) (call .xdg.share.home.file_type_transition (ARG1 file ARG2 ARG3)) (call .xdg.state.home.file_type_transition (ARG1 file ARG2 ARG3))) (blockinherit .file.home.template) (filecon "HOME_DIR/\.config/weechat(/.*)?" any file_context) (filecon "HOME_DIR/\.local/share/weechat(/.*)?" any file_context) (filecon "HOME_DIR/\.local/state/weechat(/.*)?" any file_context) (filecon "HOME_DIR/\.cache/weechat(/.*)?" any file_context)) (block run ;; This is similar to the file type transition macro above, but for runtime files instead ;; of config and state files. (macro file_type_transition_file ((type ARG1) (class ARG2) (name ARG3)) (call .run.file_type_transition (ARG1 file ARG2 ARG3))) (blockinherit .file.run.template) (filecon "/run/user/%{USERID}/weechat" dir file_context) (filecon "/run/user/%{USERID}/weechat/.*" any file_context))) ;; we want files and dirs weechat creates to be of the weechat type so we call our ;; type transition macro. (call .weechat.data.xdg_file_type_transition_file (.weechat.subj dir "*")) (call .weechat.data.xdg_file_type_transition_file (.weechat.subj file "*")) ;; same as above but for runtime files (call .weechat.run.file_type_transition_file (.weechat.subj dir "weechat")) (call .weechat.run.file_type_transition_file (.weechat.subj file "*"))