Bug 1250605 - conman denied access to /dev/*random prevents it from starting
conman denied access to /dev/*random prevents it from starting
Status: CLOSED ERRATA
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: selinux-policy (Show other bugs)
7.1
All Linux
medium Severity medium
: rc
: 7.2
Assigned To: Lukas Vrabec
Milos Malik
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2015-08-05 10:33 EDT by Miroslav Hradílek
Modified: 2015-11-19 05:43 EST (History)
9 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2015-11-19 05:43:11 EST
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
ausearch after conmand service start (1.24 KB, text/x-vhdl)
2015-08-05 10:35 EDT, Miroslav Hradílek
no flags Details

  None (edit)
Description Miroslav Hradílek 2015-08-05 10:33:22 EDT
Description of problem:
When conman is configured to share IPMI console and systemd service file is started, the daemon is denied access to random_device_t which is needed by conman to start so the process is aborted.



Version-Release number of selected component (if applicable):
selinux-policy-3.13.1-23.el7.noarch

Steps to Reproduce:
1. Configure conmand "echo "CONSOLE name='ipmisol' dev='ipmi:$host' ipmiopts='U:$user,P:$pass'" > /etc/conman.conf" replacing $values with actual BMC adress, user, password.
2. Start conmand "systemctl start conman".
3. Check conmand status "systemctl status conman"

Actual results:
systemd[1]: Starting ConMan Console Management Daemon...
systemd[1]: Started ConMan Console Management Daemon.
systemd[1]: conman.service: main process exited, code=dumped, status=6/ABRT
systemd[1]: Unit conman.service entered failed state.


Expected results:
Start daemon and successfully share ipmi console.

Additional info:
cat auserch-urandom | audit2allow 


#============= conman_t ==============

#!!!! This avc can be allowed using the boolean 'authlogin_nsswitch_use_ldap'
allow conman_t random_device_t:chr_file read;

#!!!! This avc can be allowed using one of the these booleans:
#     authlogin_nsswitch_use_ldap, global_ssp
allow conman_t urandom_device_t:chr_file read;
Comment 1 Miroslav Hradílek 2015-08-05 10:35:30 EDT
Created attachment 1059482 [details]
ausearch after conmand service start
Comment 3 Denys Vlasenko 2015-08-05 16:15:34 EDT
conman uses freeipmi library when it needs to talk over IPMI.
freeipmi library contains this code snippet:

int
ipmi_get_random (void *buf, unsigned int buflen)
{
#if (HAVE_DEVURANDOM || HAVE_DEVRANDOM)
  int fd, rv;
#endif /* !(HAVE_DEVURANDOM || HAVE_DEVRANDOM) */

  if (!buf)
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  if (!buflen)
    return (0);

#if (HAVE_DEVURANDOM || HAVE_DEVRANDOM)
#if HAVE_DEVURANDOM
  if ((fd = open ("/dev/urandom", O_RDONLY)) < 0)
    goto gcrypt_rand;
#else  /* !HAVE_DEVURANDOM */
  if ((fd = open ("/dev/random", O_RDONLY)) < 0)
    goto gcrypt_rand;
#endif /* !HAVE_DEVURANDOM */

  if ((rv = read (fd, buf, buflen)) < buflen)
    {
      close (fd);
      goto gcrypt_rand;
    }

  /* ignore potential error, cleanup path */
  close (fd);
  return (rv);
#endif /* !(HAVE_DEVURANDOM || HAVE_DEVRANDOM) */

 gcrypt_rand:
/* achu: nothing to do with encryption, but the gcrypt lib isn't loaded.
 * hopefully the user has /dev/random or /dev/urandom.
 */
#ifdef WITH_ENCRYPTION
  gcry_randomize ((unsigned char *)buf, buflen, GCRY_STRONG_RANDOM);
  return (buflen);
#else /* !WITH_ENCRYPTION */
  SET_ERRNO (EPERM);
  return (-1);
#endif /* !WITH_ENCRYPTION */
}

As you see, when open("/dev/[u]random") doesn't succeed, it falls back to gcry_randomize(), which is provided by libgcrypt library.

Unfortunately, gcry_randomize() fares no better. After several layers of abstraction, we reach this function which again tries to access /dev/[u]random, and when that doesn't work, it fatally fails:

static int (*
getfnc_gather_random (void))(void (*)(const void*, size_t,
                                      enum random_origins),
                             enum random_origins, size_t, int)
{
  int (*fnc)(void (*)(const void*, size_t, enum random_origins),
             enum random_origins, size_t, int);

#if USE_RNDLINUX
  if ( !access (NAME_OF_DEV_RANDOM, R_OK)
       && !access (NAME_OF_DEV_URANDOM, R_OK))
    {
      fnc = _gcry_rndlinux_gather_random;
      return fnc;
    }
#endif

#if USE_RNDEGD
  if ( _gcry_rndegd_connect_socket (1) != -1 )
    {
      fnc = _gcry_rndegd_gather_random;
      return fnc;
    }
#endif

#if USE_RNDUNIX
  fnc = _gcry_rndunix_gather_random;
  return fnc;
#endif

#if USE_RNDW32
  fnc = _gcry_rndw32_gather_random;
  return fnc;
#endif

#if USE_RNDW32CE
  fnc = _gcry_rndw32ce_gather_random;
  return fnc;
#endif

