Closed jthyssenrocket closed 1 month ago
For whoever picks this up, I have REXX code that uses SYSCALL to test for SETUID, among other things,
Something like this should be ok, example of output for zFS mounted with -s nosetuid
df -v "{zowe.runtimeDirectory}/components/zss/bin"
Mounted on Filesystem Avail/Total Files Status
/mount/point (ZOWE.TEST) 3703006/5588640 4294953614 Available
ZFS, Read/Write, Device:T800, ACLS=Y, No SUID
aggrgrow
File System Owner : ZEUS Automove=Y Client=N
Filetag : T=off codeset=0
Aggregate Name : ZOWE.TEST
Using "df -v" means you have to parse command output, which might change over time, or differ with different code pages or shells, so it is not a valid option for testing whether SETUID is set or not.
if \SyscallCmd('statvfs' Dir 'stfs.',ToDD,0)
then call Echo ToDD,'* unable to test for NOSETUID',
'(errno' errno 'errnojr' errnojr')'
else do
call Echo ToDD,'* the filesystem is mounted' word('R/W R/O',stfs.11+1)
if stfs.12 /* STFS_NOSUID=12 STFS_RDONLY=11 */
then do
/*
SETUID|NOSETUID
Specifies whether the SETUID and SETGID mode bits on executables
in this file system are respected. Also determines whether the
APF and the Program Control extended attributes are honored.
*/
select
when SUid = 1 then do; xRC=8; MsgHeader='** ERROR **'; end
when SUid = 0 then do; xRC=0; MsgHeader='** INFO **'; end
otherwise xRC=4; MSgHeader='** WARNING **'
end /* when SUid */
call Echo ToDD,MsgHeader 'the filesystem is mounted with',
'the NOSETUID argument'
cRC=max(cRC,xRC)
end /* NOSETUID */
if stfs.16 /* STFS_NOSEC=16 */
then do
/*
SECURITY|NOSECURITY
Specifies whether security checks are to be enforced for files in
this file system. When a z/OS UNIX file system is mounted with the
NOSECURITY option enabled, any new files or directories that are
created will be assigned an owner of UID 0, no matter what UID
issued the request.
*/
call Echo ToDD,'** WARNING ** the filesystem is mounted with',
'the NOSECURITY argument'
cRC=max(cRC,4)
end /* NOSETUID */
end /* statvfs */ ```
A lot of internal logic depends on shell commands output...
I am preferring either shell function or JS function (if not already there).
Another option is to check only zssServer
and/or zssServer64
file with extattr
. The question is where:
zss/bin/start.sh
if [ "$ZWE_components_zss_agent_64bit" = "true" ] && [ -x "${ZSS_SERVER_64}" ]; then
ZSS_SERVER="${ZSS_SERVER_64}"
else
ZSS_SERVER="${ZSS_SERVER_31}"
fi
if [ -z $(extattr "${ZSS_SERVER}" | grep 'Program controlled = YES') ]; then
echo "Some warning message"
fi
* zwe install
* zwe support
* Other?
I prefer the JS function and we owe an investigation of whether this is available programmatically.
I have a working prototype in JS:
import * as zos from 'zos';
const PATHS = [ './', '/', '/bin/', '', null, true, false ];
for (let p = 0; p < PATHS.length; p++) {
const result = zos.getStatvfs(PATHS[p]);
console.log(`===> "${PATHS[p]}"`);
console.log(`Stats=${JSON.stringify(result[0])}`);
console.log(`RC=${result[1]}\n`);
}
===> "./"
Stats={"bsize":1024,"blocks":4096080,"bavail":1781927,"fsid":4009,"flag":0,"frsize":1024,"bfree":1781927,"files":4294967295,"ffree":4294935683,"favail":4294935683,"namemax":255,"OEmaxfilesizehw":1023,"OEmaxfilesizelw":-1024,"OEusedspace":2314153,"OEinvarsec":0}
RC=0
===> "/"
Stats={"bsize":1024,"blocks":3600,"bavail":3275,"fsid":1,"flag":1,"frsize":1024,"bfree":3275,"files":4294967295,"ffree":4294967244,"favail":4294967244,"namemax":255,"OEmaxfilesizehw":1023,"OEmaxfilesizelw":-1024,"OEusedspace":325,"OEinvarsec":0}
RC=0
===> "/bin/"
Stats={"bsize":1024,"blocks":3954960,"bavail":159562,"fsid":2,"flag":1,"frsize":1024,"bfree":159562,"files":4294967295,"ffree":4294940191,"favail":4294940191,"namemax":255,"OEmaxfilesizehw":1023,"OEmaxfilesizelw":-1024,"OEusedspace":3795398,"OEinvarsec":0}
RC=0
===> ""
Stats=null
RC=129
===> "null"
Stats=null
RC=129
===> "true"
Stats=null
RC=129
===> "false"
Stats=null
RC=129
I like doing this check at install, init, AND launcher startup to catch config changes.
Doing the test during install does not make sense for larger customers as they would install on a test system and then deploy to the target systems. Also, SMP/E install of Zowe would not do this, unless you provide a script SMPE must run when it processes a specific file. Doing the test during startup is useful but will increase startup time and resource usage for every customer, and that just for catching somebody doing a setup error. For my products we have a log & system setup gathering script that does this test (among many others) and report if something is wrong. Customers run this when they have issues, and if they can't figure out the issue based on the comments from the tool, they pass the output to support.
The SETUID requirement is valid for all environments where the customer want to run Zowe. Checking the mount options in the sandbox won't help if the customer mounted the zFS with NOSETUID in production.
The check should happen at least once on after initial install and any release upgrade.
I don't know the best location for this check.
How about you run it AFTER startup? The startup process can check the server RC and run the SETUID check only when needed (RC not 0) for all related directories (/bin, /usr/lpp/zowe, /usr/lpp/java).
zssServer runs program controlled which requires that the zFS is mounted with option SETUID. If the zFS is mounted with option NOSETUID zssServer is no longer program controlled and certain API calls can fail with BPXTLS failed: rc=-1, return code=139, reason code=0x0be802af
I suggest to modify the relevant install script to check if the zFS mount where zssServer is installed is mounted with SETUID option. I am not sure how to do it, but it might be possible to script over "df -v".
See information on SETUID/NOSETUID here: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxa500/tsomount.htm