[CRIU] [PATCH] security: check_ids - return true if [se]?[ug]id is the same as task id
Ruslan Kuprieiev
kupruser at gmail.com
Sun Jun 15 22:55:37 PDT 2014
And again sorry for necromailing=).
After a bit more thinking, here is what I figured out.
Current check if(crid == id && crid == eid && crid == sid) doesn't work
right.
Andrew was able to show it in "[CRIU] RPC support for --shell-job
missing on restore"
thread.
I wasn't able to make it work only with crid available.
Andrew also suggested that we should be able to dump/restore task if we
are able
to kill it. He also attached a function from the kernel:
static int kill_ok_by_cred(struct task_struct *t)
{
const struct cred *cred = current_cred();
const struct cred *tcred = __task_cred(t);
if (uid_eq(cred->euid, tcred->suid) ||
uid_eq(cred->euid, tcred->uid) ||
uid_eq(cred->uid, tcred->suid) ||
uid_eq(cred->uid, tcred->uid))
return 1;
if (ns_capable(tcred->user_ns, CAP_KILL))
return 1;
return 0;
}
Maybe we should add gete(u/g)id,gets(u/g)id and use check from
kill_ok_by_cred?
It looks easy to implement with cmdline usage of criu, but with service
we can't get all
id's(id, eid, sid) through the socket. But, maybe we could parse
/proc/pid/status to get all of them?
What do you all think about that?
On 23.05.2014 12:33, Pavel Emelyanov wrote:
> On 05/19/2014 06:17 PM, Ruslan Kuprieiev wrote:
>> On 17.05.2014 12:00, Andrew Vagin wrote:
>>> On Fri, May 16, 2014 at 05:54:55PM +0300, Ruslan Kuprieiev wrote:
>>>> Currently there are typos in check_ids, so one can't pass this check,
>>>> unless (u/g)id == e(g/u)id == s(g/u)id == task_(g/u)id.
>> OMG, I mixed task and caller id's in this description!
> The checks you're fixing prevent from creating images with "bad"
> code and restore them into siud-ed process. What problem are we
> trying to resolve? If I get it right it is -- task executes a
> suid-ed binary belonging to some other user, then we checkpoint
> it, then try to restore and fail. Is that correct?
>
>>>> Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
>>>> ---
>>>> security.c | 2 +-
>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/security.c b/security.c
>>>> index d4b4230..dc90208 100644
>>>> --- a/security.c
>>>> +++ b/security.c
>>>> @@ -28,7 +28,7 @@ static bool check_ids(unsigned int crid, unsigned int rid,
>>>> unsigned int eid, uns
>>>> {
>>>> if (crid == 0)
>>>> return true;
>>>> - if (crid == rid && crid == eid && crid == sid)
>>>> + if (crid == rid || crid == eid || crid == sid)
>>> I have thought a bit more and now I am not sure about this. Could you explain why this is correct?
>> Hm... Yes, you are right. Well, crid == rid || crid == sid we get from the
>> statement, that we should be able to dump task, if we can kill it.
>> And crid == eid looks wrong.
>>
>>>> return true;
>>>>
>>>> pr_err("UID/GID mismatch %u != (%u,%u,%u)\n", crid, rid, eid, sid);
>>>> --
>>>> 1.8.1.2
>>>>
>>>> _______________________________________________
>>>> CRIU mailing list
>>>> CRIU at openvz.org
>>>> https://lists.openvz.org/mailman/listinfo/criu
>>
>
More information about the CRIU
mailing list