  log_fatal (_("no entropy gathering module detected\n"));

  return NULL; /*NOTREACHED*/
}

log_fatal() ends up calling abort() and kills itself with SIGABRT.
Comment 4 Milos Malik 2015-08-06 03:02:51 EDT
Could you re-test it with latest policy? The access to /dev/urandom should be allowed without a need to enable any boolean:

# rpm -qa selinux-policy\*
selinux-policy-targeted-3.13.1-37.el7.noarch
selinux-policy-3.13.1-37.el7.noarch
selinux-policy-devel-3.13.1-37.el7.noarch
selinux-policy-minimum-3.13.1-37.el7.noarch
selinux-policy-mls-3.13.1-37.el7.noarch
selinux-policy-sandbox-3.13.1-37.el7.noarch
selinux-policy-doc-3.13.1-37.el7.noarch
# sesearch -s conman_t -t urandom_device_t -A -C
Found 3 semantic av rules:
   allow domain urandom_device_t : chr_file { ioctl read getattr lock open } ; 
DT allow nsswitch_domain urandom_device_t : chr_file { ioctl read getattr lock open } ; [ authlogin_nsswitch_use_ldap ]
DT allow domain urandom_device_t : chr_file { ioctl read getattr lock open } ; [ global_ssp ]
#
Comment 5 Miroslav Hradílek 2015-08-06 05:57:47 EDT
I can confirm that it works as expected with 3.13.1-37 policy. Thanks Milos.

# rpm -qa selinux-policy\*
selinux-policy-3.13.1-37.el7.noarch
selinux-policy-devel-3.13.1-37.el7.noarch
selinux-policy-targeted-3.13.1-37.el7.noarch
# rpm -q conman freeipmi
conman-0.2.7-12.el7.ppc64
freeipmi-1.2.9-7.el7.ppc64

# systemctl start conman
# systemctl status conman
conman.service - ConMan Console Management Daemon
   Loaded: loaded (/usr/lib/systemd/system/conman.service; disabled)
   Active: active (running) since Thu 2015-08-06 05:47:56 EDT; 6s ago
  Process: 12681 ExecStart=/usr/sbin/conmand -c /etc/conman.conf (code=exited, status=0/SUCCESS)
 Main PID: 12683 (conmand)
   CGroup: /system.slice/conman.service
           └─12683 /usr/sbin/conmand -c /etc/conman.conf

systemd[1]: Started ConMan Console Management Daemon.

# conman ipmisol

<ConMan> Connection to console [ipmisol] opened.
Comment 9 Dominique Martinet 2015-10-23 07:07:48 EDT
Hi,

(hopefully this won't re-open the bug as it's not really a problem, but would appreciate an answer anyway)

I can't see the diff, but here's what I have on a 7.1 system:
> # sesearch -s conman_t -t urandom_device_t -A -C
> Found 2 semantic av rules:
> ... nss ...
> DT allow domain urandom_device_t : chr_file { ioctl read getattr lock open } ; [ global_ssp ]

And here's what you linked:
> # sesearch -s conman_t -t urandom_device_t -A -C
> Found 3 semantic av rules:
>   allow domain urandom_device_t : chr_file { ioctl read getattr lock open } ; 
> ... nss ...
> DT allow domain urandom_device_t : chr_file { ioctl read getattr lock open } ; [ global_ssp ]


Looking at the source (from selinux-policy-3.13.1-44.el7.src.rpm, 7.2 beta...), we have ./policy/modules/kernel/domain.te:
# Allow all domains to read /dev/urandom. It is needed by all apps/services
# linked to libgcrypt. There is no harm to allow it by default.
dev_read_urand(domain)

then a few lines below:
tunable_policy(`global_ssp',`
        # enable reading of urandom for all domains:
        # this should be enabled when all programs
        # are compiled with ProPolice/SSP
        # stack smashing protection.
        dev_read_urand(domain)
')

Sooo. Why not just make the tunable default to on? Or remove the bool? It looks to me that it just became useless, but I may have missed something.


Thanks,
-- 
Dominique Martinet
Comment 10 Miroslav Grepl 2015-10-26 02:56:41 EDT
Yes, we will remove it in 7.3.

Thank you.
Comment 12 errata-xmlrpc 2015-11-19 05:43:11 EST
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHBA-2015-2300.html

Note You need to log in before you can comment on or make changes to this bug.