Hi,
Background: In current git, crash dumps are always processed by the daemon, which runs under root. Clients merely send commands to daemon.
This poses the security problem: a lot of code runs under root and auditing it all for safety is a non-trivial task, which will be a constant burden during development.
Worse, it makes code unnecessarily complex.
Consider abrt-action-print: it has -o OUTFILE option. With current arrangement, we either should prohibit its usage altogether to prevent overwriting of arbitrary files, or add code which checks that the file is writable *by the user which issued the dbus command to daemon*! So, we need to do something like pass down $UID to all children, and don't forget to check it everywhere. This wouldn't be pretty, and easy to get wrong.
Therefore we decided to try to migrate crash dump processing to user side. IOW: we want to run events on crash dumps by clients themselves - without any talking to daemon.
As Jiri reported, when he tried to do this, one problem he immediately stumbled upon is that currently crash dumps are created under uid:gid and mode which make them non-writable by user. And we _do_ require writing to crash dumps for any nontrivial processing.
This mail discusses one possible way to overcome this problem.
At least one kind of crash dumps - C/C++ dumps - is created by kernel hook and therefore it might be unable to access $HOME. This rules out creation of crash dumps somewhere inside user home directories. Even if this problem would not exist and we could save crash dumps in, say, $HOME/.abrt/spool/*, we would lose a property that admin (root) can see all crashes (with any uids) in one place.
I propose the following solution: crash dumps creation is not changed: they are still created in /var/spool/abrt/*. Root user can process them there, in-situ.
Non-root users can not, but they can "steal" their crashes: by copying/moving them to $HOME/.abrt/spool/*. This is the only operation which requires cooperation from daemon. Copying itself can be done by client-side program without any help from daemon if /var/spool/abrt/USER'S_CRASH_DUMP directory is readable; deleting requires help from daemon. We end up needing only one command sent from client to daemon: "please delete crash dump /var/spool/abrt/USER'S_CRASH_DUMP".
From the non-root user's perspective, working with crash dumps will look
like this: there is a GUI app which shows the list of all crashes. It is built by scanning both /var/spool/abrt/* and $HOME/.abrt/spool/*. User can click on any element of the list and open a window (this most likely runs a separate GUI program) to handle selected crash; or they can delete any element of the list.
Those crashes which reside in $HOME/.abrt/spool/* can be acted upon (reported / deleted / any_other_action) immediately; those from /var/spool/abrt/* need to be "stolen" first - moved from /var/spool/abrt/* to $HOME/.abrt/spool/*. GUI asks for confirmation before doing it. (Maybe it makes sense to separate "copy" and "delete" steps which comprise "move" operation and allow user to do only "copy", or only "delete"? -> more power to user?). "Delete" step is implemented by sending a command to daemon to delete specified /var/spool/abrt/* directory. It's the only operation which needs help from daemon side. (Theoretically, we can have a tiny specialized suid-root binary for this operation instead, doing away with needing a running daemon).
After "stealing", crash resides in $HOME/.abrt/spool/* and we end up with simple case of "can be acted upon (reported / deleted / any_other_action) immediately".
Do you see any problems with this approach?
On Mon, 03 Jan 2011 16:55:14 +0100, Denys Vlasenko dvlasenk@redhat.com wrote:
Hi,
Background: In current git, crash dumps are always processed by the daemon, which runs under root. Clients merely send commands to daemon.
This poses the security problem: a lot of code runs under root and auditing it all for safety is a non-trivial task, which will be a constant burden during development.
Worse, it makes code unnecessarily complex.
Consider abrt-action-print: it has -o OUTFILE option. With current arrangement, we either should prohibit its usage altogether to prevent overwriting of arbitrary files, or add code which checks that the file is writable *by the user which issued the dbus command to daemon*! So, we need to do something like pass down $UID to all children, and don't forget to check it everywhere. This wouldn't be pretty, and easy to get wrong.
Therefore we decided to try to migrate crash dump processing to user side. IOW: we want to run events on crash dumps by clients themselves - without any talking to daemon.
As Jiri reported, when he tried to do this, one problem he immediately stumbled upon is that currently crash dumps are created under uid:gid and mode which make them non-writable by user. And we _do_ require writing to crash dumps for any nontrivial processing.
This mail discusses one possible way to overcome this problem.
At least one kind of crash dumps - C/C++ dumps - is created by kernel hook and therefore it might be unable to access $HOME. This rules out creation of crash dumps somewhere inside user home directories. Even if this problem would not exist and we could save crash dumps in, say, $HOME/.abrt/spool/*, we would lose a property that admin (root) can see all crashes (with any uids) in one place.
I propose the following solution: crash dumps creation is not changed: they are still created in /var/spool/abrt/*. Root user can process them there, in-situ.
Non-root users can not, but they can "steal" their crashes: by copying/moving them to $HOME/.abrt/spool/*. This is the only operation which requires cooperation from daemon. Copying itself can be done by client-side program without any help from daemon if /var/spool/abrt/USER'S_CRASH_DUMP directory is readable; deleting requires help from daemon. We end up needing only one command sent from client to daemon: "please delete crash dump /var/spool/abrt/USER'S_CRASH_DUMP".
From the non-root user's perspective, working with crash dumps will look
like this: there is a GUI app which shows the list of all crashes. It is built by scanning both /var/spool/abrt/* and $HOME/.abrt/spool/*. User can click on any element of the list and open a window (this most likely runs a separate GUI program) to handle selected crash; or they can delete any element of the list.
Those crashes which reside in $HOME/.abrt/spool/* can be acted upon (reported / deleted / any_other_action) immediately; those from /var/spool/abrt/* need to be "stolen" first - moved from /var/spool/abrt/* to $HOME/.abrt/spool/*. GUI asks for confirmation before doing it. (Maybe it makes sense to separate "copy" and "delete" steps which comprise "move" operation and allow user to do only "copy", or only "delete"? -> more power to user?). "Delete" step is implemented by sending a command to daemon to delete specified /var/spool/abrt/* directory. It's the only operation which needs help from daemon side. (Theoretically, we can have a tiny specialized suid-root binary for this operation instead, doing away with needing a running daemon).
After "stealing", crash resides in $HOME/.abrt/spool/* and we end up with simple case of "can be acted upon (reported / deleted / any_other_action) immediately".
Do you see any problems with this approach?
Maybe I don't fully understand. Why do you want to *move* it? It will lead to that admin won't see crash. Another things what's come up. How we will sync crash dump? One thing what's good now is, that we have crash dump in sync with users. When user do whatever with dump dir, admin doesn't see that.
On 01/04/2011 01:56 PM, Nikola Pajkovsky wrote:
On Mon, 03 Jan 2011 16:55:14 +0100, Denys Vlasenkodvlasenk@redhat.com wrote:
Hi,
Background: In current git, crash dumps are always processed by the daemon, which runs under root. Clients merely send commands to daemon.
This poses the security problem: a lot of code runs under root and auditing it all for safety is a non-trivial task, which will be a constant burden during development.
Worse, it makes code unnecessarily complex.
Consider abrt-action-print: it has -o OUTFILE option. With current arrangement, we either should prohibit its usage altogether to prevent overwriting of arbitrary files, or add code which checks that the file is writable *by the user which issued the dbus command to daemon*! So, we need to do something like pass down $UID to all children, and don't forget to check it everywhere. This wouldn't be pretty, and easy to get wrong.
Therefore we decided to try to migrate crash dump processing to user side. IOW: we want to run events on crash dumps by clients themselves - without any talking to daemon.
As Jiri reported, when he tried to do this, one problem he immediately stumbled upon is that currently crash dumps are created under uid:gid and mode which make them non-writable by user. And we _do_ require writing to crash dumps for any nontrivial processing.
This mail discusses one possible way to overcome this problem.
At least one kind of crash dumps - C/C++ dumps - is created by kernel hook and therefore it might be unable to access $HOME. This rules out creation of crash dumps somewhere inside user home directories. Even if this problem would not exist and we could save crash dumps in, say, $HOME/.abrt/spool/*, we would lose a property that admin (root) can see all crashes (with any uids) in one place.
I propose the following solution: crash dumps creation is not changed: they are still created in /var/spool/abrt/*. Root user can process them there, in-situ.
Non-root users can not, but they can "steal" their crashes: by copying/moving them to $HOME/.abrt/spool/*. This is the only operation which requires cooperation from daemon. Copying itself can be done by client-side program without any help from daemon if /var/spool/abrt/USER'S_CRASH_DUMP directory is readable; deleting requires help from daemon. We end up needing only one command sent from client to daemon: "please delete crash dump /var/spool/abrt/USER'S_CRASH_DUMP".
From the non-root user's perspective, working with crash dumps will look
like this: there is a GUI app which shows the list of all crashes. It is built by scanning both /var/spool/abrt/* and $HOME/.abrt/spool/*. User can click on any element of the list and open a window (this most likely runs a separate GUI program) to handle selected crash; or they can delete any element of the list.
Those crashes which reside in $HOME/.abrt/spool/* can be acted upon (reported / deleted / any_other_action) immediately; those from /var/spool/abrt/* need to be "stolen" first - moved from /var/spool/abrt/* to $HOME/.abrt/spool/*. GUI asks for confirmation before doing it. (Maybe it makes sense to separate "copy" and "delete" steps which comprise "move" operation and allow user to do only "copy", or only "delete"? -> more power to user?). "Delete" step is implemented by sending a command to daemon to delete specified /var/spool/abrt/* directory. It's the only operation which needs help from daemon side. (Theoretically, we can have a tiny specialized suid-root binary for this operation instead, doing away with needing a running daemon).
After "stealing", crash resides in $HOME/.abrt/spool/* and we end up with simple case of "can be acted upon (reported / deleted / any_other_action) immediately".
Do you see any problems with this approach?
Maybe I don't fully understand. Why do you want to *move* it? It will lead to that admin won't see crash. Another things what's come up. How we will sync crash dump? One thing what's good now is, that we have crash dump in sync with users. When user do whatever with dump dir, admin doesn't see that.
- we had a discussion about this and there is a problem with non-root writeable directories outside the $HOME ... and the crash dir must be writeable for the reporters which will run as non privileged user and that's why we need to change the handling of crash dirs...
J.
On Tue, 2011-01-04 at 13:56 +0100, Nikola Pajkovsky wrote:
On Mon, 03 Jan 2011 16:55:14 +0100, Denys Vlasenko dvlasenk@redhat.com wrote:
I propose the following solution: crash dumps creation is not changed: they are still created in /var/spool/abrt/*. Root user can process them there, in-situ.
Non-root users can not, but they can "steal" their crashes: by copying/moving them to $HOME/.abrt/spool/*. This is the only operation which requires cooperation from daemon. Copying itself can be done by client-side program without any help from daemon if /var/spool/abrt/USER'S_CRASH_DUMP directory is readable; deleting requires help from daemon. We end up needing only one command sent from client to daemon: "please delete crash dump /var/spool/abrt/USER'S_CRASH_DUMP".
From the non-root user's perspective, working with crash dumps will look
like this: there is a GUI app which shows the list of all crashes. It is built by scanning both /var/spool/abrt/* and $HOME/.abrt/spool/*. User can click on any element of the list and open a window (this most likely runs a separate GUI program) to handle selected crash; or they can delete any element of the list.
Those crashes which reside in $HOME/.abrt/spool/* can be acted upon (reported / deleted / any_other_action) immediately; those from /var/spool/abrt/* need to be "stolen" first - moved from /var/spool/abrt/* to $HOME/.abrt/spool/*. GUI asks for confirmation before doing it. (Maybe it makes sense to separate "copy" and "delete" steps which comprise "move" operation and allow user to do only "copy", or only "delete"? -> more power to user?). "Delete" step is implemented by sending a command to daemon to delete specified /var/spool/abrt/* directory. It's the only operation which needs help from daemon side. (Theoretically, we can have a tiny specialized suid-root binary for this operation instead, doing away with needing a running daemon).
After "stealing", crash resides in $HOME/.abrt/spool/* and we end up with simple case of "can be acted upon (reported / deleted / any_other_action) immediately".
Do you see any problems with this approach?
Maybe I don't fully understand. Why do you want to *move* it?
Because program which runs under non-root cannot dd_opendir() a dump dir in /var/spool/abrt/. It can only operate on some writable directory.
It will lead to that admin won't see crash.
Yes. But only for those crash dumps which were "stolen". Presumably, if user (as opposed to root) "stole" crash dump, user is going to deal with it, not root.
But not ever crash dump will be "stolen". Basically, use cases fall into two categories which usually do not intersect:
- Root-administered machines (like web servers): even though there are processes running (and crashing) under non-root accounts, there are no real people logging in and working ar non-root. Admin logs in as root and deals with crashes. In this case, stealing is not needed and never happens.
- Shared machines (e.g. personal laptops; student labs): there are non-root users. Some of them will want to report crasher they experience - they use "stealing" to take crashes from /var/spool/abrt/ to their $HOME, and report and/or delete them. Other users don't - root deals with their crashes, without using stealing. For example, this is the case for all "machine" accounts which do not correspond to real people.
Another things what's come up. How we will sync crash dump?
We won't sync anythin. "Stolen" dump dir is no longer visible to root. As far as root is concerned, user's dump dir was deleted by the user.
One thing what's good now is, that we have crash dump in sync with users. When user do whatever with dump dir, admin doesn't see that.
Yes, this property is lost. Do you have an idea how to do it better?
On Tue, 04 Jan 2011 14:41:49 +0100, Denys Vlasenko dvlasenk@redhat.com wrote:
On Tue, 2011-01-04 at 13:56 +0100, Nikola Pajkovsky wrote:
On Mon, 03 Jan 2011 16:55:14 +0100, Denys Vlasenko dvlasenk@redhat.com wrote:
I propose the following solution: crash dumps creation is not changed: they are still created in /var/spool/abrt/*. Root user can process them there, in-situ.
Non-root users can not, but they can "steal" their crashes: by copying/moving them to $HOME/.abrt/spool/*. This is the only operation which requires cooperation from daemon. Copying itself can be done by client-side program without any help from daemon if /var/spool/abrt/USER'S_CRASH_DUMP directory is readable; deleting requires help from daemon. We end up needing only one command sent from client to daemon: "please delete crash dump /var/spool/abrt/USER'S_CRASH_DUMP".
From the non-root user's perspective, working with crash dumps will look
like this: there is a GUI app which shows the list of all crashes. It is built by scanning both /var/spool/abrt/* and $HOME/.abrt/spool/*. User can click on any element of the list and open a window (this most likely runs a separate GUI program) to handle selected crash; or they can delete any element of the list.
Those crashes which reside in $HOME/.abrt/spool/* can be acted upon (reported / deleted / any_other_action) immediately; those from /var/spool/abrt/* need to be "stolen" first - moved from /var/spool/abrt/* to $HOME/.abrt/spool/*. GUI asks for confirmation before doing it. (Maybe it makes sense to separate "copy" and "delete" steps which comprise "move" operation and allow user to do only "copy", or only "delete"? -> more power to user?). "Delete" step is implemented by sending a command to daemon to delete specified /var/spool/abrt/* directory. It's the only operation which needs help from daemon side. (Theoretically, we can have a tiny specialized suid-root binary for this operation instead, doing away with needing a running daemon).
After "stealing", crash resides in $HOME/.abrt/spool/* and we end up with simple case of "can be acted upon (reported / deleted / any_other_action) immediately".
Do you see any problems with this approach?
Maybe I don't fully understand. Why do you want to *move* it?
Because program which runs under non-root cannot dd_opendir() a dump dir in /var/spool/abrt/. It can only operate on some writable directory.
It will lead to that admin won't see crash.
Yes. But only for those crash dumps which were "stolen". Presumably, if user (as opposed to root) "stole" crash dump, user is going to deal with it, not root.
But not ever crash dump will be "stolen". Basically, use cases fall into two categories which usually do not intersect:
Root-administered machines (like web servers): even though there are processes running (and crashing) under non-root accounts, there are no real people logging in and working ar non-root. Admin logs in as root and deals with crashes. In this case, stealing is not needed and never happens.
Shared machines (e.g. personal laptops; student labs): there are non-root users. Some of them will want to report crasher they experience - they use "stealing" to take crashes from /var/spool/abrt/ to their $HOME, and report and/or delete them. Other users don't - root deals with their crashes, without using stealing. For example, this is the case for all "machine" accounts which do not correspond to real people.
Another things what's come up. How we will sync crash dump?
We won't sync anythin. "Stolen" dump dir is no longer visible to root. As far as root is concerned, user's dump dir was deleted by the user.
One thing what's good now is, that we have crash dump in sync with users. When user do whatever with dump dir, admin doesn't see that.
Yes, this property is lost. Do you have an idea how to do it better?
Thank you for tremendous explanation. This seems to me very reasonable.
crash-catcher@lists.fedorahosted.org