On Mon, 2 Dec 2013 13:36:43 -0600, Ray Overby <[email protected]> wrote:
>When creating authorized code I use the following guidelines:
>
>- It is not good enough that the authorized code "functions" as
>designed. Authorized code has a higher standard that it must adhere to.
>Your code must not allow malicious or uninformed users to make it do
>things outside of its scope.
>- Pay attention to how you obtain your parameters.
> - Parameters should be accessed in the requesters PSW Key.
> - Make a copy of the parameters so that they cannot be changed
>after you have validated them and before you use them (time of check 2
>time of use vulnerability).
>- Make sure sensitive data is kept in fetch protected storage.
>- Make sure your design does not allow the requester to control where
>the authorized code branches to:
> - By branching to a user specified address in an authorized state
> - By branching on a function code whose value is not verified
>to be in a specific range
>- Be careful issuing authorized services in your code AND allowing
>user parameters to be specified in the authorized services parameter list.
>- Return data to requester in their PSW Key.
>- Don't return control to the requester with a higher level of authority
> - Don't dynamically elevate their security credentials
> - Don't allow the requester the ability to MODESET
> - Don't return control in a different PSW Key or State
>
>
>Ray Overby
>Key Resources, Inc
>Ensuring System Integrity for z/Series
>(312) 574-0007
>
I've lost track of the number of issues I found in this sort of code over the
years. A lot of those problems would have been avoided by following the advice
above.
Some of the more common problems:
Flawed function code validation. Like this in an SVC routine that was
"supposed" to be called with a function code of 0, 4 or 8 in R1.
CH R1,=H'8' IF FUNCTION CODE TOO LARGE
BH RETURN THEN IGNORE IT
B BTABLE(R1) USE BRANCH TABLE TO GO TO REQUIRED
* FUNCTION
BTABLE B HERE FUNCTION=0
B THERE FUNCTION=4
B EVERYWHERE FUNCTION=8
So what happens if it is called with a function code that is not a multiple of
4? Actually, it has a bigger problem than that, can you spot it?
Still, that is better than the two SVC routines I encountered, both of which
were only two bytes long, and that could have been called IEFBR15 and IEFBR1
respectively, or the SVC which performed an MVCL using caller provided
addresses and lengths, with absolutely no validation at all.
Another common problem was SVC routines that found it necessary to examine a
CDE to assist with distinguishing the good guys from the bad (a notoriously
difficult task if the bad guys refuse to cooperate). They followed a pointer
from the caller's RB to locate the CDE, "forgetting" that not all RBs point to
CDEs. The result was that they could be trivially deceived by calling them from
an IRB.
Another issue was inadvertently making an assumption about the contents of some
register. This was more common in PC routines but I also saw more than one SVC
that started out with:
STM R14,R12,12(R13)
Another flawed "good guy" test I saw over and over again was to assume that if
you knew the location of your caller (say PLPA) or if the caller's code resided
in system key storage, then they could be trusted. I suspect this false notion
may have its roots in the original, and somewhat infamous "SPFCOPY" SVC.
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN