Try testing such a patch to see if it resolves your issue. However, I think
if you switch to installing your policy module from your package post
scriptlet, you won't encounter this issue in the first place.

On Jan 3, 2018 7:26 AM, "Li Kun" <[email protected]> wrote:

>
>
> 在 2018/1/2 22:31, Stephen Smalley 写道:
>
>
>
> On Jan 2, 2018 1:37 AM, "Li Kun" <[email protected]> wrote:
>
>
>
> On 2018/1/2 12:16, Stephen Smalley wrote:
>
> On Jan 1, 2018 8:40 PM, "Li Kun" <[email protected]> wrote:
>
>
>
> 在 2017/12/30 1:25, Stephen Smalley 写道:
>
> On Dec 28, 2017 10:14 PM, "Li Kun" <[email protected]> wrote:
>
>
>
> 在 2017/12/28 22:57, Stephen Smalley 写道:
>
> On Sat, Dec 23, 2017 at 3:03 AM, Li Kun <[email protected]> wrote:
>
>> Hi all,
>> When i start a docker container, the runc will call selinux_setprocattr
>> to set the exec_sid before start the container.
>> Meanwhile if i use "semodule -i" to load a policy pp, the old sidtab will
>> be shutdown before switch to the new sidtab, and cause
>> sidtab_context_to_sid  failed with the errno -NOMEM.
>>
>> Error message:
>> Dec 14 09:18:18 wuwenming_vudfua_0 docker: 
>> time="2017-12-14T09:18:18.549862564+08:00"
>> level=error msg="Handler for GET /v1.23/containers/192.168.0.2:
>> 9082/dfs_d:V100R013C11SPC000BCD2/json returned error: No such container:
>> 192.168.0.2:9082/dfs_d:V100R013C11SPC000BCD2"
>> Dec 14 09:18:18 wuwenming_vudfua_0 kernel: [   48.463179] SELinux:
>> security_context_to_sid(system_u:object_r:svirt_sandbox_file_t:s0:c290,c371)
>> failed for (dev overlay, type overlay) errno=-12
>> Dec 14 09:18:18 wuwenming_vudfua_0 dbus-daemon: dbus[720]: avc:  received
>> policyload notice (seqno=2)
>> Dec 14 09:18:18 wuwenming_vudfua_0 dbus[720]: avc:  received policyload
>> notice (seqno=2)
>>
>>
>> runc
>>
>>     semodule
>> ->selinux_setprocattr
>>
>> ->security_load_policy
>>     ->security_context_to_sid
>>
>> ->sidtab_shutdown(oldsidtab)
>>         ->read_lock(&policy_rwlock);
>>
>> ->sidtab_map(&oldsidtab, clone_sid, &newsidtab);
>>
>>         ->sidtab_context_to_sid
>>
>>             {
>>                         ....
>>                         if (s->next_sid == UINT_MAX || s->shutdown) {
>>                         ret = -ENOMEM;
>>                         ....
>>             }
>>         ->read_unlock(&policy_rwlock);
>>
>>
>>
>> ->write_lock_irq(&policy_rwlock);
>>
>>
>> ->"switch to new policydb"
>>
>>
>> ->write_unlock_irq(&policy_rwlock);
>>
>> I wonder that if this is the intention or a bug?
>> If it is the intention, what should the application do when it get
>> -ENOMEM error,  to try again?
>> If it is a bug, may the two options below suitable to solve the issue?
>> Option1:
>>     use policy_rwlock to protect the "sidtab_shutdown" & "sidtab_map" ,
>> load_policy is rarely to be called after system bringing up,
>> so i think it will not impact much on the performance.
>> Option2:
>>     Use a temp list to store the sid in oldsidtab after it is shutdown,
>> and deal with it
>> after cloning the major sids from oldsidtab to newsidtab and getting the
>> policy_rwlock.
>>
>
> The current logic is intentional.  One might argue that a different error
> code might be more suitable in this situation (e.g. EAGAIN or something),
> but ENOMEM is already a possible error code when loading policy upon
> transient OOM conditions, so the caller might have to retry regardless.
> The policy write lock must only be held for the minimal critical section as
> otherwise all system activity could be blocked; it is only held when making
> the new policydb and sidtab active not during their allocation and setup -
> ideally it would be further reduced to a couple of pointer updates. Is this
> scenario something you are encountering in actual practice or just a
> theoretically possible one?
>
> Thank you very much for your reply.
> Yes, we encounter this issue in our implementation.
> We have an intertion in our design that we can divide the policy into
> several parts to load separately.
> So after the red-hat linux bringing up, which has loaded the system policy
> db released by redhat, we begin to load the policy released by our product
> ,
> and meanwhile someone want to start a docker container, and the runc get
> an ENOMEM error like i mentioned above.
> Should we merge all the policy into the system policy db and just load
> once?
>
>
> --
> Best Regards
> Li Kun
>
> Typically you would install your policy module when your package is
> installed and not need to do it at runtime.
>
> Would you think it's suibable to change the error code to EAGAIN?
>
>
> You likely want it to return - EINTR or -ERESTARTSYS if you want existing
> callers of setprocattr to automatically restart the call instead of
> failing.
>
> AFAIU, the EINTR & ERESTARTSYS are releated to sigpending under most
> circumstances, is it proper to use them here?
> And as i mentioned above, most apps(like runc, bind)do not retry when they
> meet ENOMEM, so i think maybe EAGAIN is more suitable for the transient
> race conditions
>
>
> EINTR is already handled by the libselinux procattr code, so returning
> that will cause existing users of the libselinux interfaces to retry.
> EAGAIN is not handled since the descriptor is not marked nonblocking.
>
> Ok, i understand, thank you.
> Maybe i can send a patch to change the errno to EINTR if you think it make
> sense.
>
> --
> Best Regards
> Li Kun
>
>

Reply via email to