Individual Entry

The immorality of immortality. — Part 2

In the article "The immorality of immortality — Part 1," I discussed various problems stemming from the setting of the PCB$V_NODELET bit on INTERACTIVE processes by the database product, Caché. The first installment of this article was intended to serve more as a cathartic expository of problems which the setting of this bit can create as well as an exposé of one commercial product doing so, and less of a dissertation about the ways to address or correct the problem. In this follow-up, I will explore various ways to achieve what I believe the Caché product is trying to achieve without making the erroneous "NODELET" pact with the devil. Immortal Process Goes 'Boink' — PCB$V_NODELET

Before looking for alternatives to setting the PCB$V_NODELET bit, let's see how a process with this bit set interacts with other processes. In particular, what happens when a $ STOP/IDENTIFIER={pid} command is issues to terminate such a process. To do this, a simple demonstrator program which sets the process's PCB$V_NODELET bit can be use to explore these interactions. Such a program is show here: .TITLE DEMO_IMMORTALITY

.LIBRARY "SYS$LIBRARY:STARLET.MLB" ; look here for:
$SSDEF ; system status & completion codes

.LIBRARY "SYS$LIBRARY:LIB.MLB" ; look here for:
$PCBDEF ; process control block definitions

.PSECT DATA,WRT,NOEXE,5
X60SEC: .LONG -60*1000*1000*10,-1

.PSECT CODE,NOWRT,EXE,5
.ENTRY DEMO,0

$CMKRNL_S ROUTIN=KERNEL_SETBIT

$SCHDWK_S daytim = X60SEC
$HIBER_S

PUSHL #SS$_FISH
CALLS #1,LIB$SIGNAL
RET

.ENTRY KERNEL_SETBIT,0
BISL2 #PCB$M_NODELET,PCB$L_STS(R4)
RET
.END DEMO

The program above is written in Macro-32 which is available on all systems. It will set the process's PCB$V_NODELET bit and then, it $HIBERnates for 60 seconds before it exits. After one minute, it will exit signaling SS$_FISH to signify that it completed on its own. Any other status signaled or returned would indicate that something else affected this program's course of execution. Because this program uses the $CMKRNL system service, the CMKRNL privilege is needed to explore with this program on your own. However, it's is not necessary that you do so to follow along at home.

With the demonstrator program compiled and linked, it is now run in another process. To see how having the PCB$V_NODELET bit set affects this process, I issued a few commands directed at the process, by PID, which would affect a normal OpenVMS process.

The first and obvious command is $ STOP/IDENTIFICATION={pid}, since it is this command that Caché was so intent upon debilitating. When issued, supplying the PID (process ID) of the process which is executing the demonstrator program above, this command returned %SYSTEM-F-NODELETE, object cannot be deleted; thus, showing that setting this bit has, indeed, achieved that which Caché is seeking to prevent. In addition to a complete process termination, the $ STOP/IMAGE/IDENTIFICATION={pid} command was also tested. This command returned to the DCL command prompt with normal completion status; however, the program in the other process continued to execute. At the end of one minute, the test program exited with the prescribed signaled error code.

All other DCL commands, such as those seeking information from and about the process, continue to function when the PCB$V_NODELET bit is set.

The problem now is that if the process which ran the demonstrator program were to $ LOGOUT, it would find itself looping ad nauseum in SYS$EXIT which is what is happening in the case of the Caché executing processes at the medical center discussed in the initial article. To avoid this issue, another program — similar to the demonstrator program above — was written to clear the PCB$V_NODELET bit.


Immortal Alternative Lifestyles

There are several other process status bits which can be set to effectively thwart attempts by third-parties to delete another process. Two of these will now be discussed. Their purpose is to signify to OpenVMS that a particular activity is already in progress. When OpenVMS is asked to perform a task that is already in progress, it assumes that that task actually is in progress and it doesn't try to instigate that action again. It's sort of like looking for a lost set of keys. You don't keep looking for them once you've located them. That would be fruitless. So would deleting a process that is already being deleted or forcing an image exit if the image is already exiting.

So, instead of setting the PCB$V_NODELET bit in the demonstrator program, the code is modified to set the PCB$V_DELPEN bit. .ENTRY KERNEL_SETBIT,0
BISL2 #PCB$M_DELPEN,PCB$L_STS(R4)
RET
.END DEMO

