Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1450475 > unrolled thread
| Started by | Cyrill Gorcunov <gorcunov@gmail.com> |
|---|---|
| First post | 2016-07-26 10:40 +0200 |
| Last post | 2016-08-01 11:30 +0200 |
| Articles | 7 — 4 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [PATCH] prctl: remove one-shot limitation for changing exe link Cyrill Gorcunov <gorcunov@gmail.com> - 2016-07-26 10:40 +0200
Re: [PATCH] prctl: remove one-shot limitation for changing exe link ebiederm@xmission.com (Eric W. Biederman) - 2016-07-30 19:50 +0200
Re: [PATCH] prctl: remove one-shot limitation for changing exe link Mateusz Guzik <mguzik@redhat.com> - 2016-07-30 22:30 +0200
Re: [PATCH] prctl: remove one-shot limitation for changing exe link ebiederm@xmission.com (Eric W. Biederman) - 2016-07-31 21:00 +0200
Re: [PATCH] prctl: remove one-shot limitation for changing exe link Cyrill Gorcunov <gorcunov@gmail.com> - 2016-08-01 00:50 +0200
Re: [PATCH] prctl: remove one-shot limitation for changing exe link Andy Lutomirski <luto@amacapital.net> - 2016-08-01 01:00 +0200
Re: [PATCH] prctl: remove one-shot limitation for changing exe link Cyrill Gorcunov <gorcunov@gmail.com> - 2016-08-01 11:30 +0200
| From | Cyrill Gorcunov <gorcunov@gmail.com> |
|---|---|
| Date | 2016-07-26 10:40 +0200 |
| Subject | Re: [PATCH] prctl: remove one-shot limitation for changing exe link |
| Message-ID | <rZ64a-884-9@gated-at.bofh.it> |
On Mon, Jul 25, 2016 at 02:56:43PM -0500, Eric W. Biederman wrote: ... > >> > >> Also there is a big fat bug in prctl_set_mm_exe_file. It doesn't > >> validate that the new file is a actually mmaped executable. We would > >> definitely need that to be fixed before even considering removing the > >> limit. > > > > Could you please elaborate? We check for inode being executable, > > what else needed? > > That the inode is mmaped into the process with executable mappings. > > Effectively what we check the old mapping for and refuse to remove the old > mm_exe_file if it exists. > > I think a reasonable argument can be made that if the file is > executable, and it is mmaped with executable pages that exe_file is not > a complete lie. I might be missing something obvious, so sorry for the question -- when criu setups old exe link the inode we obtain from file open is not mapped into memory, the old exe not read by anyone because it's not even executed anyhow. So I don't really understand which mapping we should check here. Mind to point me? > Which is the important part. At the end of the day how much can > userspace trust /proc/pid/exe? If we are too lax it is just a random > file descriptor we can not trust at all. At which point there is > exactly no point in preserving it in checkpoint/restart, because nothing > will trust or look at it. You know, I think we should not trust exe link much, and in real we never could: this link is rather a hint pointing which executable a process has been using on execve call, once the process start working one can't be sure if the code currently running is exactly from the file pointed by exe link. It just a hint suitable for debuggin and obtain clean view of which processes are running on noncompromised system. Monitoring exe link change won't help much if there are malicious software running on the system. > If the only user is checkpoint/restart perhaps it should be only ptrace > that can set this and not the process itself with a prctl. I don't > know. All I know is that we should work on making it a very trustable > value even though in some specific instances we can set it. Since as I said I suppose nobody except us using this feature, we can setup some sysctl trigger for it (I personally think this is an overkill, but OTOH if people rely on the exe link and not going to use criu at all, this trigger will help). Cyrill
[toc] | [next] | [standalone]
| From | ebiederm@xmission.com (Eric W. Biederman) |
|---|---|
| Date | 2016-07-30 19:50 +0200 |
| Message-ID | <s0GyB-5wI-3@gated-at.bofh.it> |
| In reply to | #1450475 |
Cyrill Gorcunov <gorcunov@gmail.com> writes: > On Mon, Jul 25, 2016 at 02:56:43PM -0500, Eric W. Biederman wrote: > ... >> >> >> >> Also there is a big fat bug in prctl_set_mm_exe_file. It doesn't >> >> validate that the new file is a actually mmaped executable. We would >> >> definitely need that to be fixed before even considering removing the >> >> limit. >> > >> > Could you please elaborate? We check for inode being executable, >> > what else needed? >> >> That the inode is mmaped into the process with executable mappings. >> >> Effectively what we check the old mapping for and refuse to remove the old >> mm_exe_file if it exists. >> >> I think a reasonable argument can be made that if the file is >> executable, and it is mmaped with executable pages that exe_file is not >> a complete lie. > > I might be missing something obvious, so sorry for the question -- > when criu setups old exe link the inode we obtain from file open > is not mapped into memory, the old exe not read by anyone because > it's not even executed anyhow. So I don't really understand which > mapping we should check here. Mind to point me? That sounds like an out and out bug that should not be preserved. Of course we should mmap the executable and set it up so that it can be executed (at least as much as the executable was previously mapped). Anything else is a buggy restart, and lying to userspace. >> Which is the important part. At the end of the day how much can >> userspace trust /proc/pid/exe? If we are too lax it is just a random >> file descriptor we can not trust at all. At which point there is >> exactly no point in preserving it in checkpoint/restart, because nothing >> will trust or look at it. > > You know, I think we should not trust exe link much, and in real we > never could: this link is rather a hint pointing which executable a > process has been using on execve call, once the process start working > one can't be sure if the code currently running is exactly from the > file pointed by exe link. It just a hint suitable for debuggin and > obtain clean view of which processes are running on noncompromised > system. Monitoring exe link change won't help much if there are > malicious software running on the system. But it is not just a hint. It is a record of which executable we called execve on. Knowing which file was executed doesn't guarantee what is running now but it provides a very strong hint. At then end of a restart the state of a process should be (by definition) exactly the state the process was before a checkpoint and thus a state the original executable could have gotten into. I admit it is possible for an application to unmap itself. I honestly have not met that application (except perhaps criu). >> If the only user is checkpoint/restart perhaps it should be only ptrace >> that can set this and not the process itself with a prctl. I don't >> know. All I know is that we should work on making it a very trustable >> value even though in some specific instances we can set it. > > Since as I said I suppose nobody except us using this feature, we can > setup some sysctl trigger for it (I personally think this is an > overkill, but OTOH if people rely on the exe link and not going > to use criu at all, this trigger will help). Some clarity of thought came to me, and I apologise for not replying sooner with it sooner. My problem with the original patch submission is that it was justifying changing prctl_set_mm_exe_file based on what prctl_set_mm_exe_file does today. As prctl_set_mm_exe_file was added for the checkpoint/restart case that is justifying changing code based on a buggy implementation. It is necessary to look at the ordinary situation. Without prctl_set_mm_exe /proc/[pid]/exe can be counted on as a record of which executable was last passed to execve. Furthermore the state of a process can be counted on to be a state reachable from calling execve on /proc/[pid]/exe. Which means to preserve those expectations prctl_set_mm_exe_file should in practice just be a nicer less cumbersome interface to things you can already achieve with execve. Justifying removale of the one-short nature for prctl_set_mm_exe_file is as straight forward as noting that a process can call execve on any executable file. However when I compare the invariants that execve has on a file (such as the executable being mmaped) I see some noticable disparities between what prctl_set_mm_exe_file allows and what execve allows. With prctl_set_mm_exe being less strict. So what I am requesting is very simple. That the checks in prctl_set_mm_exe_file be tightened up to more closely approach what execve requires. Thus preserving the value of the /proc/[pid]/exe for the applications that want to use the exe link. Once the checks in prctl_set_mm_exe_file are tightened up please feel free to remove the one shot test. Eric
[toc] | [prev] | [next] | [standalone]
| From | Mateusz Guzik <mguzik@redhat.com> |
|---|---|
| Date | 2016-07-30 22:30 +0200 |
| Message-ID | <s0J3r-7ef-1@gated-at.bofh.it> |
| In reply to | #1452733 |
On Sat, Jul 30, 2016 at 12:31:40PM -0500, Eric W. Biederman wrote:
> So what I am requesting is very simple. That the checks in
> prctl_set_mm_exe_file be tightened up to more closely approach what
> execve requires. Thus preserving the value of the /proc/[pid]/exe for
> the applications that want to use the exe link.
>
> Once the checks in prctl_set_mm_exe_file are tightened up please feel
> free to remove the one shot test.
>
This is more fishy.
First of all exe_file is used by the audit subsystem. So someone has to
ask audit people what is the significance (if any) of the field.
All exe_file users but one use get_mm_exe_file and handle NULL
gracefully.
Even with the current limit of changing the field once, the user can
cause a transient failure of get_mm_exe_file which can fail to increment
the refcount before it drops to 0.
This transient failure can be used to get a NULL value stored in
->exe_file during fork (in dup_mmap):
RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm));
The one place which is not using get_mm_exe_file to get to the pointer
is audit_exe_compare:
rcu_read_lock();
exe_file = rcu_dereference(tsk->mm->exe_file);
ino = exe_file->f_inode->i_ino;
dev = exe_file->f_inode->i_sb->s_dev;
rcu_read_unlock();
This is buggy on 2 accounts:
1. exe_file can be NULL
2. rcu does not protect f_inode
The issue is made worse with allowing arbitrary number changes.
Modifying get_mm_exe_file to retry is trivial and in effect never return
NULL is trivial. With arbitrary number of changes allowed this may
require some cond_resched() or something.
For comments I cc'ed Richard Guy Briggs, who is both an audit person and
the author of audit_exe_compare.
--
Mateusz Guzik
[toc] | [prev] | [next] | [standalone]
| From | ebiederm@xmission.com (Eric W. Biederman) |
|---|---|
| Date | 2016-07-31 21:00 +0200 |
| Message-ID | <s147U-3P4-7@gated-at.bofh.it> |
| In reply to | #1452744 |
Mateusz Guzik <mguzik@redhat.com> writes: > On Sat, Jul 30, 2016 at 12:31:40PM -0500, Eric W. Biederman wrote: >> So what I am requesting is very simple. That the checks in >> prctl_set_mm_exe_file be tightened up to more closely approach what >> execve requires. Thus preserving the value of the /proc/[pid]/exe for >> the applications that want to use the exe link. >> >> Once the checks in prctl_set_mm_exe_file are tightened up please feel >> free to remove the one shot test. >> > > This is more fishy. > > First of all exe_file is used by the audit subsystem. So someone has to > ask audit people what is the significance (if any) of the field. > > All exe_file users but one use get_mm_exe_file and handle NULL > gracefully. > > Even with the current limit of changing the field once, the user can > cause a transient failure of get_mm_exe_file which can fail to increment > the refcount before it drops to 0. > > This transient failure can be used to get a NULL value stored in > ->exe_file during fork (in dup_mmap): > RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm)); > > The one place which is not using get_mm_exe_file to get to the pointer > is audit_exe_compare: > rcu_read_lock(); > exe_file = rcu_dereference(tsk->mm->exe_file); > ino = exe_file->f_inode->i_ino; > dev = exe_file->f_inode->i_sb->s_dev; > rcu_read_unlock(); > > This is buggy on 2 accounts: > 1. exe_file can be NULL > 2. rcu does not protect f_inode > > The issue is made worse with allowing arbitrary number changes. > > Modifying get_mm_exe_file to retry is trivial and in effect never return > NULL is trivial. With arbitrary number of changes allowed this may > require some cond_resched() or something. > > For comments I cc'ed Richard Guy Briggs, who is both an audit person and > the author of audit_exe_compare. That is fair. Keeping the existing users working is what needs to happen. At the same time we have an arbitrary number of possible changes with exec, but I guess that works differently because the mm is changed as well. So yes let's bug fix this piece of code and then we can see about relaxing constraints. Eric
[toc] | [prev] | [next] | [standalone]
| From | Cyrill Gorcunov <gorcunov@gmail.com> |
|---|---|
| Date | 2016-08-01 00:50 +0200 |
| Message-ID | <s17It-6dc-3@gated-at.bofh.it> |
| In reply to | #1452733 |
On Sat, Jul 30, 2016 at 12:31:40PM -0500, Eric W. Biederman wrote: > Cyrill Gorcunov <gorcunov@gmail.com> writes: > > > On Mon, Jul 25, 2016 at 02:56:43PM -0500, Eric W. Biederman wrote: > > ... > >> >> > >> >> Also there is a big fat bug in prctl_set_mm_exe_file. It doesn't > >> >> validate that the new file is a actually mmaped executable. We would > >> >> definitely need that to be fixed before even considering removing the > >> >> limit. > >> > > >> > Could you please elaborate? We check for inode being executable, > >> > what else needed? > >> > >> That the inode is mmaped into the process with executable mappings. Eric, thanks for clarification. Let me talk from CRIU perspective (because the interface came from its need) -- the former executable may no longer exist, completely: for such cases in CRIU we simply create that named "ghost" files wich are just literally removed upon open. So we simply can't mmap the former executable into memory. Moreover I would really _like_ to not do this check -- the former intarface has been done exactly to behave as it does now: don't read original file into memory (in criu, when we setup this exelink, the original memory of a process already restored so additional mmap for every executable is purely waste of time). > >> > >> Effectively what we check the old mapping for and refuse to remove the old > >> mm_exe_file if it exists. > >> > >> I think a reasonable argument can be made that if the file is > >> executable, and it is mmaped with executable pages that exe_file is not > >> a complete lie. > > > > I might be missing something obvious, so sorry for the question -- > > when criu setups old exe link the inode we obtain from file open > > is not mapped into memory, the old exe not read by anyone because > > it's not even executed anyhow. So I don't really understand which > > mapping we should check here. Mind to point me? > > That sounds like an out and out bug that should not be preserved. No, it's done on intent, as I explained above -- we would like to escape double reading (which not always possible in case of deleted files). > Of course we should mmap the executable and set it up so that it can be > executed (at least as much as the executable was previously mapped). > Anything else is a buggy restart, and lying to userspace. Same way once someone ptraces the process it makes exelink to lie into userspace. exelink is valid only small time moment: when kernel reads elf and maps it. After that, once you jump back into userspace that's end of game, there might be anything else running instead of former executable as we already know. > > >> Which is the important part. At the end of the day how much can > >> userspace trust /proc/pid/exe? If we are too lax it is just a random > >> file descriptor we can not trust at all. At which point there is > >> exactly no point in preserving it in checkpoint/restart, because nothing > >> will trust or look at it. > > > > You know, I think we should not trust exe link much, and in real we > > never could: this link is rather a hint pointing which executable a > > process has been using on execve call, once the process start working > > one can't be sure if the code currently running is exactly from the > > file pointed by exe link. It just a hint suitable for debuggin and > > obtain clean view of which processes are running on noncompromised > > system. Monitoring exe link change won't help much if there are > > malicious software running on the system. > > But it is not just a hint. It is a record of which executable we called > execve on. Knowing which file was executed doesn't guarantee what is > running now but it provides a very strong hint. Exactly, its a record of what been valid when kernel did execve and run new content. Once we're in userspace back this data may be informative but not representative. > At then end of a restart the state of a process should be (by > definition) exactly the state the process was before a checkpoint > and thus a state the original executable could have gotten into. > > I admit it is possible for an application to unmap itself. I honestly > have not met that application (except perhaps criu). It's not common practice on modern machines indeed. But you can do that, you can even continue running when former executable no longer present on the disk. > >> If the only user is checkpoint/restart perhaps it should be only ptrace > >> that can set this and not the process itself with a prctl. I don't > >> know. All I know is that we should work on making it a very trustable > >> value even though in some specific instances we can set it. > > > > Since as I said I suppose nobody except us using this feature, we can > > setup some sysctl trigger for it (I personally think this is an > > overkill, but OTOH if people rely on the exe link and not going > > to use criu at all, this trigger will help). > > Some clarity of thought came to me, and I apologise for not replying > sooner with it sooner. > > My problem with the original patch submission is that it was > justifying changing prctl_set_mm_exe_file based on what > prctl_set_mm_exe_file does today. As prctl_set_mm_exe_file was added > for the checkpoint/restart case that is justifying changing code based > on a buggy implementation. I dont think so: it's not buggy but the minimum we need to be able to restore deleted files. I'll read the rest of the email tomorrow, thank you for comments!
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-08-01 01:00 +0200 |
| Message-ID | <s17Sa-6gO-17@gated-at.bofh.it> |
| In reply to | #1452904 |
On Sun, Jul 31, 2016 at 3:43 PM, Cyrill Gorcunov <gorcunov@gmail.com> wrote: > On Sat, Jul 30, 2016 at 12:31:40PM -0500, Eric W. Biederman wrote: >> Cyrill Gorcunov <gorcunov@gmail.com> writes: >> >> > On Mon, Jul 25, 2016 at 02:56:43PM -0500, Eric W. Biederman wrote: >> > ... >> >> >> >> >> >> Also there is a big fat bug in prctl_set_mm_exe_file. It doesn't >> >> >> validate that the new file is a actually mmaped executable. We would >> >> >> definitely need that to be fixed before even considering removing the >> >> >> limit. >> >> > >> >> > Could you please elaborate? We check for inode being executable, >> >> > what else needed? >> >> >> >> That the inode is mmaped into the process with executable mappings. > > Eric, thanks for clarification. Let me talk from CRIU perspective (because > the interface came from its need) -- the former executable may no longer > exist, completely: for such cases in CRIU we simply create that named > "ghost" files wich are just literally removed upon open. So we simply > can't mmap the former executable into memory. > > Moreover I would really _like_ to not do this check -- the former > intarface has been done exactly to behave as it does now: don't > read original file into memory (in criu, when we setup this exelink, > the original memory of a process already restored so additional > mmap for every executable is purely waste of time). Eric, I think I generally disagree with you here. I see no compelling reason that we shouldn't allow unlimited changes to exe_file so long as the selected files are executable. (It might make sense to check that LSM is okay, but even that is a dubious requirement, I think.) What kind of attack are you worried about? That being said, we should probably make it so that audit logs indicate the real executable that was execve'd, but I'd imagine that this is already the case. But I don't think the original executable needs to be directly visible in /proc. --Andy
[toc] | [prev] | [next] | [standalone]
| From | Cyrill Gorcunov <gorcunov@gmail.com> |
|---|---|
| Date | 2016-08-01 11:30 +0200 |
| Message-ID | <s1hHQ-4rR-7@gated-at.bofh.it> |
| In reply to | #1452733 |
On Sat, Jul 30, 2016 at 12:31:40PM -0500, Eric W. Biederman wrote: ... > > It is necessary to look at the ordinary situation. Without > prctl_set_mm_exe /proc/[pid]/exe can be counted on as a record > of which executable was last passed to execve. True. > Furthermore the state of a process can be counted on to be a state > reachable from calling execve on /proc/[pid]/exe. Absolutely not. The state is valid until kernel jumped back to userspace and give control to an interpretator. > Which means to preserve those expectations prctl_set_mm_exe_file should > in practice just be a nicer less cumbersome interface to things you can > already achieve with execve. > > Justifying removale of the one-short nature for prctl_set_mm_exe_file > is as straight forward as noting that a process can call execve on > any executable file. > > However when I compare the invariants that execve has on a file (such as > the executable being mmaped) I see some noticable disparities between > what prctl_set_mm_exe_file allows and what execve allows. With > prctl_set_mm_exe being less strict. > > So what I am requesting is very simple. That the checks in > prctl_set_mm_exe_file be tightened up to more closely approach what > execve requires. Thus preserving the value of the /proc/[pid]/exe for > the applications that want to use the exe link. > > Once the checks in prctl_set_mm_exe_file are tightened up please feel > free to remove the one shot test. Thanks a huge for the detailed explanation, but i don't agree here because assuming that state of a process reachable from calling execve on /proc/[pid]/exe is not always true.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web