Investigate the XFRO MI instruction by experimentation.
According to the MI documentation in the
Investigate the XFRO MI Instruction
To figure out how the XFRO instruction is used by the operating system, you can start with an MI instruction supervisor linkage (*SVL) LIC trace upon a successful change-ownership operation (for example, via the Change Object Owner (CHGOBJOWN) command). Steps involved in the analyzing process are the following:
1. Complete a *SVL trace upon a change-ownership operation.
2. Find the trace record generated for the XFRO instruction in the resulting spooled file of the *SVL trace. Two fields in XFRO's trace record are of interest: the program name field identifies the program that issues the XFRO MI instruction, and the return address field can be used to calculate the precise location in the issuing program's instruction stream from which the XFRO MI instruction is issued.
3. Dump the RISC instruction stream of the issuing program of XFRO and locate the SCV 10 instruction generated for XFRO, the PowerPC instruction at address return address - 4.
4. Analyze the RISC instructions generated for XFRO (including the SCV 10 instruction). By convention, addresses of operands of an MI instruction implemented via a SCV 10 instruction are passed to the LIC routine that actually implements the MI instruction via General Purpose Registers (GPRs) r3 to r6.
5. Debug the program that issues the XFRO instruction and check the contents of each operand of XFRO.
Say you have a Data Queue (*DTAQ) object called QQ that is owned by user profile X. Complete a *SVL trace upon a change-ownership operation on QQ like so:
4 > trcint *on trctbl(a) trctype(*svl)
job(name-of-your-interactive-job) /* Start +
an LIC trace against the current job */
4 > chgobjown QQ *dtaq newown(Y) /* Transfer the +
ownership of QQ from X to Y */
Ownership of object QQ in LSBIN type *DTAQ changed.
4 > trcint *off trctbl(a) /* Stop trace and output +
the trace records to spooled file QPCSMPRT. */
At V5R4, the trace record generated for the XFRO instruction and another MI instruction of interest in the resulting spooled file might look like the following:
MI SVL IDENTIFIER : SV#00001 TIME 14/03/04 10:35:44.669456 TDE# 000000090CC3
XFRO INSTRUCTION #: C300 RETURN ADDRESS: 38DBDEBBC5 0087E0 PROGRAM NAME: QSYCHONR
...
MI SVL IDENTIFIER : SV#00001 TIME 14/03/04 10:35:44.685056 TDE# 000000090CC3
RETRACT INSTRUCTION #: C300 RETURN ADDRESS: 3D0BCC1206
The trace record generated for XFRO reveals that the QSYS/QSYCHONR program (Command Processing Program (CPP) of the CHGOBJOWN command) issues the XFRO instruction. The exact location in the RISC instruction stream of QSYCHONR where the XFRO instruction is issued is one PowerPC instruction (4 bytes) before the RETURN ADDRESS field: 38DBDEBBC5 0087E0. From the System Service Tools (SST) dump of the QSYCHONR program, we can find the disassembled PowerPC instructions generated for the XFRO instruction. For example, the following are the PowerPC instructions generated for XFRO in the QSYCHONR program at V5R4:
MI PROGRAM SUBTYPE: 01 NAME: QSYCHONR ADDRESS: 38DBDEBBC5 000000 |
||||
RISC INSTRUCTIONS (QSYCHONR) |
||||
MI INSTRUCTION NUMBERS: 0505 |
||||
Address |
Location |
Object Text |
Source Statement |
Description |
38DBDEBBC5 0087D0 |
007250 |
387E3220 |
ADDI 3,30,12832 |
r3 addresses operand 1, which is an MI system pointer to the user profile to receive the ownership of operand 2. |
38DBDEBBC5 0087D4 |
007254 |
389E3230 |
ADDI 4,30,12848 |
r4 addresses operand 2, which is an MI system pointer to the object the ownership of which is to be transferred. |
38DBDEBBC5 0087D8 |
007258 |
39400048 |
ADDI 10,0,72 |
Set r10 to the SCV 10 function number of XFRO (72). |
38DBDEBBC5 0087DC |
|
44000141 |
SCV 10 |
Invoke the implementing LIC routine of XFRO. |
The above PowerPC instructions generated for XFRO reveal the following:
- The XFRO MI instruction is implemented via a SCV 10 (Supervisor Call Vectored (SCV) with dispatch code 10) instruction with SCV 10 function number 72 (at V5R4). Many thanks to Mark S. Waterbury, who told me that the SCV 10 function numbers for MI instructions implemented via the SCV 10 instruction changed entirely at V6R1. Thus, if you are working on V6R1 or later releases, the SCV 10 function number of XFRO will be different from the above shown.
- The XFRO instruction takes two operands. Addresses of operand 1 and operand 2 of XFRO are passed to XFRO's implementing LIC routine via GPR 3 and GPR 4 (r3 and r4), respectively. Debugging shows that operand 2 (which is addressed by r4) is an MI system pointer to the object whose ownership is to be transferred, and operand 1 (which is addressed by r3) is an MI system pointer to the user profile that is to receive the ownership of the object identified by operand 2.
Simulate the XFRO MI Instruction
To discover the details of the functionality of the XFRO instruction, we need to issue it directly from a user program. However, since the XFRO instruction is a blocked MI instruction, it is impossible for us either to get a user program containing an XFRO instruction compiled or to issue the XFRO instruction (at runtime) from a user program at security level 40 or above. A workaround is to modify the PowerPC instruction stream of a compiled user program to simulate the process of invoking the XFRO instruction, and then change the user program to system state.
The following OMI program xfronr.emi will become a utility by which we complete our further investigation on the XFRO instruction.
/** * @file xfronr.emi * * XFRO. * @param SYSPTR to the new owner * @param SYSPTR to a system object */
dcl spcptr new-owner@@ parm ; dcl sysptr new-owner@ bas(new-owner@@) ; dcl spcptr obj@@ parm ; dcl sysptr obj@ bas(obj@@) ; dcl ol pl-main( new-owner@@, obj@@ ) parm ext ; entry i-main(pl-main) ext ; matsobj spp@, obj@ ; rtx * ; dcl spcptr spp@ auto ; pend ; |
Compile the OMI program with any wrapper utility of the Create Program (QPRCRTPG) API (e.g., mic). Modify the PowerPC instructions generated for MI instruction 01 (matsobj spp@, obj@;) to simulate the invoking process of the XFRO instruction. The PowerPC instructions before and after modification are shown as follows:
MI PROGRAM SUBTYPE: 01 NAME: XFRONR ADDRESS: |
|||||
MI INSTRUCTION NUMBERS: 01 (address: |
|||||
Address |
Object Text (Before) |
Source Statement (Before) |
Object Text (After) |
Source Statement (After) |
Description |
0015FC |
39400061 |
ADDI 10,0,97 |
E89E0008 |
LD 4,0X8(30) |
Now r30 addresses the program parameter area. The Load Doubleword PowerPC instruction loads the 8-byte address of space pointer new-owner@@ from the program parameter area (at offset hex 08) into r4. |
001600 |
E05FFFF2 |
LQ 2,0XFFF0(31),2 |
E1440002 |
LQ 10,0X0(4),2 |
Load space pointer new-owner@@ that addresses system pointer new-owner@ into r10 and r11. |
001604 |
E8DE0010 |
LD 6,0X10(30) |
61630000 |
ORI 3,11,0 |
r3 is set to the address of system pointer new-owner@. |
001608 |
|
TXER 0,0,41 |
E89E0010 |
LD 4,0X10(30) |
Load the 8-byte address of space pointer obj@@ from the program parameter area (at offset hex 10) into r4. |
|
E0860002 |
LQ 4,0X0(6),2 |
E1440002 |
LQ 10,0X0(4),2 |
Load space pointer obj@@ that addresses system pointer obj@ into r10 and r11. |
001610 |
|
TXER 0,0,41 |
61640000 |
ORI 4,11,0 |
r4 is set to the address of system pointer obj@. |
001614 |
|
ORI 4,5,0 |
39400048 |
ADDI 10,0,72 |
Set r10 to the SCV 10 function number of XFRO (72). |
001618 |
44000141 |
SCV 10 |
44000141 |
SCV 10 |
Invoke the implementing LIC routine of XFRO. |
Finally, change the program state field in the program header of XFRONR from user state (hex 0001) to system state (hex 0080). At V5R4, the program state field is at offset hex
Now, let's test the XFRONR program via the a tiny ILE RPG program xfronrt2.rpgle, which accepts the name of a user profile (user) and the name of an object (obj), and the 2-byte MI object type/subtype code of obj, which resolves a system pointer to user and a system pointer to obj, then invokes the XFRONR program to transfer the ownership of obj to user.
/** * @file xfronrt2.rpgle * * Test of XFRONR. * Transfer the ownership of obj@ to user@. * @param [in] User profile name * @param [in] Object name * @param [in] 2-byte MI object type/subtype code */
h dftactgrp(*no) * Basic resolve option template of the RSLVSP instruction d rslv_opt ds qualified d obj_type d obj_name * required authorization d auth * Prototype of SYSBIF _RSLVSP2 d rslvsp2 pr extproc('_RSLVSP2') d obj * d opt * Prototype of XFRONR d xfronr pr extpgm('XFRONR') d user@ * d obj@ * * Prototype of XFRONRT2 d me pr extpgm('XFRONRT2') d user d obj d objtyp
d user@ s * d obj@ s * d me pi d user d obj d objtyp
/free rslv_opt.obj_type = x'0801'; rslv_opt.obj_name = user; rslvsp2(user@ : rslv_opt);
rslv_opt.obj_type = objtyp; rslv_opt.obj_name = obj; rslvsp2(obj@ : rslv_opt);
xfronr(user@ : obj@); *inlr = *on; /end-free |
Compile the XFRONRT2 program and call it to transfer the ownership of a program (say, MYPGM) from its owning user profile (say, X) to a new user profile (say, Y) like the following:
CALL XFRONRT2 (Y MYPGM x'0201') |
Then issue a Display Object Authority (DSPOBJAUT) command upon program MYPGM. The resulting display might look like the following:
Display Object Authority
Object . . . . . . . : MYPGM Owner . . . . . . . : Y [1] Library . . . . . : MYLIB Primary group . . . : *NONE Object type . . . . : *PGM ASP device . . . . . : *SYSBAS
Object secured by authorization list . . . . . . . . . . . . : *NONE
Object User Group Authority *PUBLIC *CHANGE X *ALL [3] Y *ALL [2] |
Notes
[1] As we expected, now user profile Y owns MYPGM.
[2] As the owner of the object, user profile Y is implicitly granted all authorities to the object.
[3] The XFRO instruction does not affect the former owner's private authorities to the object. This may be a surprise to developers who are familiar with the CHGOBJOWN command. The CHGOBJOWN command takes a Current owner authority (CUROWNAUT) parameter, which defaults to *REVOKE. With the CUROWNAUT(*REVOKE) parameter, a CHGOBJOWN command revokes the authority of the current owner to the object when the ownership of the object is transferred to the new owner. From the *SVL LIC trace data of a CHGOBJOWN command with the CUROWNAUT(*REVOKE) parameter specified, you know that the RETRACT MI instruction is issued to revoke object authorities of the former owner of the object after the XFRO instruction transfers the ownership of the object to its new owner successfully.
More Experiments via the XFRNOR Program
With the XFRONR program, we are able to perform many more experiments about the XFRO instruction. For example, with the XFRONR program and the Edit Object Authority (EDTOBJAUT) command, you can design an experiment to find out the minimal authorities needed to execute the XFRO instruction by a thread:
- Object control authority to operand 2 of XFRO (the object the ownership of which is to be transferred).
- Delete authority to the former owning user profile of the operand 2 of XFRO.
- Insert authority to operand 1 of XFRO (the new owning user profile).
At the operating system level, all object (*ALLOBJ) and security administrator (*SECADM) special authorities are required to change the ownership of a program that adopts a user profile. For a program that uses the user profile of its owner as a source of authority, changes made to its ownership affect the actual authorities the program would adopt from its owner at run time. At the MI level, all object special authority is needed to transfer the ownership of a program that adopts a user profile. Consider doing the experiment shown in the previous section again after a CHGPGM MYPGM USRPRF(*OWNER) command. If the current thread does not have all object special authority, the XFRO instruction issued by the XFRONR program will fail with the MCH1004 (i.e., the Special Authorization Required (hex 0A04)) exception.
The lock enforcement rules applied to the XFRO instruction when accessing MI objects identified by its operands, and the former owning user profile of operand 2 can also be discovered by experiments via the XFRONR program and object locking/unlocking utilities (e.g. the ALCOBJ and DCLOBJ commands).
Note that the ALCOBJ/DCLOBJ commands do not allow the user to lock/unlock a user profile object. Consider the LCKLCK (lcklck.rpgle) program for replacement.
Document the XFRO MI Instruction
Now let's produce our version of documentation for the XFRO MI instruction, based on previous investigation and experiments.
Transfer Ownership (XFRO)
Operand 1: System pointer
Operand 2: System pointer
Description: The Transfer Ownership (XFRO) MI instruction transfers the ownership of a permanent system object identified by operand 2 from its current owning user profile to the user profile identified by operand 1. After the ownership of operand 2 is transferred, the former owning user profile retains the private object authorities it had to operand 2. The new owning user profile is implicitly granted all of the object authorities to operand 2.
An attempt to transfer the ownership of a program that adopts the user profile of its owner causes the Special Authorization Required (hex
The attempt to transfer the ownership of a temporary object causes the Object Not Eligible for Operation (hex 2204) exception to be signaled.
Authorization Required
Object control
Operand 2
Retrieve
Contexts referenced for address resolution
Delete
User profile owning operand 2
Insert
Operand 1
Lock Enforcement
Materialize
Contexts referenced for address resolution
Modify
Operand 1
Operand 2
User profile owning operand 2
Exceptions
22 Object Access
2204 Object Not Eligible for Operation
...and more.
LATEST COMMENTS
MC Press Online