This is the bit which OpenVMS sets to indicate that the process is already undergoing the process of being deleted. Using the same $ STOP/IDENTIFICATION={pid} command, this appears to thwart attempts to terminate the process. The only difference being that when the command completes, it does so with normal completion status; not %SYSTEM-F-NODELETE, object cannot be deleted.

Setting the PCB$V_DELPEN bit on a process does not thwart $ STOP/IMAGE/IDENTIFICATION={pid} from being used to force the executing image to exit. However, like the PCB$V_DELPEN bit which indicates that the process is being deleted, there is a similar bit to indicate that the $FORCEX system service has been employed to force an image to terminate. That bit is the PCB$V_FORCPEN bit.

Using the same demonstrator program but now setting both the PCB$V_DELPEN bit and the PCB$V_FORCPEN bit, any third-party's .ENTRY KERNEL_SETBIT,0
BISL2 #PCB$M_DELPEN!PCB$M_FORCPEN,PCB$L_STS(R4)
RET
.END DEMO

attempts to utilize the $ STOP/IDENTIFICATION={pid} or the $ STOP/IMAGE/IDENTIFICATION={pid} commands cause both to return with normal completion status and the target process is unaffected. The same results as setting the PCB$V_DELPEN bit have been realized save that issuing the $ STOP/IDENTIFICATION={pid} command does not indicate that the process cannot be deleted.

There is one drawback to setting the PCB$V_DELPEN bit. Code which must issue an AST (asynchronous system trap) to the process to collect information about the process will not work. OpenVMS assumes that since the process is being deleted, there is no reason to queue the AST to a dying process. Thus, issuing a command such as $ SHOW PROCESS/IDENTIFICATIN={pid} will return with the status message %SYSTEM-F-SUSPENDED, process is suspended. This may or may not be an issue, but there are still a few aces up the sleeve. The one benefit this does present is that a process with these bits set can die without being trapped in the infamous immortal conundrum loop.

A slight permutation of the aforementioned scheme using the PCB$V_DELPEN bit and the PCB$V_FORCPEN bit exists with OpenVMS versions V7.3 and later. In these versions of OpenVMS, a new PCB (process control block) cell was introduced -- PCB$L_DELPRC_FORCED. This new cell is used as a mask of the access modes for which the $DELPRC system service's forced exit processing has been initiated. The PCB$L_DELPRC_FORCED mask was intended to replace the use of the PCB$M_FORCPEN bit in the PCB$L_STS cell which would still allow repetitive invocations of $DELPRC calls to initiate its rundown activities. This knowledge can be exploited to our advantage as yet another way to thwart third-party process termination.

The PCB$L_DELPRC_FORCED is used for a bit mask for each of the four modes — KERNEL, EXECUTIVE, SUPERVISOR and USER. It's a longword to promote aligned access but only the low four bits of the field have any significance. Only the lowest nybble's bits need to be set; however, I will typically shove negative one — ^xFFFFFFFF — into this PCB cell to signify that it has been externally modified. Thus, the code for this method is: .ENTRY KERNEL_SETBIT,0
BISL2 #PCB$M_FORCPEN,PCB$L_STS(R4)
MNEGL #1,PCB$L_DELPRC_FORCED(R4)
RET
.END DEMO

This code provides insulation for both the process and the image from the wanton issue of the $ STOP/IDENTIFICATION={pid} and the $ STOP/IMAGE/IDENTIFICATION={pid} commands. In addition, a $ SHOW PROCESS/IDENTIFICATION={pid} command functions properly with this method. This is my preferred way of preventing a DETACHED process image from being deleted by a third-party. There's no need, in this scenario, to clean-up and or reset the PCB$L_DELPRC_FORCED cell.

Will any of these mechanisms suffice in the scheme of Caché processing? I can say that I honestly do not know. I had tried to obtain a copy of Caché when ProvN AUDIT was being wrongly accused of causing the interminable process looping but Caché refused to cooperate to provide a copy. Why? I do not know but I do have my suspicions. What better way to cover up immorality?


Comments?


To thwart automated comment SPAM, you must answer this question to post.

Comment moderation is enabled. Your comment(s) will not be visisble until approved.
Remember personal info?
Notify?
Hide email?
All html tags, with the exception of <b> and <i>, will be removed from your comment. You can make links by simply typing the url or email-address.
Powered by…