Added old docs
This commit is contained in:
parent
b0e4422f62
commit
a786c44b90
66
docs/bc-thesis-idea.md
Normal file
66
docs/bc-thesis-idea.md
Normal file
@ -0,0 +1,66 @@
|
||||
# File subsystem with process-specific file access control for Linux.
|
||||
## The problem
|
||||
When you run a program on Linux, it can access the same files as the user account that started it, which is usually overly permissive.
|
||||
|
||||
For example, one may write a trojan, that would download all of your photos, documents, personal info, data of other programs, etc. and you wouldn't even have a way of knowing it happened.
|
||||
|
||||
At the same time, you *sometimes* would like *some* programs to have access to *some* of your files, for example if you are applying for the university, you would like your text editor to have access to application form, but you only need it when you are applying for a university, and you only need the editor to access this specific file.
|
||||
|
||||
So you have to somehow control *when* and *which* programs can access *what* file.
|
||||
|
||||
## Existing file access control solutions
|
||||
|
||||
### Linux security modules
|
||||
Kernel modules such as SELinux and AppArmor can certainly enforce rules on *which* programs can access *what* files, which certainly helps. Unfortunately:
|
||||
* They are overcomplicated (especially SELinux).
|
||||
* They have to be compiled into the kernel.
|
||||
* They give permissions forever: you have to reset them manually.
|
||||
|
||||
### Flatpaks, Snaps and similar namespace-based solutions
|
||||
When the programs themselves are isolated from the rest of the OS, it definitely helps to prevent unwanted access to the filesystem. However:
|
||||
|
||||
* To even be able to override the default filesystem access permissions the user needs to use another app (flatseal for example) or to master the CLI tools.
|
||||
* They give permissions forever: you have to revoke them manually.
|
||||
* The program has to be packaged and distributed is a specific way, which is a developer's decision.
|
||||
* **LOTS of apps need access to some files. Because the default permissions are regulated by the developer himself, it is usually easier to give entire filesystem access permissions, rather than select a specific folder that it needs.**
|
||||
|
||||
## My idea to solve the problem
|
||||
Make a program using FUSE that would control processes' access to selected files by freezing the process and letting the user to choose whether to allow the access or not.
|
||||
|
||||
From the point of view of the process files would appear completely normal, so no involvement of the developer is required.
|
||||
|
||||
When a process calls `open()` on a file that our system controls, that process would be frozen. User then uses the system's interface to either allow (and then the file is opened normally), or deny access (and then the `open()` returns `EACCES`).
|
||||
|
||||
Under the hood, the system's daemon would open some other file stored in a hidden directory with restricted "classic" POSIX permissions (I talk more about how those files are protected in the problems section). From now on, these files would be called "source files".
|
||||
|
||||
The program would keep track processes' permissions, and allow repeated access to the same file, to avoid bothering the user excessively.
|
||||
|
||||
Also, because the program is running fully within userspace, it will make it far easier to develop, interface with, install and distribute.
|
||||
|
||||
## Problems
|
||||
|
||||
See `bc-thesis-problems.md` .
|
||||
|
||||
## (Proposed) time plan
|
||||
* before 31.10 - A sort of "security risk assessment" and therefore a review of requirements, since this kind of is a security project.
|
||||
* before 30.11 - Architecture and design.
|
||||
* before 28.01 - Implementation.
|
||||
* before 31.02 - Testing.
|
||||
* before 30.03 - The thesis itself.
|
||||
|
||||
Rest of the time is reserved for unexpected problems.
|
||||
|
||||
Since the "buisness analysis" and requirements are already more than half-ready, I am not including them.
|
||||
|
||||
## Formal specification
|
||||
Name:
|
||||
|
||||
`File subsystem with temporary, process-specific file access control policies for Linux.`
|
||||
|
||||
Goal:
|
||||
|
||||
`Develop and implement a virtual file subsystem that would manage and enforce temporary, process and file specific rules and policies regulated by the user's choice, therefore ensuring greater security by restricting arbitrary file access by processes.`
|
||||
|
||||
[^1]: I haven't found any better information on that topic. The solutions mentioned seem overcomplicated.
|
||||
[^2]: Which is obtained through 22-nd field in /proc/\[pid\]/stat (see `man proc_pid_stat(5)`).
|
||||
[^3]: To the best of my knowledge.
|
78
docs/bc-thesis-problems.md
Normal file
78
docs/bc-thesis-problems.md
Normal file
@ -0,0 +1,78 @@
|
||||
|
||||
# Problems
|
||||
## Keeping track of running processes
|
||||
Since [we can't simply be notified about random process's termination](https://stackoverflow.com/questions/15275366/how-to-get-notified-on-termination-of-some-another-process-in-linux)[^1], the question arises: how to keep track of the processes in the permission table?
|
||||
If we don't delete a permission table entry exactly before the process finishes, another process, [intentionally](https://stackoverflow.com/questions/18122592/how-to-set-process-id-in-linux-for-a-specific-program) or not, gets the same PID, it would gain unauthorized access to files.
|
||||
|
||||
The solution I offer involves writing down process's start time:
|
||||
|
||||
* Permission table will consist of entries $(pid, starttime, permission)$, where $pid$ is the process's PID, $starttime$ is the process's start time and $permission$ is the type of access the process is allowed (e.g. to which files).
|
||||
* When the process opens a file, search through the table.
|
||||
+ If an entry with the correct PID was found:
|
||||
- If $starttime_{table} < starttime_{actual}$[^2], delete all the entries with that PID and file a permission request to the user -- the process that requested access is not the same because it has started after the original process who had this permission(and because their PIDs match, the original process had to end before this could start).
|
||||
- Otherwise:
|
||||
* If the permission matches the request, open the file.
|
||||
* Otherwise file a new permission request.
|
||||
+ Otherwise file a new permission request.
|
||||
|
||||
This approach should make "permission hijacking" practically impossible, as it would take a considerable amount of time just to approve the permission. Even if our permissions could be approved instantly it would still take a few scheduler cycles to execute the original program, so the new ones must have a later start time.
|
||||
|
||||
This approach still has an issue: the table would be hoarded with old permissions, and therefore waste memory. This might be mitigated by regular cleanups (e.g. every time you create a new permission, check if the oldest one's process is still running)
|
||||
|
||||
Another issue might be speed, because all of the table lookups take linear time. But considering that file opening isn't exactly a time-critical operation and that the table could be sorted by PID, it does not seem to be that big of an issue.
|
||||
|
||||
## FUSE issues
|
||||
As mentioned in the initial idea, the source files have to be protected from external access in some way.
|
||||
|
||||
Here I can see three solutions:
|
||||
|
||||
1. Encrypting source files.
|
||||
2. Running our virtual filesystem daemon as a special user, and making all our source files only accessible to this special user, therefore processes would have no permissions to access the source files.
|
||||
3. Use some LSM's MAC policy to deny access to source files to any process except our daemon.
|
||||
|
||||
The first solution would definitely be preferable from the standpoint of compatibility, as it requires no special configuration, and because it mitigates the issue the best, as the attacker has to get encryption keys from the memory. Moreover, it could allow us to deny access for processes running as `root`[^3]. However, implementing encryption seems to be way out of scope of this project.
|
||||
|
||||
The second solution seems to work well in theory. There are some specific details to be clarified about it's implementation, but generally it seems to work out.
|
||||
|
||||
Although the third solution looks like exactly what we are looking for, but it requires a kernel module that enforces MAC policies. Even though those modules are common on most distros, they are pretty different from each other, and I think their usage should be limited to being an additional layer on top of the second solution.
|
||||
|
||||
## User interface
|
||||
From the description of the software, it remains unclear what type of user interaction design is appropriate. Do we make a CLI? GUI?
|
||||
|
||||
I propose to deal with it like the [Transmission](https://github.com/transmission/transmission) did[^3] -- create the backend with an integrated CLI first, and then make GUI wrapper in GTK after (if there would be time, of course `:)` ).
|
||||
|
||||
## Programs with CLI
|
||||
Programs that are run via shell can have an execution time of a fraction of a second, which means you would have to re-allow the access for them every time you run them.
|
||||
My solution is to give an option to set permissions for specific *sessions*, so that every command run from a specific terminal window would have the same permissions.
|
||||
Then the permission table would be populated with the session process's data (e.g. the shell), or maybe this would necessitate a separate table just for the sessions.
|
||||
That might also imply a creation of two CLI tools:
|
||||
|
||||
* `sprequest [PERM]` -- request a certain permission for the session
|
||||
* `spdrop` -- drop all permissions given to the session
|
||||
|
||||
## Too many files...
|
||||
It would be annoying to go and allow access for each program every time one of them opens a new file.
|
||||
For example, if the file subsystem looks like this:
|
||||
```
|
||||
Documents/
|
||||
| Work/
|
||||
| | horalky_secret_recipe.pdf
|
||||
| | colleagues.csv
|
||||
| Notes/
|
||||
| | set_theory.md
|
||||
| | Peano_axioms.md
|
||||
| | ...
|
||||
| | Cantor_theorem.md
|
||||
```
|
||||
If I want to view my notes, I would want allow my markdown editor the access to all the files in the `Documents/Notes` folder to make links work, but when I want to find a name of my colleague, I would like to only give the permission to the `Documents/Work/colleagues.csv` file.
|
||||
The solution is obvious: to give an option for the user to give permissions for the entire folder, not just a specific file.
|
||||
|
||||
## Other
|
||||
* Threads (not that big of a problem, but a complication nevertheless).
|
||||
* All of the permissions get reset after the process is ended, which is annoying. Perhaps it would be possible to implement permanent permissions through identifying programs by their executables' hashes/paths, but updates almost certainly make that impossible (unless we are modifying a package manager, which is clearly out of scope of this project).
|
||||
|
||||
Another issue, severity of which I can't assess properly, is whether this idea fits the Informatics degree, as it does not seem to be as much of an experimental or "theoretical" idea. In my opinion it sill holds enough water to entertain the possibility though.
|
||||
|
||||
[^1]: I haven't found any better information on that topic. The solutions mentioned seem overcomplicated.
|
||||
[^2]: Which is obtained through 22-nd field in /proc/\[pid\]/stat (see `man proc_pid_stat(5)`).
|
||||
[^3]: To the best of my knowledge.
|
33
docs/bc-thesis-specs.md
Normal file
33
docs/bc-thesis-specs.md
Normal file
@ -0,0 +1,33 @@
|
||||
# Formal specification
|
||||
|
||||
## Name
|
||||
```
|
||||
Filesystem with Interactive Access Control for Linux
|
||||
```
|
||||
|
||||
```
|
||||
Súborový systém s interaktívnym riadením prístupu pre Linux
|
||||
```
|
||||
|
||||
## Note
|
||||
```
|
||||
Traditional access control mechanisms in operating systems allow the same level of access to all processes running on behalf of the same user. This typically enables malicious processes to read and/or modify all data accessible to the user running a vulnerable application. It can be dealt using various mandatory access control mechanisms, but these are often complicated to configure and are rarely used in common user oriented scenarios. This thesis focuses on design and implementation of a filesystem layer which delegates the decision to allow or deny access to a filesystem object by a specific process to the user.
|
||||
```
|
||||
|
||||
```
|
||||
Tradičné mechanizmy riadenia prístupu v operačných systémoch povoľujú rovnakú úroveň prístupu všetkým procesom bežiacim v mene toho istého používateľa. Toto typicky umožňuje škodlivým procesom čítať a/alebo modifikovať všetky údaje prístupné používateľovi, ktorý spustil zraniteľnú aplikáciu. Dá sa to riešiť použitím rôznych mechanizmov povinného riadenia prístupu, no tieto sú často náročné na konfiguráciu a zriedkavo sa používajú v bežných scenároch orientovaných na používateľa. Táto práca sa zameriava na návrh a implementáciu vrstvy súborového systému, ktorá rozhodnutie povoliť alebo zakázať prístup k objektu súborového systému konkrétnym procesom deleguje na používateľa.
|
||||
```
|
||||
|
||||
## Goal
|
||||
|
||||
```
|
||||
- analyse the problem and design a solution
|
||||
- implement the solution using the FUSE framework
|
||||
- test the solution and demonstrate its benefits
|
||||
```
|
||||
|
||||
```
|
||||
- analyzovať problém a navrhnúť riešenie
|
||||
- implementovať riešenie využitím FUSE
|
||||
- otestovať riešenie a demonštrovať jeho prínos
|
||||
```
|
Loading…
Reference in New Issue
Block a user