 So, hello, everyone. Good afternoon. My name is Roberto Sasso. I am Senior Engineer at Huawei. Today I would like to present InfoFlow LSM. It's a new Linux security module that specifically enforces integrity policy. This is only a piece of the puzzle of a solution that allows us to have a stable PCR in a system, in a legacy system, which perform integrity measurements with AIMA. And enable us to have a ceiling policy for TLS key. This TLS key can be used only with a good software configuration. But today we talk about only this part for the enforcement of the integrity policy. Why we need the enforcement of integrity policy? Why InfoFlow LSM? Then I will give an overview of the security module and the demo and the conclusion. Why we need an integrity policy? Basically, we have a standard AIMA. This is the left cycle of mutable files. Initially, the content is known, and when the reader reads this file, this can be recognized from a list of reference measurements. However, after the first access, there are some writes. Then the content of the file is not known anymore, and at the next reader, then we get in the measurement list these new digest, and this cannot be verified. So we send it to a remote verifier. The remote verifier checks the digest, and it sees that there is no reference measurement for that. So I will solve this problem. First, we give you some definition. So we intend integrity as the ability of a software to behave as intended by the developer. Integrity policy is a set of a rule that allows us to preserve the integrity of a software. And the trusted computing base is the set of a subject and object, which don't violate the rules of the integrity policy. Particularly, which policy we want to enforce? First, we want to enforce Clark Wilson. The first rule is that no read down, so a subject should not read an object with a lower integrity level outside the PCB, because potentially this file can contain malicious data, and then the software can be corrupted. No write up. So a process outside the PCB should not be allowed to write a file inside the PCB for the same reason, because it may inject malicious data, and the process inside the PCB may be corrupted from this. And third, we have a filtering interface, so we allow some violations, so we allow a subject inside the PCB to read potentially malicious data with a condition that this subject has a filtering interface, so it does not become corrupted when it reads this file. So when we enforce the Clark Wilson policy, we know exactly which subject and object are in the PCB, so we are now considering a mutable file inside the PCB, and we have a reader which reads the file for the first time, so the file is known and the digest is known. And then the malicious control, so the Linux security model, depending on, so if the subject is in the PCB, it allows the write. If the subject is not in the PCB, then we deny the write. So if all the writes are performed by the PCB, we can say that the file does not become corrupted, so the integrity of this mutable file is good. So this allows us to say, well, okay, the file was good at the beginning, so we have the initial content is known, and then the integrity of this file is preserved, so we can exclude it from the measurement, which evidence we give to the verifier then. We give the evidence of the initial content of the file, and then the monetary control policy that we are enforcing, so the fact that this file is in the PCB and which subject in the PCB can actually write this file. We also have a more complicated scheme in which we consider also the offline protection. In this scheme we have the EVM key that is used to calculate the HMAC for the file, and this EVM key is actually sealed to the MAC policy, to the monetary control policy, and to the initial value. Why? Because when we boot the system the second time, so if we provide evidence that the integrity policy is enforced, and then we have the key policy, which is bound to the initial content of the file, and the initial content of the file, then we can, even if we are in the next boot, we know that in the first boot the file was processed correctly, because it was processed by the same monetary control policy. Why? We introduced a new LSM, and why we don't use, for example, Selinux. Selinux actually can enforce the multi-level security policy, but actually it's not easy, because, for example, we have to select a different policy. I don't know if it is possible easily to specify which subject are in the TCB. So I was thinking to have a different independent security model, which allows us to define the TCB more easily. And also Selinux does not have the concept of filtering subject, so with a multi-level security policy we can enforce the BIBA integrity model, so they don't read down and don't write up rules. But, for example, if we have some violations, or if a subject in the TCB tries to read an object outside the TCB, then Selinux is not the policy language is not powerful enough to enforce this kind of rule. Also, so when we enforce the integrity policy, we have to know which are the interactions of the process, so which file are read by the process, which file are written. And if we try to discover all the process interactions with the audit subsystem, this is a particularly difficult job, because we have many duplicates permission, because auditor does not know if the same permission was requested before. So we have many logs and we have to analyze them. And also, so if we want to support the Clark Wilson policy, for example, is Mark or in Selinux, we have to apply the modification in every security model. Instead, we can do the enforcement on top of a different security model. So we can enforce this integrity policy and we use the LSM stocking capability to do that. So we don't modify the Selinux policy or the Mark policy, and we define our own policy to do the integrity enforcement. In for the LSM, as three main model of operation, discover to know to see which are the operations requested by the processes, and to enforce the Clark Wilson policy on the TCP and on the mutable files. And permissive, so we check if the process operation, if they've violated the integrity policy, and we record the violation. So this is to modify the policy in case, for example, we need to add more processing into the TCP. So this is what happens in the system when we have multiple security models. In this case, we have a lower Linux security model, which is a Linux Mark. They continue to do their own enforcement based on their own policy. And then we have InfoFlow LSM on top, and it performs the decision depending on its own policy. And LSM framework works in a way that the final decision depends on the decision of each security model. So when we are checking the permission on the node, after the Linux determines if the permission should be granted or not, then we ask the LSM framework, which are the security identifiers of the process, which is accessing the file and the security identifiers of the node itself. And then we pass these two security identifiers in the operational request, so if it is a read or write or read write to our decision module. And our decision module asks another module called InfoFlow CTX, if the subject and the object are in the TCP, because this is needed to perform the decision depending on the decision policy. So we get this information, and then we perform the decision. Actually, if an object is in the TCP or not, it depends on two information. One is the label, the policy, and the other source of information is the extended attribute. So we have an extended attribute that we use to determine if the file was created by the TCP. Now the decision part. So this is the Biba write up rule. So if a TCP subject writes a TCP object, this operation is denied. The same for Biba read down. So a TCP subject read or execute a non-TCB object, this operation is denied. Or if a subject tries a TCP subject, try to read an object which is not filtered, which is outside the TCP and does not have a filtering interface, then also this operation is denied. So this is the format of the InfoFlow SM policy. So we have a TCP object equal to security context, which is a Selenux or SMAC label, and we use it to say that the object is in the TCP. TCP is a subject equal to a sexityx to put a subject in the TCP. And we have the last type of rules, which is filter object equal to sexityx. So this object is a filter, meaning that this object is potentially malicious and we have to check if the subject has a filtering interface to read this file without being corrupted. Actually, we have two types of filters. For example, in the kernel we have DevNull. We can write to DevNull and we can read from DevNull. In this case, it's a filtering interface because it is the kernel, which is doing desanitization, so we don't get bad data from the kernel. So in this case, we are saying that every object can read from DevNull without being corrupted. Or we specify for an object which potentially is malicious, the set of subjects which allow it to read the object without being corrupted. So we now load the policy into InfoFlow LSM. We parse the rule, like any other LSM. And we are adding the security context. So we are discovering the interaction using the serinux or smak label. So this is the input that we give to InfoFlow CTX. And we are adding subject and object to the PCB and also we are setting the filtering subject. And lastly, we are adding this information in memory so that the security decision can be calculated when a file is assessed. So lastly, we are not able to determine precisely all the objects that are in the PCB. For example, when we have a subject in the PCB, the label of the new object depends on the label of the parent, the process which is creating the file plus the label of the parent directory. So in this case, we are saying if a subject is in the PCB, let's add also the object to the PCB regardless of its label. We are marking the file as PCB, but this does not depend on the policy. It is decided at file creation time and we are marking this file as... this is in the PCB. So we check first if the subject which is creating the file is in the PCB. And then we are setting a new extended attribute in which we say this file is in the PCB. Actually, we are using a bit mask. We are setting a bit to one, saying, OK, this file, this bit means... if this bit is set, it means that the object is in the PCB. And when we call info flow D instantiator, we are reading the extended attribute. So we are saying that when the file is visited for the first time, we are saying, OK, this file is in the PCB. For the management of the context, so we say that the policy contains a set of security context. And when we are loading the policy, we are actually converting the security context into security identifier. And we are loading this security identifier into our red-black tree. So when we take the decision, so for example in I-Node permission, and we are getting the security identifier, we know by searching in these three if the file is in the PCB or not. Now, I would like to show a case study. So we have a sample application, and we want to protect the integrity of this application. Here we have two type of files. On the top, we see a configuration file. This is an immutable file, and can be recognized with reference measurement. But as I said at the beginning, for immutable files this solution does not work, so we have to do the enforcement with integrity policy. So myapp.state actually is storing the current number of requests made by the user. So first the user, so this is a DNS resolver. So the user is asking the myapp, what is the IP address of a server? Then myapp is querying the DNS, and it is increasing the number of requests made by the user, so I am writing to myapp.state, and lastly is returning the IP address of the server to the user. So we want to protect the integrity of this application, so we have to first find the PCB of this application. And I will show how we can do it. So first we are running infoflow.sm in discovery model, so we are booting the system and checking what the processes are doing. So the system is booting. OK. And now the output of infoflow.sm is this. So this is the set of operation that are performed by the system while the system is booting. And as you can see we are using, those are the Selinux label attached to the process into the file. So we are also considering the class, for example we have a regular file and we have also, let's see, we have also socket, for example, so we are considering different type of classes. Now I execute myapp. We are asking the address of google.com and we are getting the current number of requests from the user and we are getting the IP address. So now we discovered all the interaction, included the interaction performed by myapp and now we want to see, we want to find the tcb for myapp. So we are copying this interaction to a file and now we determine the tcb for myapp. So this is a user space tool that takes as input the process interaction that we discovered and we pass to it the application that we want to protect. So this tool is analyzing the process interaction and the output of this tool is this. So now we have, the target of our evaluation is myapp and we see that myapp is reading a file, resolver.conf, which is written by network manager. But since network manager is not yet in the tcb because now the tcb is only the application we want to protect, this is an integrity conflict. Potentially network manager can write bad content to resolve.conf and can compromise myapp if we don't trust network manager. But now we are trusting a network manager. So we add network manager to the tcb. We add network manager to the tcb and we perform again the analysis of the integrity analysis. And as you can see, now the situation is much worse because we have new integrity conflicts from a process outside the tcb. So these are all the processes outside the tcb. And we see that now we have, for example, null device t, which is dev null, so we can say that all the subject can read this file and write this file without being compromised. So this is a candidate for being a filtering interface. For that, okay, let's see first. So we perform again the analysis. And now we have still some conflicts. We have these three files which are outside the tcb and those are files which are read by network manager, which is in the tcb. So we have to add the more processes inside the tcb. In particular, this tool is also suggesting which subject we have to add to the tcb. So I will add this subject. So now you see that the number of subjects which are violating the integrity policies are much more because we are adding a process to the tcb. And now we are basically solving the integrity conflicts by adding a subject to the tcb or filtering interfaces. Now I am doing some assumption. I am assuming that the process can properly filter data coming from a socket. And these assumptions are not necessarily true, but now for the, this is an example of analysis and then we need to verify this assumption. So effectively the kernel is able to filter the data coming from a socket. So now I add this as a kernel t socket as a filtering interface. I will also add init tfifofile as a filtering interface because I assume that all the communication to init are properly filtered. So init should be good enough to pass the data coming from a fifofile. So I will complete the analysis. And then the final result is, so this is the final analysis, so there are a lot of iteration and then at the end you will find set of tcb subject that don't violate the integrity policy. Now for example you will see that this is the set of data that we add to the tcb and we have only filtering interfaces so this is the interaction that you see are two objects which are outside the tcb and we are assuming that the processes inside the tcb are able to properly handle the data coming from this object. So this is at the end the list of tcb subject that we have to trust in order to have myup.state the integrity of this file is preserved. So this is the set of subject that we have to trust. And now the tool will produce the policy that we have to give to infoflow lsm as you see there is tcb object equal to security contest we have also subject equal to security contest and we have also the filtering interface and we are copying this policy to the virtual machine and now we are booting the virtual machine with the policy the enforcement enable. I will also recreate the initial and disk because we are loading the policy from the initial and disk. Now it takes few seconds so in this particular policy we are excluding the subject unconfined t. So when we log in as root the security contest that is applied to the process running to root is unconfined t. And we are excluding this process from the tcb. So since this process in the tcb is outside the tcb when we write a file which is included in the tcb we expect that the root is not able to write this file even if it is root. We boot now in enforcing mode now the system booted and we log in. As you can see this is our context unconfined t. This subject is not in the tcb. We execute again myapp myapp still works. We have the integrity enforcement enable and now we try to attack. We are trying to write the mutable file which is inside the tcb from outside the tcb so the operation is denied and now we see the reason. So this is the subject which is performing the operation. This is the object actually should have been myapp.state and this is the operation this is a bibab write up. So this process outside the tcb is writing something inside the tcb. So this operation is denied. As you can see this is a Fedora 30 operating system which is enforcing the Syrinux policy so we are not touching the Syrinux policy but we are doing additional enforcement on top of it. And we are doing this enforcement with this new infoflow lsm. So conclusion. We publish the code of of this new software. This is published in our github repository. We also publish the user space too to find the tcb from process interaction. And this currently under development yesterday I sent the first version of the kernel module and I kindly ask you to have a look at the code and provide any feedback. Possible optimization. Now we are checking if a subject is in the tcb or not. For every I know the permission every time I know the permission is called. Well this means that we are doing a search in a red-black tree for every permission request. Actually we can use the lsm stacking feature to store if a subject in the tcb only in specific hooks. For example when we have BPR installed creds so when the new credential is installed to a process then we can check at that point if the subject is in the tcb so we don't have to do every time in order permission. That will be an improvement and that's it. Yes, now we are for example this is the list of filtering interface that we considered. For example we have these ptmx which are the control device to set the terminal or we have actually for example this FIFO file that I mentioned before and so for example we have a dev init ctl which is the interface I think is used for a process to signal to do some signaling to systemd. And I assume that this is a filtering interface because if systemd is corrupted every time that a process communicates with it then probably systemd should do a better job to filter the data because systemd is the most important process in the system. So I'm doing the assumption that the systemd developers write a very a very good pass for the data that is coming from init ctl. Test. So a filter is just something that you're specifying in the the analysis. So it's it's basically whatever you're saying, so I could just say if I wanted to just any as the elonics context is a filter and that it would be treated thusly in your policy. So you're making assumption and you're saying to the remoto, so when you are doing remoto testation you are sending this policy in that you are developing. And the remoto verifier can say I trust systemd to do the filtering of the data coming from init ctl, then for me the remoto testation is a success. Or there is a remoto verifier which has more strict requirements and may say I don't trust that systemd is able to properly filter data coming from any process. So for me the testation fails. So this is a remoto testation. So it's not a fixed result but the result of the outcome of the remoto testation depends on the requirements of the verifier. So you as a platform that is being verified you are sending all the data necessary for the verification and it's up to the verifier to decide if it's acceptable for him or not. So the part you were talking about earlier where after the reboot you were able to know that you didn't want to measure for a while. So I'm trying to understand so my assumption is the system gets compromised at some point. Remoto testation must detect that the system was tampered with. How, what is I didn't understand what happened across the reboot that you would be able to detect when the system was tampered with. So we can run info flow in two modes. One is enforcing mode which means when there is an operation potentially corrupt mutable file, we are denying the operation. So we are saying the process outside the TCP is not allowed to write a file inside the TCP. Or we can have the permissive mode in which we allow the operation but we update the PCR. So we have a TPM, we are using a TPM key and this TPM key is sealed to a set of PCR. So in the permissive mode we are saying we can allow the operation but we change the PCR so it means that the TPM key that is bound to a policy is not usable anymore. But an attacker who compromises the system in a way that is not detected by info flow LSM will not modify the PCR and after the reboot the key will still unseal the same and you will say oh remote attestation you need to trust me because I am not tampered with. But how the attacker is able to any other vulnerability anywhere else in the system. So the attacker didn't compromise the system by writing to the one file you are protecting. I exploited some vulnerability elsewhere in the kernel. We are making an assumption. But my assumption is remote attestation must be able to detect whether or not the system is in a good state or not. In the case of a remote attestation system that is based on predetermined hashes or signatures that you can't tamper with on the device no attacker can simulate a signature from a key in my vault ever. An attacker can never do that no matter how much they compromise the kernel. But that attestation of the locally modified file I have no way of trusting that I don't understand why this is any better than just a plain SE Linux policy. Because the Selenux policy is not enforcing any integrity policy. So the TCB is something which we are defining depending on for example the reputation of the process. So we trust system D or we trust Apache but we don't trust POSFIX. So we are doing on the device that we want to attest. We are making our assumption but it doesn't mean that this assumption are accepted by the verifier. So our goal is just to enforce the integrity policy according to our policy. If the policy is not acceptable sure then the attestation fail. So how does this come into play in offline tampering of the files so when your system is not running that's one question and two actually so how does this work across K exec and other scenarios actually so in your current kernel. In this particular presentation I didn't mention offline protection or at least I just briefly mentioned but I didn't want to make the presentation too complicated because this topic itself but for the offline protection we are using EVM and so I said that we don't measure the file if it is a mutable file we don't measure it anymore but we have so how IMA determines if the file should be measured or not because we are attacking we are attaching to each file the HMAC and the key used to calculate this HMAC is sealed to a software configuration so you can actually get the EVM key only if the system is enforcing the integrity if only the initial content is allowed so only if the file is good so we are taking reference measurement from the distribution so we have an empty file or a file with an header and this is the initial file and we allow the system to access only this so the file must be in a known state and the EVM key can be unsealed only if all these conditions are met then when we reboot if we find HMAC it means that in the previous boot also the system was enforcing the integrity was reading a file shipped by the Linux distribution and we can continue to grant access to the file and we don't measure it the goal is to have a stable PCR like Paul said in a system which is performing file measurement and there is only one part of the story because so we are not measuring mutable file we are also using a whitelist approach to say that we measure the whitelist at the beginning when the kernel starts and we are not doing footer measurement so if we have whitelist for the immutable files this scheme with the integrity policy for the mutable files so the PCR remains stable if we have the permissive mode so we are allowing integrity violation then the PCR will change and then we are not able so for example we delete the EVM key so the system is not able to calculate the valid HMAC anymore so we are tampering at the next boot so are you doing your integrity check before or after the mandatory access control checks? after then you are not going to get called if the mandatory access control check fails no, no, no so if Selinux denies the operation we are not getting the operation in our module we are not touching the Selinux enforcement so we are doing enforcement on top right, but if in the module stack the the SC Linux gets called before you do and the SC Linux denies the access then you are not going to get called no, no, no, no yes but for us ok so if the interaction does not happen it is not so the processor cannot corrupt a file because it is Selinux first which is denying the operation that makes sense for enforce but for audit when you are trying to build the model in the first place you have to just turn off SC Linux enforcement to build that full audit log or we can have a combination of both meaning that we assume that the policy does not change from the discovery to enforcement but I am just saying in order to get a complete discovery to really build the correct TCP you need to disable SC Linux enforcement yes, it will be helpful you shouldn't have to be able to disable SC Linux enforcement you can stick your module in before SC Linux and have it being called before SC Linux and have SC Linux come after in the stack yes because the Selinux label are applied not in the permission requests but they are applied in different hooks different hooks yes, good work thanks ok, thank you