I'm getting the following error when running java
with a profile with a long list of file_read
extended attributes:
# pfexec /usr/jdk/instances/jdk1.8.0/bin/java -cp /vagrant HelloWorld
/usr/jdk/instances/jdk1.8.0/bin/java: Value too large for defined data type
When I run it with truss
I see the exec error message is:
execve("/usr/jdk/instances/jdk1.8.0/bin/java", 0xFCEA4B60, 0xFCEA4B74) Err#79 EOVERFLOW
The man page for execve doesn't list EOVERFLOW
as a possible return.
It appears to be related to the number of file_read
extended attributes that I place in the profile. Here's how to reproduce the issue. The HelloWorld.java
source is trivial but useful to ensure the privileges are assigned properly from ppriv -v pid
public class HelloWorld {
public static void main( String[] args ) {
System.out.println("Sleeping");
try {
Thread.sleep(50000);
} catch( Exception e ) {
}
System.out.println("Hello World");
}
}
There appears to be a bug in the profiles
command as well as the profiles
command was unwilling to generate a large enough list of file_read
at
tributes. In order to create the profile, you must edit the resulting /etc/security/exec_attr
as follows:
# profiles -p test 'set desc=testing; add cmd=/usr/jdk/instances/jdk1.8.0/bin/java; set privs=basic; end; commit'
# usermod -P+test root
Manually edit /etc/security/exec_attr
and use the following for the minimal permission set for java
to execute without any permissions errors (backslashes added for readability and are allowed within the exec_attr
file):
test:solaris:cmd:::/usr/jdk/instances/jdk1.8.0/bin/java:privs=\
{file_read}\:/lib/amd64/libc.so.1,\
{file_read}\:/lib/amd64/libcryptoutil.so.1,\
{file_read}\:/lib/amd64/libdl.so.1,\
{file_read}\:/lib/amd64/libdoor.so.1,\
{file_read}\:/lib/amd64/libelf.so.1,\
{file_read}\:/lib/amd64/libgen.so.1,\
{file_read}\:/lib/amd64/libkstat.so.1,\
{file_read}\:/lib/amd64/libm.so.1,\
{file_read}\:/lib/amd64/libm.so.2,\
{file_read}\:/lib/amd64/libmp.so.2,\
{file_read}\:/lib/amd64/libnsl.so.1,\
{file_read}\:/lib/amd64/libnvpair.so.1,\
{file_read}\:/lib/amd64/libscf.so.1,\
{file_read}\:/lib/amd64/libsocket.so.1,\
{file_read}\:/lib/amd64/libthread.so.1,\
{file_read}\:/lib/amd64/libucrypto.so.1,\
{file_read}\:/lib/amd64/libuutil.so.1,\
{file_read}\:/lib/amd64/libz.so.1,\
{file_read}\:/proc/*,\
{file_read}\:/system/volatile/name_service_door,\
{file_read}\:/system/volatile/tzsync,\
{file_read}\:/tmp,\
{file_read}\:/tmp/hsperfdata_root,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/bin/java,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/jre/lib/amd64/jvm.cfg,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/jre/lib/amd64/libjava.so,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/jre/lib/amd64/libverify.so,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/jre/lib/amd64/libzip.so,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/jre/lib/amd64/server/libjvm.so,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/jre/lib/ext,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/jre/lib/ext/meta-index,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/jre/lib/meta-index,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/jre/lib/resources.jar,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/jre/lib/rt.jar,\
{file_read}\:/usr/jdk/instances/jdk1.8.0/lib/amd64/jli/libjli.so,\
{file_read}\:/usr/lib/amd64/libCrun.so.1,\
{file_read}\:/usr/lib/amd64/libdemangle.so.1,\
{file_read}\:/usr/lib/amd64/libsched.so.1,\
{file_read}\:/usr/lib/amd64/libsmbios.so.1,\
{file_read}\:/usr/share/lib/zoneinfo/US/Eastern,\
{file_read}\:/vagrant/HelloWorld.class;limitprivs=file_read
In order to produce the error I added {file_read}\:/absolute/path
entries until the error was generated. I used pre-existing files by generated by calling find /usr/lib -name '*.jar'
and adding them until it failed with EOVERFLOW
In my case the following list of files was enough. Removing any of them was enough for it to work again.
{file_read}\:/usr/lib/rad/java/authentication.jar,\
{file_read}\:/usr/lib/rad/java/authentication_1.jar,\
{file_read}\:/usr/lib/rad/java/config.jar,\
{file_read}\:/usr/lib/rad/java/config_1.jar,\
{file_read}\:/usr/lib/rad/java/container.jar,\
{file_read}\:/usr/lib/rad/java/container_1.jar,\
{file_read}\:/usr/lib/rad/java/control.jar,\
{file_read}\:/usr/lib/rad/java/control_1.jar,\
{file_read}\:/usr/lib/rad/java/dlmgr.jar,\
{file_read}\:/usr/lib/rad/java/dlmgr_1.jar,\
{file_read}\:/usr/lib/rad/java/errors.jar,\
{file_read}\:/usr/lib/rad/java/errors_1.jar,\
{file_read}\:/usr/lib/rad/java/evscntl.jar,\
{file_read}\:/usr/lib/rad/java/evscntl_1.jar,\
{file_read}\:/usr/lib/rad/java/files.jar,\
{file_read}\:/usr/lib/rad/java/files_1.jar,\
{file_read}\:/usr/lib/rad/java/kstat.jar,\
{file_read}\:/usr/lib/rad/java/kstat_1.jar,\
{file_read}\:/usr/lib/rad/java/modules.jar,\
{file_read}\:/usr/lib/rad/java/modules_1.jar,\
{file_read}\:/usr/lib/rad/java/network.jar,\
{file_read}\:/usr/lib/rad/java/network_1.jar,\
{file_read}\:/usr/lib/rad/java/pam.jar,\
{file_read}\:/usr/lib/rad/java/pam_1.jar,\
{file_read}\:/usr/lib/rad/java/panels.jar,\
{file_read}\:/usr/lib/rad/java/panels_1.jar,\
{file_read}\:/usr/lib/rad/java/rad.jar,\
{file_read}\:/usr/lib/rad/java/smf.jar,\
{file_read}\:/usr/lib/rad/java/smf_1.jar,\
{file_read}\:/usr/lib/rad/java/smf_old.jar,\
{file_read}\:/usr/lib/rad/java/smf_old_1.jar,\
{file_read}\:/usr/lib/rad/java/time.jar,\
{file_read}\:/usr/lib/rad/java/time_1.jar,\
{file_read}\:/usr/lib/rad/java/usermgr.jar,\
{file_read}\:/usr/lib/rad/java/usermgr_1.jar,\
{file_read}\:/usr/lib/rad/java/zfsmgr.jar,\
{file_read}\:/usr/lib/rad/java/zfsmgr_1.jar,\
{file_read}\:/usr/lib/rad/java/zonemgr.jar,\
{file_read}\:/usr/lib/rad/java/zonemgr_1.jar,\
{file_read}\:/usr/lib/rad/java/zonesbridge.jar,\
{file_read}\:/usr/lib/rad/java/zonesbridge_1.jar,\
{file_read}\:/usr/lib/ocm/ccr/inventory/engines.jar,\
{file_read}\:/usr/lib/ocm/ccr/inventory/metricdata.jar,\
{file_read}\:/usr/lib/ocm/ccr/inventory/core.jar,\
{file_read}\:/usr/lib/ocm/ccr/inventory/scripts.jar,\
{file_read}\:/usr/lib/ocm/ccr/inventory/ocmcert.jar,\
{file_read}\:/usr/lib/ocm/ccr/oui/jlib/OraPrereq.jar,\
{file_read}\:/usr/lib/ocm/ccr/oui/jlib/OraCheckPoint.jar,\
{file_read}\:/usr/lib/ocm/ccr/oui/jlib/OraInstallerNet.jar,\
{file_read}\:/usr/lib/ocm/ccr/oui/jlib/OraInstaller.jar,\
{file_read}\:/usr/lib/ocm/ccr/oui/jlib/share.jar,\
{file_read}\:/usr/lib/ocm/ccr/oui/jlib/xmlparserv2.jar,\
{file_read}\:/usr/lib/ocm/ccr/lib/OCMRFCreator.jar,\
{file_read}\:/usr/lib/ocm/ccr/lib/OpsCenterHarvester.jar,\
{file_read}\:/usr/lib/ocm/ccr/lib/emCCR.jar,\
{file_read}\:/usr/lib/ocm/ccr/lib/emgcharvester.jar,\
{file_read}\:/usr/lib/ocm/ccr/lib/emocmclnt-14.jar,\
{file_read}\:/usr/lib/ocm/ccr/lib/emocmclnt.jar,\
{file_read}\:/usr/lib/ocm/ccr/lib/emocmcommon.jar,\
{file_read}\:/usr/lib/ocm/ccr/lib/emocmdsf.jar
Ensure your profile changes are reflected by executing profiles -l
Is this just two bugs under Solaris 11.3? One in the profiles
command (which can be worked around), and the other within the kernel? (Which cannot easily be worked around)
First of all, why not use wildcards like {file_read}\:/usr/lib/rad/java/*
?
That will limit the number of entries. Also, having so many files specifically when we are talking about {file_read}
will be very expensive.
The number of rules are limited but there is an (undocumented) tunable:
xpol_rules_max
which you can set in /etc/system
by adding the line: set xpol_rules_max=100
or on-the-fly using mdb -wk
as follows:
# mdb -wk
Loading modules: [ unix genunix specfs dtrace mac cpu.generic uppc pcplusmp zvpsm scsi_vhci zfs sata sd ip hook neti arp usba kssl sockfs lofs random idm cpc crypto fcip fctl nfs ufs logindmux ptm sppp ]
> xpol_rules_max/x
xpol_rules_max:
xpol_rules_max: 64
> xpol_rules_max/w 100
xpol_rules_max: 0x64 = 0x100