Do you need the Mitigation Patch in CDB$ROOT and all PDBS?

Thanks to Axel Delin for asking this very reasonable question on the blog. Do you need the Mitigation Patch in CDB$ROOT and all PDBS? Background for this question is that Axel can’t remove JVM but doesn’t use it. A typical case we cover in our slides and presentations as well. And in this case, the Mitigation Patch will become your friend. Please note: If you DON’T have JAVAVM in your database, you won’t need to pay attention and instead could stop reading now.

Do you need the Mitigation Patch in CDB$ROOT and all PDBS?

Photo by Mick Truyts on Unsplash

Mitigation Patch

You can read more about the Mitigation Patch, and its pros and cons here:

In short, you will find the Mitigation Patch in all your environments since 11.2.0.4. Once you execute the dbmsjdev.sql script, you can disable the Java subsystem with a call. Only real downside: Whenever you patch or upgrade, you need to enable it beforehand. Plus, you shouldn’t forget to disable it after upgrade or patching again.

Mitigation Patch and Multitenant?

For non-CDB databases, everything is easy.

@?/rdbms/admin/dbmsjdev.sql

And then you disable JVM with:

exec dbms_java_dev.disable

But how about Multitenant?

At first, you can decide WHERE you’d like to disable the Java subsystem. This is pretty handy as you could disable JVM in PDB1, PDB2 and PDB4 but have it still enabled in PDB3.

But there are a lot of questions coming to my mind right now.

  • How do you make the dbms_java_dev.disable call available in all containers?
  • When you provision a new PDB, will it have JVM on or off?
  • Can you have JVM enabled in a PDB when you disabled it in the CDB$ROOT?
  • Can you disable JVM in all containers with one single command?

Maybe I didn’t search clever enough but I couldn’t find answers in MOS or in the documentation to my questions. No idea why I need to raise these questions as our team does not own OJVM … but let’s play a bit with the database and see what happens.

Setup

I will use a 19.10.0 CDB with 3 PDBs:

SQL> show pdbs

    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  READ ONLY  NO
	 3 PDB1 			  READ WRITE NO
	 4 PDB2 			  READ WRITE NO
	 5 PDB3 			  READ WRITE NO

And in all of them I’ll have the JVM component enabled:

SQL> select CON_ID, COMP_ID, STATUS from CDB_REGISTRY where COMP_ID='JAVAVM' order by CON_ID;

    CON_ID COMP_ID    STATUS
---------- ---------- --------
	 1 JAVAVM     VALID
	 2 JAVAVM     VALID
	 3 JAVAVM     VALID
	 4 JAVAVM     VALID
	 5 JAVAVM     VALID

One important thing to mention: When I write “Mitigation Patch is activated”, I mean that the dbmsjdev.sql script has been run. Then the functionatily to disable the JAVAMVM is available. When I write “JAVAVM is disabled”, then nobody can use the JAVAVM, and you are safe.

Can you enable the Mitigation Patch in CDB$ROOT only?

In CDB$ROOT only:

@?/rdbms/admin/dbmsjdev.sql
exec dbms_java_dev.disable

Unfortunately DBA_REGISTRY does not give any indication of the fact that JAVAVM has been disabled now.

Luckily I had this issue before – and blogged about it a while ago: OJVM and the Mitigation Patch – Things to know in 2020. This is the key:

SQL> select status from dba_triggers where trigger_name='DBMS_JAVA_DEV_TRG';

STATUS
--------
DISABLED

What does this mean?

It means, the Mitigation Patch is active, but JAVAVM is still ENABLED.

The three potential results of the query select status from dba_triggers where trigger_name=’DBMS_JAVA_DEV_TRG’; mean:

  • Query returns “no rows selected”: You haven’t run dbmsjdev.sql in this container
  • Query returns DISABLED: You ran dbmsjdev.sql but the JAVAVM is still ENABLED
  • Query returns ENABLED: You ran dbmsjdev.sql and the JAVAVM is DISABLED

Looks weird? Yes, it does … and don’t shoot the messenger as I haven’t implemented it this way.

What you want is the last bullet point: The query returns ENABLED, and nobody can use JAVAVM.

Let me bring this now into a useful query for my Multitenant environments:

column STATUS format A60

SELECT
t.con_id,
CASE t.status WHEN 'ENABLED' THEN 'Mitigation patch active, JAVAVM is disabled'
            WHEN 'DISABLED' THEN 'Mitigation patch active, but JAVAVM is still enabled'
            END AS status
from CDB_TRIGGERS t, CDB_REGISTRY r
where t.TRIGGER_NAME='DBMS_JAVA_DEV_TRG' AND
      r.comp_id='JAVAVM' AND
      t.con_id=r.con_id
order by CON_ID;


CON_ID STATUS
------ ------------------------------------------------------------
     1 Mitigation patch active, but JAVAVM is still enabled
     3 Mitigation patch active, JAVAVM is disabled

