.TITLE EXECSYMB_KM -- EXECSYMB kernel-mode code .IDENT "V3.6.0--14Jul94" ;note: EXECSYMB.BLD takes care of selected one of the following two ;VAX=1 ; uncomment if assembling manually for VAX ;AXP=1 ; uncomment if compiling manually for AXP .LIBRARY "SYS$LIBRARY:LIB.MLB" $PLVDEF ; Define PLV offsets and values $SSDEF ; Define system status codes $JIBDEF ; Define JIB symbols $PCBDEF ; Define PCB symbols $PRVDEF ; Define privileges ; ; Written: 09-Oct-1992 by John Osudar for EXECSYMB V3.4.0 ; ; Modification history: ; ; 3.4.0 09-Oct-1992 JO Wrote original version ; 3.5.0 24-Nov-1993 JO Modified to add AXP support ; 3.6.0 14-Jul-1994 JO Bug fix in conditionalization for VAX vs. AXP ; ; This module contains the (few) parts of EXECSYMB that operate in ; kernel mode -- specifically: ; ; (1) The routine that changes the process username ; ; (2) A kernel-mode rundown routine that is called by the system at ; process termination ; ; The main reason for writing this as a user-written system service ; is to gain the rundown routine capability mentioned in (2) above. ; Prior to EXECSYMB V3.4, if the symbiont process was killed (e.g. ; by the job controller's "last gasp" routine during a queue manager ; abort), the active queue processors would continue to run. This ; would prevent a clean restart. ; ; This image must be linked /PROTECT and installed /PROTECT in order ; for it to work. The image file should have no world access, as a ; safeguard against its (unintended) use by unprivileged code. ; (A privilege check *is* also performed in the services.) ; .IF DEFINED AXP $PLVDEF .PSECT PLV_SECTION PAGE,VEC,NOWRT,NOEXE .LONG PLV$C_TYP_CMOD ; PLV$L_TYPE .LONG 0 ; PLV$L_VERSION .LONG 1 ; PLV$L_KERNEL_ROUTINE_COUNT .LONG 0 ; PLV$L_EXEC_ROUTINE_COUNT .ADDRESS ROUTINELIST ; PLV$PS_KERNEL_ROUTINE_LIST .LONG 0 ; PLV$PS_EXEC_ROUTINE_LIST .ADDRESS KM_RUNDOWN ; PLV$PS_KERNEL_RUNDOWN_HANDLER .LONG 0 ; PLV$PS_EXEC_RUNDOWN_HANDLER .LONG 0 ; PLV$PS_RMS_DISPATCHER .LONG 0 ; PLV$PS_KERNEL_ROUTINE_FLAGS .LONG 0 ; PLV$PS_EXEC_ROUTINE_FLAGS .PSECT PDATA NOWRT,NOEXE,PIC,QUAD ROUTINELIST: .ADDRESS LIB_SET_USERNAME .ENDC ; .IF DEFINED VAX .PSECT $$$_XFER_VEC PAGE,NOWRT,EXE,PIC .TRANSFER LIB_SET_USERNAME .MASK LIB_SET_USERNAME CHMK #KMCODE RET KMCODE = -1024 .PSECT _USER_SRV PAGE,VEC,PIC,NOWRT,EXE .LONG PLV$C_TYP_CMOD ; This is change mode dispatcher vector .LONG 0 ; Reserved .LONG KM_DSP-. ; Offset to kernel mode dispatcher .LONG 0 ; No exec dispatcher .LONG KM_RUNDOWN-. ; Offset to rundown service .LONG 0 ; Reserved .LONG 0 ; No RMS dispatcher .LONG 0 ; Address check - PIC image ; .IF_TRUE_FALSE .PSECT CODE NOWRT,EXE,PIC,QUAD .IF_TRUE ; ; Kernel-mode dispatcher, called with R0 - change-mode argument value, ; R4 = PCB address, AP = same as when CHMK executed ; Validate that we are called from a process that has SETPRIV privilege; ; if not, return with insufficient privilege error ; KM_DSP:: BBC #PRV$V_SETPRV,PCB$Q_PRIV(R4),KM_NOPRIV ; Validate privilege CMPL #KMCODE,R0 ; Is it our code (we have only one)? BEQL SET_USERNAME ; Yes, do the set-username operation RSB ; Else it's not ours KM_NOPRIV: MOVZWL #SS$_NOPRIV,R0 ; Report insufficient privilege RET .ENDC ; ; Taken from LIB_SET_USERNAME in SETUSER.MAR, as supplied with EXECSYMB ; .IF DEFINED VAX .ENTRY LIB_SET_USERNAME, ^M .ENDC .IF DEFINED AXP .CALL_ENTRY MAX_ARGS=1,HOME_ARGS=TRUE,LABEL=LIB_SET_USERNAME .ENDC SET_USERNAME: MOVL PCB$L_JIB(R4),R7 ; Get address of JIB for later IFNORD #8,(AP),KM_ACCVIO ; Check argument list accessibility MOVZWL 4(AP),R8 ; Get address of string descriptor IFNORD (R8),@4(R8),KM_ACCVIO ; Check argument value accessibility MOVC5 (R8),@4(R8),#32,#12,G^CTL$T_USERNAME ; Copy into P1 space MOVC5 (R8),@4(R8),#32,#12,JIB$T_USERNAME(R7) ; Copy into JIB MOVZWL #SS$_NORMAL,R0 ; Return with success RET KM_ACCVIO: MOVZWL #SS$_ACCVIO,R0 ; Access violation RET ; ; The rundown service is called with a JSB in kernel mode at IPL 0, and ; must return at IPL 0. None of the system rundown functions have been ; called yet. This code cannot use RMS or RTL routines, but it can use ; system services that don't use RMS. On entry, R4 = PCB address ; The only validation done is a test for SETPRV privilege. ; This code assumes that location CTL$A_COMMON contains a valid pointer ; to the routine that is to be called. ; .IF DEFINED VAX KM_RUNDOWN:: .ENDC .IF DEFINED AXP .CALL_ENTRY MAX_ARGS=0,LABEL=KM_RUNDOWN MOVL G^CTL$GL_PCB,R4 ; Is this necessary for AXP? Who knows?! .ENDC PUSHR #^M ; Save BBC #PRV$V_SETPRV,PCB$Q_PRIV(R4),99$ ; Validate privilege MOVL G^CTL$A_COMMON,R3 ; Get pointer BEQL 99$ ; If it's zero, can't be valid IFNORD #2,(R3),99$ ; Validity test is accessibility CALLS #0,(R3) ; Call the routine 99$: POPR #^M ; Restore .IF DEFINED VAX RSB ; Return .ENDC .IF DEFINED AXP RET ; Return .ENDC ; .END