a h@slddlmZddlZddlmZddlZgdZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlTddlmZddlTddlTddlTddlTdZddZd d Zd d Ze d ZddZe dZddZddlZddZGddde Z!Gddde Z"Gddde Z#GdddZ$Gddde Z%Gdd d e&Z'Gd!d"d"Z(d#d$Z)dS)%)absolute_importN)range) derive_record_formatparse_audit_record_text AvcContextAVC AuditEventID AuditEvent AuditRecordAuditRecordReader compute_avcs)*cCs||k||kSN)xyrr=/usr/lib/python3.9/site-packages/setroubleshoot/audit_data.py7rcCs t|\}}}}t|||}|Sr)rr )textparse_succeeded record_typeevent_id body_text audit_recordrrraudit_record_from_text=s rcCs*td|rtjStd|r$tjStjS)Nz/audispd_events$z/audit_events$)researchr TEXT_FORMAT BINARY_FORMAT)Z socket_pathrrrrEs   rzL(node=(\S+)\s+)?(type=(\S+)\s+)?(msg=)?audit\(((\d+)\.(\d+):(\d+))\):\s*(.*)c Csd}d}d}d}d}t|}|durd}|dr>|d}|drR|d}|drt|d}t|d}t|d} t||| |}|d }||||fS) NFT )audit_input_rergroupintr) inputrhostrrrmatchsecondsmilliserialrrrr^s&       rz%audit\(((\d+)\.(\d+):(\d+))\):\s*(.*)cCsvd}d}d}t|}|durld}|drbt|d}t|d}t|d}t|||}|d}|||fS)NFTr!rr")audit_binary_input_rerr)r*r)r+rrrr-r.r/r0rrrparse_audit_binary_text|s    r4cCs"|rdd|D}||krdSdS)NcSsg|]}|tjvr|qSr)string printable.0rrrr rzprintable..TFr)sZ filtered_pathrrrr6s r6csZeZdZddiddiddiddidZfddZddZdd Zd d Zd d ZZ S)rXMLForm attributeuserroletypemlscsztt|t|tjrv|d}t|dkrv|d|_|d|_ |d|_ t|dkrpd |dd|_ nd|_ dS)N:rrr1r!Zs0) superr__init__ isinstancesixZ string_typessplitlenr>r?r@joinrA)selfdatafields __class__rrrDs       zAvcContext.__init__cCsd|j|j|j|jfS)Nz %s:%s:%s:%sr=rJrrr__str__szAvcContext.__str__cCstt|\}}|Sr)selinuxZselinux_raw_to_trans_contextstr)rJrcZtransrrrformatszAvcContext.formatcCs || Sr)__eq__rJotherrrr__ne__szAvcContext.__ne__cCs2t|jD]}t||t||krdSqdSNFT)list _xml_infokeysgetattr)rJrWnamerrrrUszAvcContext.__eq__) __name__ __module__ __qualname__r[rDrPrTrXrU __classcell__rrrMrrs rcsveZdZdeddeddedddidZdfdd Zdd Zd d Zd d Ze ddZ ddZ ddZ Z S)rr<r;import_typecastr;)r.r/r0r,Ncs2tt|||_||_||_|dur.||_dSr)rCrrDr.r/r0r,)rJr.r/r0r,rMrrrDs zAuditEventID.__init__cCsD|j|jkrdS|j|jkr dS|j|jkr0dS|j|jkr@dSdSrY)r,r.r/r0rVrrrrUs    zAuditEventID.__eq__cCsb|j|jkr&td|jj|j|jf|j|jkr>|j|jkS|j|jkrV|j|jkS|j|jkS)Nz?cannot compare two %s objects whose host values differ (%s!=%s))r, ValueErrorrNr_r.r/r0rVrrr__lt__s     zAuditEventID.__lt__cCsddl}||SNr)copy)rJrhrrrrhszAuditEventID.copycCst|j|jdS)N@@)floatZsecr/rOrrrrrzAuditEventID.cCsd|j|j|jfS)Nzaudit(%d.%d:%d)r.r/r0rOrrrrPszAuditEventID.__str__cCs.|jdurdS|jdurdS|jdur*dSdSrYrkrOrrris_valids   zAuditEventID.is_valid)N)r_r`rar*r[rDrUrfrhpropertytimerPrlrbrrrMrrs   rcseZdZddidedddideddZdZdZe eZ e dZ e d Ze d Zd*fd d ZddZddZddZddZddZddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)ZZS)+r r;r<elementrc)rrr line_numberrZiiiiz([^ \t]+)\s*=\s*([^ \t]+)z$avc:\s+([^\s]+)\s+{([^}]+)}\s+for\s+z^a\d+$Ncs8tt|||_||_||_||_||_|dSr) rCr rDrrrrLrp_init_postprocess)rJrrrrLrprMrrrDszAuditRecord.__init__cCsrt|dddur||j|jdvrnd|jvrntj|j}|rn|d}||jd<|d}| |jd<dS)NrLrZUSER_AVCZ1400Z1107seresultr1r!seperms) r]set_fields_from_textrrrLr avc_rerr)rG)rJr-rsrtrrrrqs      zAuditRecord._init_postprocesscCs|Sr) to_host_textrOrrrrP(szAuditRecord.__str__cCs d|_|jjdurt|j_dSr)rprr,Z get_hostnamerOrrraudispd_rectify+s zAuditRecord.audispd_rectifycCs.|jsdS|jdurdS|jdur*dSdSrY)rrlrmessagerOrrrrl0s   zAuditRecord.is_validcCs4|jd}|dkrdS|dkr"dStjd|dS)NrsZdeniedFZgrantedTz!unknown value for seresult ('%s'))rLlogZavcwarn)rJrsrrr is_granted9s zAuditRecord.is_grantedcCsgd}|D]>}||jvr |jdkr.|dkr.q |j|}t|}||j|<q |jdkrt|jD]0\}}|j|rd|j|}t|}||j|<qddS)N)ZacctcmdcommcwdrKdirexefiler,keymsgr^newZocommoldpathZwatchrZsaddrZEXECVE)rLrZaudit_msg_decoderZitems exec_arg_rer)rJZencoded_fieldsZfieldvalueZ decoded_valuerrr decode_fieldsBs      zAuditRecord.decode_fieldscCsFz0tjddkr|dWSt|dWSWn|YS0dS)Nrrhexzutf-8)sys version_infodecode bytearrayfromhexrJrrrr translate_hexVs  zAuditRecord.translate_hexc Csg|_i|_tj|D]}|d}|d}|d}z|dkr^tt |d}t |}|dvr|d ds| |}|dkrzt jtt |}Wn Yn0|dkrtt |t}|r|}WntyYn0||j|<|j|qdS) Nr1r!"arch)r^rr~r}rrexitsyscall) fields_ordrLr key_value_pair_refinditerr)stripauditZaudit_elf_to_machiner*Zaudit_machine_to_name startswithrerrno errorcodeabsZaudit_syscall_to_nameZaudit_detect_machinereappend)rJrr-rriZ syscall_namerrrrues4       z AuditRecord.set_fields_from_textcCs |j|Sr)rLget)rJr^rrr get_fieldszAuditRecord.get_fieldcCs"t|}ttjtjtj|j|Sr)rHstructpackr binary_header_formatbinary_versionbinary_header_sizer)rJr msg_lengthrrrget_binary_headers  zAuditRecord.get_binary_headercsjjdurdSjdkr4djjdjf}ndjjf}|dfddjDd7}|S) Nrz#type=%s msg=%s: avc: denied { %s }  ztype=%s msg=%s: csg|]}d|j|fqS)z%s=%s)rL)r8krOrrr9rz.AuditRecord.fields_to_text.. )rLrrrIaccessr)rJbufrrOrfields_to_texts  "zAuditRecord.fields_to_textcCsd|j|j|jfS)Nztype=%s msg=%s: %s )rrrrOrrrto_textszAuditRecord.to_textcCs2|jjdur&d|jj|j|j|jfS|SdS)Nznode=%s type=%s msg=%s: %s )rr,rrrrOrrrrws  zAuditRecord.to_host_textcCsd|j|jf}|||S)Nz%s: %s)rrrrJrecordrrr to_binaryszAuditRecord.to_binary)NN) r_r`rarr*r[rrrcalcsizerrcompilerrvrrDrqrPrxrlr|rrrurrrrrwrrbrrrMrr s4       " r c@s,eZdZdZdZddZddZddZd S) r r1r!cCsV||_d|_d|_|j|jkr(|j|_n*|j|jkr>|j|_ntd||j j fdS)Nrrz unknown record format (%s) in %s) record_format _input_bufferrpr feed_textZfeedr feed_binaryrerNr_)rJrrrrrDs    zAuditRecordReader.__init__c cst|dkrdS|j|7_t|jtjkr2dSttj|jdtj\}}}}tj|}t|j|krpdS|jtj|}t|\}} } |j|d|_|rt || | ddfVqdSrg) rHrr rrunpackrr4rZaudit_msg_type_to_name) rJnew_datarrrrZ total_lenrrrrrrrrs$    zAuditRecordReader.feed_binaryc cst|dkrdS|j|7_d}|jd|}|dkr|jd7_|d7}|j||}t|\}}}}|r|||d|jfV|}|jd|}q0|j|d|_dS)Nrrr1)rHrfindrpr) rJrstartendlinerrrrrrrrs  zAuditRecordReader.feed_textN)r_r`rar rrDrrrrrrr s  !r cseZdZddeddeddZfddZdd Zd d Zd$d dZ ddZ e ddZ ddZ ddZd%ddZddZddZddZd d!Zd"d#ZZS)&r ror)r;rZrdrc)recordsrcs*tt|d|_g|_i|_d|_dSr)rCr rDrr record_types timestamprOrMrrrDs zAuditEvent.__init__cCs0t|ddduri|_|jD]}||qdS)Nr)r]rrprocess_recordrrrrrqs zAuditEvent._init_postprocessc CsL|j}|d|j||ddd|Dddd|jDfS)Nz2%s: is_avc=%s, is_granted=%s: line_numbers=[%s] %s,cSsg|] }t|qSrrRr7rrrr9rz&AuditEvent.__str__..rcSsg|] }d|qS)z %srr8rrrrr9r) line_numberssortris_avcr|rIr)rJrrrrrP szAuditEvent.__str__rcCs|dd|jDS)NcSsg|] }t|qSrrrrrrr9rz%AuditEvent.format..)rIr)rJ separatorrrrrTszAuditEvent.formatcCs t|jSr)rHrrOrrr num_recordsszAuditEvent.num_recordscCsdd|jDS)NcSsg|]}|jr|jqSr)rprrrrr9rz'AuditEvent...)rrOrrrrrzAuditEvent.cCs|j|||dSr)rrrrrrr add_records zAuditEvent.add_recordcCsp|jdur2|j|_t|jj|jjd|_n |j|jksRtd|j|jf|j|j g}| |dS)NrizBcannot add audit record to audit event, event_id mismatch %s != %s) rrhrjr.r/rrer setdefaultrr)rJrZ record_listrrrrs    zAuditEvent.process_recordNcCsRg}|dur|j}n ||}|D]*}|j|}|durd?Z3d@dAZ4dBdCZ5dDdEZ6dS)Grr]execute)openreadr]lockioctl)rrr]rrr)rrrr]rr)r]linkunlinkrename)createrr]setattrrrr) rrrrr]rwriterrrrr)rrr]rrr) rrr]rrradd_name remove_namer)rrr]rrrrr)rrrr]rrrrrrrrrreparentrrmdir)ZmountZremountZunmountr]rr)rr]rrrr)rr]rrrrr)rr]rrrrr)rrr]rrrrrrrrrrrrr)rr]rrr)rr]rrr)rr]rrrr)rr]rrrrrr) rrr]rrrrrrrrrz^(\w+):\[([^\]]*)\]z^(/proc/)(\d+)(.*)NTcCs||_||_i|_d|_d|_d|_d|_d|_d|_d|_ d|_ d|_ g|_ g|_ d|_d|_d|_d|_d|_g|_||dSr) audit_eventquery_environmenttemplate_substitutionstpathspathsource source_pkgrscontexttcontexttclassportsrc_rpmstgt_rpmsr,pidkmodrwhybools derive_avc_info_from_audit_event)rJr avc_recordrrrrrDs*z AVC.__init__cCs|Sr) format_avcrOrrrrPsz AVC.__str__cCsNd}|d|j7}|d|j7}|d|j7}|d|j7}|d|j7}|S)Nrz scontext=%s z tcontext=%s z access=%s z tclass=%s z tpath=%s )rrrrr)rJrrrrrszAVC.format_avccCs,|jdurdS|jD]}||vrdSqdS)zMReturns true if the AVC contains _any_ of the permissions in the access list.NFTrrJZ access_listarrrhas_any_access_ins   zAVC.has_any_access_incCs,|jdurdS|jD]}||vrdSqdS)zmReturns true if _every_ access in the AVC matches at least one of the permissions in the access list.NFTrrrrrall_accesses_are_ins   zAVC.all_accesses_are_inc Cstt}|t}|g}ddddttgt|jjt |j t |j iDD}|}|D]$}||vrb| ttt|dqb|D]}||vr||vr||q||S)NcSsg|] }|tqSr)ZTARGETr7rrrr9rz,AVC.allowed_target_types..cSsg|]}|dr|qS)Zenabledr)r8rrrrr9rtypes)Zget_all_file_typesZget_all_port_typesrZget_all_attributesrALLOWSOURCErr@ZCLASSrZPERMSrextendnextinfoZ ATTRIBUTEr)rJZ all_typesZall_attributesZ allowed_typesZwtypesrtrrrallowed_target_typess  4 zAVC.allowed_target_typescCsB|dgr>z$|jr.t|jt@tjkr.WdSWn Yn0dS)NrTF)ra1r* O_ACCMODEosO_RDONLYrOrrropen_with_writes  zAVC.open_with_writecCs"|D]}t||jrdSqdS)NTF)rr-r@)rJcontext type_listr@rrrZ __typeMatchszAVC.__typeMatchcCs|jdurdS||j|S)zReturns true if the type in the source context of the avc regular expression matches any of the types in the type list.NF)r_AVC__typeMatchrJr rrrmatches_source_typess zAVC.matches_source_typescCs|jdurdS||j|S)zReturns true if the type in the target context of the avc regular expression matches any of the types in the type list.NF)rr rrrrmatches_target_typess zAVC.matches_target_typescCs|jdurdS|j|vS)NF)r)rJZ tclass_listrrr has_tclass_ins zAVC.has_tclass_incCs||dSr)derive_environmental_info%update_derived_template_substitutionsrOrrrupdatesz AVC.updatecCs t|j Sr)is_standard_directoryrrOrrrpath_is_not_standard_directorysz"AVC.path_is_not_standard_directoryc Cs|jd}|jd}|jd}|dur|jd}|D]D}|d}|rX|dkrXq<|d}|r<|r<|dkr<||r<qq<|rtj|s|durtj|rtjtj ||}|dur"|jd}|dur"|jd}|d krd |}n(|d kr|d kr|}nd |}n|}|dur|d kr|rg} zd } |jd} tj d| rvt d| j } t |} tdd} | dD]}|}t|r|dd d krzP| d kst|d j | kr t t |dj| kr | |ddWnty(YqYn0q| t| dkrR| d d}nt| dkr| D]}|d d| ks|d| kr|d}qnJz4| d krt |d j | kr|d}WqWntyYn0qdWn.tyd}Yntyd}Yn0n|d dkr|rd dl}ddd|g}zl|j||jdd}t |} |dD]B}z&t t |j| kr|}WqWntyYn0qlWntyYn0|dur$tj|r|jd|}n4|j |}|r|j!}|d dkr$d |"d}||_#|j#dur~|j!d!krJd"|_#n4|j!d#ksb|j!d$krtt$d%|j%|_#n t$d&|_#dS)'aDerive the target path. If path information is available the avc record will have a path field and no name field because the path field is more specific and supersedes name. The name field is typically the directory entry. For some special files the kernel embeds instance information into the file name. For example 'pipe:[1234]' or 'socket:[1234]' where the number inside the brackets is the inode number. The proc pseudo file system has the process pid embedded in the name, for example '/proc/1234/mem'. These numbers are ephemeral and do not contribute meaningful information for our reports. Plus we may use the path information to decide if an alert is identical to a previous alert, we coalesce them if they are. The presence of an instance specific number in the path confuses this comparison. For these reasons we strip any instance information out of the path, Example input and output: pipe:[1234] --> pipe socket:[1234] --> socket /proc/1234/fd --> /proc//fd ./foo --> ./foo /etc/sysconfig --> /etc/sysconfig r^rinoNPATHZnametypeZPARENTrr%sr/rdevz/dev/z /proc/mountsrrr1rz/dev/%sr!zunknown mountpointFZlocatez-bz\%sT)stderrZuniversal_newlinesz \1\3@Z filesystemrZ udp_socketZ tcp_socketzport %sZUnknown)&rrrrendswithrrisabsnormpathrIexistslstatst_rdevr*rrrGrHstatst_inorOSErrorclose TypeErrorr subprocessZ check_outputZSTDOUT Exceptionproc_pid_instance_resubpipe_instance_path_rerrrr_r)rJrr^rZinodestrZavc_path_recordsZavc_path_recordrrmatchesZdev_rdevrrfdrrr+Zcommandoutputrr-rrr _set_tpaths       $           :        zAVC._set_tpathc Csd|_d|_d|_d|_d|_g|_d}}}}|r@||_n |j|_|j d}|j d|_ t |j tst|j d|_ t |jtst|j d|_|j d|_|j ddur|j d|_n|j d|_|j d |_|j d |_|r<| d }| d }| d |_| ddk|_| d|_|durR|j d }|durh|j d }||_|r|||_n|r|j|_|js|j|_|js|j j|_|j d}|r| d}nd}|||jd} | D]H} | d} tj| s |s|j| n|jtj|| qg|_g|_|jjj |_ t!"t#|j t#|jt#|j|j \|_$} |j$t!j%krt&t'd|j|j$t!j(krt&t'd|j|j$t!j)krt&t'd|j$t!j*krt&t'd|j|j$t!j+krt&t'd|j|j$t!j,kr.t&t'd|j|j$t!j-krNt&t'd|j|j$t!j.krht&t'd|j$t!j/kr|| |_0dS)NFZSYSCALLrtrrrdestsrcrrrr~rsuccessZyesrZCWDrrr^z8%s **** Recorded AVC is allowed in current policy **** zh%s **** Recorded AVC is dontaudited in current policy. 'semodule -B' will turn on dontaudit rules **** zMust call policy_init firstz.%s **** Invalid AVC: bad target context **** z.%s **** Invalid AVC: bad source context **** z*%s **** Invalid AVC: bad type class **** z*%s **** Invalid AVC: bad permission **** z&Error during access vector computation)1rrrrr7Z syscall_pathsrrrrrrrErrrrrrrrr@r4rrrr!rrIrrrr, audit2whyZanalyzerRrrrr0Z DONTAUDITZNOPOLICYZBADTCONZBADSCONZ BADTCLASSZBADPERMZ BADCOMPUTEZBOOLEANr) rJrrr~rrZsyscall_recordZ cwd_recordrZ path_recordsZ path_recordrrrrrrs                   *  z$AVC.derive_avc_info_from_audit_eventcCsT|jrP|jr,t|j|_|jr,|j|jt|jsPt|j}|rP|j|dSr) rrZget_package_nvr_by_file_pathrrrrrr)rJZrpmrrrrs   zAVC.derive_environmental_infocCs|jdur||_dSr)rrrrr set_alt_paths zAVC.set_alt_pathcKs(t|D]\}}|r ||j|<q dSr)rZrr)rJkwdsrrrrrset_template_substitutionsszAVC.set_template_substitutionscCsVt|jj|jd<t|jj|jd<t|j|jd<t|j|jd<|jrdtddt|j|jd<t|j |jd<|j rtddt|j |jd <|j durd|jd <nJ|j d krt|j |jd <n.|j d krtt j |j |jd <n d|jd <t|j |jd <|jdurd|jd<ntd|j|jd<t|j|jd<t|j|jd<dS)NZ SOURCE_TYPEZ TARGET_TYPErZ SOURCE_PATHr.ZFIX_SOURCE_PATHZ TARGET_PATHZFIX_TARGET_PATHZ TARGET_DIRrrZ TARGET_CLASSZACCESSZSOURCE_PACKAGEZ PORT_NUMBER) escape_htmlrr@rrrrrr.rrrrdirnamerrIrrrOrrrr$s,       z)AVC.update_derived_template_substitutionscCs6t|jD]"\}}|durtt||j|<qdSr)rZrrr=Z default_text)rJrrrrrvalidate_template_substitutionsCsz#AVC.validate_template_substitutions)NT)7r_r`raZstat_file_permsZ x_file_permsZ r_file_permsZ rx_file_permsZ ra_file_permsZlink_file_permsZcreate_lnk_permsZcreate_file_permsZ r_dir_permsZ rw_dir_permsZ ra_dir_permsZcreate_dir_permsZmount_fs_permsZsearch_dir_permsZgetattr_dir_permsZsetattr_dir_permsZlist_dir_permsZadd_entry_dir_permsZdel_entry_dir_permsZmanage_dir_permsZgetattr_file_permsZsetattr_file_permsZread_file_permsZappend_file_permsZwrite_file_permsZ rw_file_permsZdelete_file_permsZmanage_file_permsrrr/r-rDrPrrrrr r rrrrrr4rrr9r;rr?rrrrresf       "f rc Csg}zvdD]l}||}|D]X}z|t||Wqtyr}z&ddl}||jd|WYd}~qd}~00qq WnRty}z:ddl}ddl}||jd|t| WYd}~n d}~00|S)Nrrrrz!Unable to process audit event: %s) rrrrsyslogZLOG_ERRr, tracebackZ syslog_trace format_exc)rZavcsrrrer@rArrrr Js  0"r )*Z __future__rrFZ six.movesrr__all__rrrrrrQbase64rZselinux.audit2whyr8Zsetroubleshoot.utilZsetroubleshoot.html_utilZsetroubleshoot.xml_serializeZsepolicyrcmprrrr(rr3r4r5r6Z XmlSerializerrr r r r,rrr rrrrsP      )<*Mjh