2 rows selected.

I have activated the Mitigation Patch in CDB$ROOT (CON_ID=1) and PDB1 (CON_ID=3). In the root container JAVAMVM can still be used. In PDB1 is has been disabled and can’t be used.

You have the choice where you activate the Mitigation Patch – and where you really disable JAVAVM. I’d recommend in case you have the intention to disable JAVAVM to activate the Mitigation Patch in all containers includeing the PDB$SEED – and then disabling JAVAVM at will or in all containers.

Activate the Mitigation Patch in all containers

I create a simple script called miti_activate.sql:

-- Script Name: miti_activate.sql 
--
@?/rdbms/admin/dbmsjdev.sql

And then I execute it in all containers:

$ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -n 1 -l /home/oracle -b miti_active -d /home/oracle miti_activate.sql

Let me check with my above query:

    CON_ID STATUS
---------- ------------------------------------------------------------
	 1 Mitigation patch active, JAVAVM is enabled
	 2 Mitigation patch active, JAVAVM is enabled
	 3 Mitigation patch active, JAVAVM is enabled
	 4 Mitigation patch active, JAVAVM is enabled
	 5 Mitigation patch active, JAVAVM is enabled

Be aware: I ran the dbmsjdev.sql again – but JAVAVM was DISABLED in PDB1 (CON_ID=3) before. Now it is ENABLED – ouch! Hence, please double-check.

Let me now DISABLE JAVAVM in all containers. Sounds simple, doesn’t it?

*** At this point I’ve had to adjust my blog post – thanks to YEKI for the hint with PDB$SEED!! ***

I ran into this error:

BEGIN dbms_java_dev.disable; END;

*
ERROR at line 1:
ORA-20032: Disable failed. Parameter _oracle_script found set
ORA-06512: at "SYS.DBMS_JAVA_DEV", line 18
ORA-06512: at "SYS.DBMS_JAVA_DEV", line 12
ORA-06512: at "SYS.DBMS_JAVA_DEV", line 34
ORA-06512: at line 1

when I set _ORACLE_SCRIPT=TRUE to alter my PDB$SEED as well.

This means, you can’t use catcon.pl but rather need to connect to all container and disable it manually.

But I learned (thanks Yeki!) that you won’t need to set _ORACLE_SCRIPT to treat PDB$SEED.

SQL> alter session set container=PDB$SEED;
Session altered.

SQL> shutdown
Pluggable Database closed.

SQL> startup
Pluggable Database opened.

SQL> show pdbs

    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  READ WRITE NO


SQL> start ?/rdbms/admin/dbmsjdev.sql

SQL> exec dbms_java_dev.disable;
PL/SQL procedure successfully completed.

SQL> shutdown
Pluggable Database closed.

SQL> startup open read only;
Pluggable Database opened.

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO

And then I check all my PDBs:

    CON_ID STATUS
---------- ------------------------------------------------------------
         1 Mitigation patch active, JAVAVM is disabled
         2 Mitigation patch active, JAVAVM is disabled
         3 Mitigation patch active, JAVAVM is disabled
         4 Mitigation patch active, JAVAVM is disabled
         5 Mitigation patch active, JAVAVM is disabled

Provisiong a new PDB

Let me now provision a new PDB and see what happens:

SQL> create pluggable database PDB4 admin user adm identified by adm file_name_convert=('pdbseed','pdb4');
Pluggable database created.

SQL> alter pluggable database PDB4 open;
Pluggable database altered.

SQL> start check_mitigation_patch.sql

    CON_ID STATUS
---------- ------------------------------------------------------------
	 1 Mitigation patch active, JAVAVM is disabled
	 2 Mitigation patch active, JAVAVM is disabled
	 3 Mitigation patch active, JAVAVM is disabled
	 4 Mitigation patch active, JAVAVM is disabled
	 5 Mitigation patch active, JAVAVM is disabled
	 6 Mitigation patch active, JAVAVM is disabled

Perfect. New PDBs will be provisioned with the Mitigation Patch being active, and JAVAVM being disabled.

Conclusion

When you don’t use JAVAVM and you’d like to disable it, you need two steps. At first, you need to activate the Mitigation Patch. It is included in all bundle patches since 2018 as far as I’m aware. And then you need to DISABLE the JAVAVM with a call to DBMS_JAVA_DEV.

You can do this independently for each container, regardless whether you have disabled JAVAVM in the CDB$ROOT or not.

But there is one single flaw when you do this after provisioning a lot of PDB already:
You can’t use catcon.pl for this task but instead need either to connect to each of the PDBs manually, or write your own script who does that.

The crucial part is having JAVAVM being disabled in PDB$SEED. Once you completed this, all future PDBs you’ll provision have JAVAVM disabled then by default.

Further Links and Information

–Mike

Share this: