diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2012-12-23 18:43:12 -0500 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2012-12-23 18:43:12 -0500 |
commit | 052e80fcbc9d623cc11d34aa82d742731cdd2c08 (patch) | |
tree | b3dd591992d7e9ee8d609a30095e68f4b42d0707 | |
parent | misc/alt-revdep-pax: comment on how to use portage for /var/db/pkg data (diff) | |
download | elfix-052e80fcbc9d623cc11d34aa82d742731cdd2c08.tar.gz elfix-052e80fcbc9d623cc11d34aa82d742731cdd2c08.tar.bz2 elfix-052e80fcbc9d623cc11d34aa82d742731cdd2c08.zip |
src/paxctl-ng.c: fix flag logic under various --{en,dis}able-{pt,xt}pax
-rw-r--r-- | doc/paxctl-ng.1 | 96 | ||||
-rw-r--r-- | doc/paxctl-ng.pod | 87 | ||||
-rw-r--r-- | src/paxctl-ng.c | 81 |
3 files changed, 125 insertions, 139 deletions
diff --git a/doc/paxctl-ng.1 b/doc/paxctl-ng.1 index 3bd2f36..3a53640 100644 --- a/doc/paxctl-ng.1 +++ b/doc/paxctl-ng.1 @@ -130,64 +130,53 @@ .if n .ad l .nh .SH "NAME" -paxctl\-ng \- get or set the PaX flags for both PT_PAX and XATTR_PAX markings +paxctl\-ng \- get, set or create either PT_PAX or XATTR_PAX flags .SH "SYNOPSIS" .IX Header "SYNOPSIS" -\&\fBpaxctl-ng\fR [\-PpEeMmRrXxSs] [\-v] \s-1ELF\s0 +\&\fBpaxctl-ng\fR \-PpEeMmRrXxSs|\-Z|\-z [\-L|\-l] [\-v] \s-1ELF\s0 .PP -\&\fBpaxctl-ng\fR \-Z [\-v] \s-1ELF\s0 +\&\fBpaxctl-ng\fR \-C|\-c|\-d [\-v] \s-1ELF\s0 .PP -\&\fBpaxctl-ng\fR \-z [\-v] \s-1ELF\s0 -.PP -\&\fBpaxctl-ng\fR \-C [\-v] \s-1ELF\s0 -.PP -\&\fBpaxctl-ng\fR \-c [\-v] \s-1ELF\s0 -.PP -\&\fBpaxctl-ng\fR \-d [\-v] \s-1ELF\s0 -.PP -\&\fBpaxctl-ng\fR \-F [\-v] \s-1ELF\s0 -.PP -\&\fBpaxctl-ng\fR \-f [\-v] \s-1ELF\s0 -.PP -\&\fBpaxctl-ng\fR \-L [\-v] \s-1ELF\s0 -.PP -\&\fBpaxctl-ng\fR \-l [\-v] \s-1ELF\s0 +\&\fBpaxctl-ng\fR \-F|\-f [\-v] \s-1ELF\s0 .PP \&\fBpaxctl-ng\fR [\-h] .SH "DESCRIPTION" .IX Header "DESCRIPTION" -\&\fBpaxctl-ng\fR is used to get or set the PaX flags on \s-1ELF\s0 executables which determine -the memory restrictions on process(es) spawned from them. \fBpaxctl-ng\fR manages -two types of markings, either the older style \s-1PT_PAX\s0 markings which put the flags -in an \s-1ELF\s0 program header named \s-1PT_PAX\s0, or the newer style \s-1XATTR_PAX\s0 markings which -put the flags in an extended attribute field called \*(L"user.pax\*(R" on the filesystem. -Whenever possible, \fBpaxctl-ng\fR will set both \s-1PT_PAX\s0 and \s-1XATTR_PAX\s0 to the same flags. +\&\fBpaxctl-ng\fR is used to get, set or create the PaX flags on \s-1ELF\s0 executables which +determine the memory restrictions on process(es) spawned from them when run under +a PaX enabled kernel. \fBpaxctl-ng\fR manages two types of markings, either the older +style \s-1PT_PAX\s0 markings which put the flags in an \s-1ELF\s0 program header named \s-1PAX_FLAGS\s0, +or the newer style \s-1XATTR_PAX\s0 markings which put the flags in an extended attribute +field named user.pax.flags on the filesystem. Whenever possible, \fBpaxctl-ng\fR +will try to set both \s-1PT_PAX\s0 and \s-1XATTR_PAX\s0 to the same flags. .PP There are drawbacks to both \s-1PT_PAX\s0 and \s-1XATTR_PAX\s0 markings. \s-1PT_PAX\s0 will not work on -\&\s-1ELF\s0 binaries which do not already have a \s-1PT_PAX\s0 program header. Unlike the original -tool, \fBpaxctl\fR, which would try to add this header or convert a \s-1GNU_STACK\s0 header, -\&\fBpaxctl-ng\fR does not edit the \s-1ELF\s0 in any way, beyond setting the PaX flags if and -only if the \s-1PT_PAX\s0 program header already exists. Some \s-1ELF\s0 binaries break when -they are edited. Since, \fBpaxctl-ng\fR will never to so, it is always safe to run -it on such binaries. +\&\s-1ELF\s0 binaries which do not already have a \s-1PAX_FLAGS\s0 program header. Unlike the original +tool, \fBpaxctl\fR, which could be instructed to try to add this header or convert a +\&\s-1GNU_STACK\s0 header, \fBpaxctl-ng\fR does not edit the \s-1ELF\s0 in any way, beyond setting the +PaX flags if and only if the \s-1PAX_FLAGS\s0 program header already exists. Some \s-1ELF\s0 binaries +break when they are edited. Since, \fBpaxctl-ng\fR will never to so, it is usually safe +to run it on such binaries. .PP -Alternatively, \s-1XATTR_PAX\s0 requires a filesystem support Extended Attributes. Most -modern filesystems do so, but not all. Furthermore, one must be careful when +Alternatively, \s-1XATTR_PAX\s0 requires filesystems that support extended attributes. +Most modern filesystems do so, but not all. Furthermore, one must be careful when moving \s-1ELF\s0 objects to ensure that the target filesystem or archive supports -Extended Attributes, otherwise they are lost, unlike \s-1PT_PAX\s0 markings which +extended attributes, otherwise they are lost, unlike \s-1PT_PAX\s0 markings which are carried within the binary itself. .PP \&\fBpaxctl-ng\fR is opportunistic without taking control away from the user. If both -a \s-1PT_PAX\s0 program header and an Extended Attribute field \*(L"user.pax\*(R" exist, then -both fields will be equally updated when the user modifies flags; unless the -\&\fB\-L\fR or \fB\-l\fR flags are given, in which case the markings are limiting to just -\&\s-1PT_PAX\s0 or \s-1XATTR_PAX\s0, respectively. If only one marking is possible, then only that -marking will be updated. Under no circumstances will \fBpaxctl-ng\fR create a \s-1PT_PAX\s0 -program header as \fBpaxctl\fR does. It will only attempt to create an \s-1XATTR_PAX\s0 Extended -Attribute field if it is instructed to do so with the \fB\-C\fR or \fB\-c\fR flags, and it -will attempt to synchronize the \s-1PT_PAX\s0 and \s-1XATTR_PAX\s0 markings if given the \fB\-F\fR or -\&\fB\-f\fR flags. Finally, if the user wished, he can remvoe the Extended Attribute -field \*(L"user.pax\*(R" by running \fBpaxctl-ng\fR with the \fB\-d\fR flag. +a \s-1PAX_FLAGS\s0 program header and a user.pax.flags extended attribute field exist, then +both will be equally updated when the user modifies flags; unless the \fB\-L\fR or \fB\-l\fR +flags are given, in which case the markings are limiting to just \s-1PT_PAX\s0 or \s-1XATTR_PAX\s0, +respectively. If only one marking is possible, then only that marking will be updated. +Under no circumstances will \fBpaxctl-ng\fR create a \s-1PAX_FLAGS\s0 program header as \fBpaxctl\fR +does. It will only attempt to create an extended attribute field if it is instructed +to do so with the \fB\-C\fR or \fB\-c\fR flags, and it will attempt to synchronize the \s-1PT_PAX\s0 +and \s-1XATTR_PAX\s0 markings if given the \fB\-F\fR or \fB\-f\fR flags. Note that when copying \s-1PT_PAX\s0 +to \s-1XATTR_PAX\s0 with the \fB\-F\fR flag, if the user.pax.flags extended attribute field does +not exist, \fBpaxctl-ng\fR will create it as if given either the \fB\-C\fR or \fB\-c\fR flags. +Finally, if the user wishes, he can remove the extended attribute field by running +\&\fBpaxctl-ng\fR with the \fB\-d\fR flag. .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-P\fR or \fB\-p\fR Enable or disable \s-1PAGEEXEC\s0" 4 @@ -212,20 +201,21 @@ eg. \-Pp for \s-1PAGEEXEC\s0, then the default setting \- is used. .PD 0 .IP "\fB\-z\fR Set default setting (\-\-\-\-\-\-)" 4 .IX Item "-z Set default setting (------)" -.IP "\fB\-C\fR Create \s-1XATTR_PAX\s0 xattr with the most secure PaX settings" 4 -.IX Item "-C Create XATTR_PAX xattr with the most secure PaX settings" -.IP "\fB\-c\fR Create \s-1XP_PAX\s0 xattr with the default PaX settings" 4 -.IX Item "-c Create XP_PAX xattr with the default PaX settings" -.IP "\fB\-d\fR Delete \s-1XP_PAX\s0 xattr" 4 -.IX Item "-d Delete XP_PAX xattr" +.IP "\fB\-C\fR Create \s-1XATTR_PAX\s0 markings with the most secure PaX settings" 4 +.IX Item "-C Create XATTR_PAX markings with the most secure PaX settings" +.IP "\fB\-c\fR Create \s-1XATTR_PAX\s0 markings with the default PaX settings" 4 +.IX Item "-c Create XATTR_PAX markings with the default PaX settings" +.ie n .IP "\fB\-d\fR Delete \s-1XATTR_PAX\s0 field, ""user.pax.flags""" 4 +.el .IP "\fB\-d\fR Delete \s-1XATTR_PAX\s0 field, ``user.pax.flags''" 4 +.IX Item "-d Delete XATTR_PAX field, user.pax.flags" .IP "\fB\-F\fR Copy \s-1PT_PAX\s0 flags to \s-1XATTR_PAX\s0, if possible" 4 .IX Item "-F Copy PT_PAX flags to XATTR_PAX, if possible" .IP "\fB\-f\fR Copy \s-1XATTR_PAX\s0 flags to \s-1PT_PAX\s0, if possible" 4 .IX Item "-f Copy XATTR_PAX flags to PT_PAX, if possible" -.IP "\fB\-L\fR Only set \s-1PT_APX\s0 flags, if both are possible" 4 -.IX Item "-L Only set PT_APX flags, if both are possible" -.IP "\fB\-l\fR Only set \s-1XATTR_PAX\s0 flags, if both are possible" 4 -.IX Item "-l Only set XATTR_PAX flags, if both are possible" +.IP "\fB\-L\fR Only set \s-1PT_PAX\s0 flags, if possible" 4 +.IX Item "-L Only set PT_PAX flags, if possible" +.IP "\fB\-l\fR Only set \s-1XATTR_PAX\s0 flags, if possible" 4 +.IX Item "-l Only set XATTR_PAX flags, if possible" .IP "\fB\-v\fR View the flags" 4 .IX Item "-v View the flags" .IP "\fB\-h\fR Print out a short help message and exit." 4 diff --git a/doc/paxctl-ng.pod b/doc/paxctl-ng.pod index 377ee2c..a18a3a5 100644 --- a/doc/paxctl-ng.pod +++ b/doc/paxctl-ng.pod @@ -1,65 +1,54 @@ =head1 NAME -B<paxctl-ng> - get or set the PaX flags for both PT_PAX and XATTR_PAX markings +B<paxctl-ng> - get, set or create either PT_PAX or XATTR_PAX flags =head1 SYNOPSIS -B<paxctl-ng> [-PpEeMmRrXxSs] [-v] ELF +B<paxctl-ng> -PpEeMmRrXxSs|-Z|-z [-L|-l] [-v] ELF -B<paxctl-ng> -Z [-v] ELF +B<paxctl-ng> -C|-c|-d [-v] ELF -B<paxctl-ng> -z [-v] ELF - -B<paxctl-ng> -C [-v] ELF - -B<paxctl-ng> -c [-v] ELF - -B<paxctl-ng> -d [-v] ELF - -B<paxctl-ng> -F [-v] ELF - -B<paxctl-ng> -f [-v] ELF - -B<paxctl-ng> -L [-v] ELF - -B<paxctl-ng> -l [-v] ELF +B<paxctl-ng> -F|-f [-v] ELF B<paxctl-ng> [-h] =head1 DESCRIPTION -B<paxctl-ng> is used to get or set the PaX flags on ELF executables which determine -the memory restrictions on process(es) spawned from them. B<paxctl-ng> manages -two types of markings, either the older style PT_PAX markings which put the flags -in an ELF program header named PT_PAX, or the newer style XATTR_PAX markings which -put the flags in an extended attribute field called "user.pax" on the filesystem. -Whenever possible, B<paxctl-ng> will set both PT_PAX and XATTR_PAX to the same flags. +B<paxctl-ng> is used to get, set or create the PaX flags on ELF executables which +determine the memory restrictions on process(es) spawned from them when run under +a PaX enabled kernel. B<paxctl-ng> manages two types of markings, either the older +style PT_PAX markings which put the flags in an ELF program header named PAX_FLAGS, +or the newer style XATTR_PAX markings which put the flags in an extended attribute +field named user.pax.flags on the filesystem. Whenever possible, B<paxctl-ng> +will try to set both PT_PAX and XATTR_PAX to the same flags. There are drawbacks to both PT_PAX and XATTR_PAX markings. PT_PAX will not work on -ELF binaries which do not already have a PT_PAX program header. Unlike the original -tool, B<paxctl>, which would try to add this header or convert a GNU_STACK header, -B<paxctl-ng> does not edit the ELF in any way, beyond setting the PaX flags if and -only if the PT_PAX program header already exists. Some ELF binaries break when -they are edited. Since, B<paxctl-ng> will never to so, it is always safe to run -it on such binaries. - -Alternatively, XATTR_PAX requires a filesystem support Extended Attributes. Most -modern filesystems do so, but not all. Furthermore, one must be careful when +ELF binaries which do not already have a PAX_FLAGS program header. Unlike the original +tool, B<paxctl>, which could be instructed to try to add this header or convert a +GNU_STACK header, B<paxctl-ng> does not edit the ELF in any way, beyond setting the +PaX flags if and only if the PAX_FLAGS program header already exists. Some ELF binaries +break when they are edited. Since, B<paxctl-ng> will never to so, it is usually safe +to run it on such binaries. + +Alternatively, XATTR_PAX requires filesystems that support extended attributes. +Most modern filesystems do so, but not all. Furthermore, one must be careful when moving ELF objects to ensure that the target filesystem or archive supports -Extended Attributes, otherwise they are lost, unlike PT_PAX markings which +extended attributes, otherwise they are lost, unlike PT_PAX markings which are carried within the binary itself. B<paxctl-ng> is opportunistic without taking control away from the user. If both -a PT_PAX program header and an Extended Attribute field "user.pax" exist, then -both fields will be equally updated when the user modifies flags; unless the -B<-L> or B<-l> flags are given, in which case the markings are limiting to just -PT_PAX or XATTR_PAX, respectively. If only one marking is possible, then only that -marking will be updated. Under no circumstances will B<paxctl-ng> create a PT_PAX -program header as B<paxctl> does. It will only attempt to create an XATTR_PAX Extended -Attribute field if it is instructed to do so with the B<-C> or B<-c> flags, and it -will attempt to synchronize the PT_PAX and XATTR_PAX markings if given the B<-F> or -B<-f> flags. Finally, if the user wished, he can remvoe the Extended Attribute -field "user.pax" by running B<paxctl-ng> with the B<-d> flag. +a PAX_FLAGS program header and a user.pax.flags extended attribute field exist, then +both will be equally updated when the user modifies flags; unless the B<-L> or B<-l> +flags are given, in which case the markings are limiting to just PT_PAX or XATTR_PAX, +respectively. If only one marking is possible, then only that marking will be updated. +Under no circumstances will B<paxctl-ng> create a PAX_FLAGS program header as B<paxctl> +does. It will only attempt to create an extended attribute field if it is instructed +to do so with the B<-C> or B<-c> flags, and it will attempt to synchronize the PT_PAX +and XATTR_PAX markings if given the B<-F> or B<-f> flags. Note that when copying PT_PAX +to XATTR_PAX with the B<-F> flag, if the user.pax.flags extended attribute field does +not exist, B<paxctl-ng> will create it as if given either the B<-C> or B<-c> flags. +Finally, if the user wishes, he can remove the extended attribute field by running +B<paxctl-ng> with the B<-d> flag. =head1 OPTIONS @@ -86,19 +75,19 @@ eg. -Pp for PAGEEXEC, then the default setting - is used. =item B<-z> Set default setting (------) -=item B<-C> Create XATTR_PAX xattr with the most secure PaX settings +=item B<-C> Create XATTR_PAX markings with the most secure PaX settings -=item B<-c> Create XP_PAX xattr with the default PaX settings +=item B<-c> Create XATTR_PAX markings with the default PaX settings -=item B<-d> Delete XP_PAX xattr +=item B<-d> Delete XATTR_PAX field, "user.pax.flags" =item B<-F> Copy PT_PAX flags to XATTR_PAX, if possible =item B<-f> Copy XATTR_PAX flags to PT_PAX, if possible -=item B<-L> Only set PT_APX flags, if both are possible +=item B<-L> Only set PT_PAX flags, if possible -=item B<-l> Only set XATTR_PAX flags, if both are possible +=item B<-l> Only set XATTR_PAX flags, if possible =item B<-v> View the flags diff --git a/src/paxctl-ng.c b/src/paxctl-ng.c index ea6115b..6dbcf4c 100644 --- a/src/paxctl-ng.c +++ b/src/paxctl-ng.c @@ -75,21 +75,28 @@ print_help_exit(char *v) "Bug Reports : " PACKAGE_BUGREPORT "\n" "Program Name : %s\n" "Description : Get or set pax flags on an ELF object\n\n" - "Usage : %s -PpEeMmRrSsv ELF | -Zv ELF | -zv ELF\n" +#if defined(PTPAX) && defined(XTPAX) + "Usage : %s -PpEeMmRrSs|-Z|-z [-L|-l] [-v] ELF\n" +#else + "Usage : %s -PpEeMmRrSs|-Z|-z [-v] ELF\n" +#endif #ifdef XTPAX - " : %s -Cv ELF | -cv ELF | -dv ELF\n" + " : %s -C|-c|-d [-v] ELF\n" #endif #if defined(PTPAX) && defined(XTPAX) - " : %s -Fv ELF | -fv ELF\n" - " : %s -Lv ELF | -lv ELF\n" + " : %s -F|-f [-v] ELF\n" #endif - " : %s -v ELF | -h\n\n" + " : %s -v ELF\n" + " : %s [-h]\n\n" "Options : -P enable PAGEEXEC\t-p disable PAGEEXEC\n" " : -E enable EMUTRAMP\t-e disable EMUTRAMP\n" " : -M enable MPROTECT\t-m disable MPROTECT\n" " : -R enable RANDMMAP\t-r disable RANDMMAP\n" " : -S enable SEGMEXEC\t-s disable SEGMEXEC\n" " : -Z all secure settings\t-z all default settings\n" +#if defined(PTPAX) && defined(XTPAX) + " : -L set only PT_PAX flags\t-l set only XATTR_PAX flags\n" +#endif " :\n" #ifdef XTPAX " : -C create XATTR_PAX with most secure setting\n" @@ -99,8 +106,6 @@ print_help_exit(char *v) #if defined(PTPAX) && defined(XTPAX) " : -F copy PT_PAX to XATTR_PAX\n" " : -f copy XATTR_PAX to PT_PAX\n" - " : -L set only PT_PAX flags\n" - " : -l set only XATTR_PAX flags\n" #endif " :\n" " : -v view the flags, along with any accompanying operation\n" @@ -113,8 +118,8 @@ print_help_exit(char *v) #endif #if defined(PTPAX) && defined(XTPAX) basename(v), - basename(v), #endif + basename(v), basename(v) ); @@ -127,10 +132,13 @@ parse_cmd_args(int argc, char *argv[], uint16_t *pax_flags, int *verbose, int *c int *limit, int *begin, int *end) { int i, oc; - int compat, solitaire; + int setflags, solflags, limitflags, solitaire; - compat = 0; + setflags = 0; + solflags = 0; + limitflags = 0; solitaire = 0; + *pax_flags = 0; *verbose = 0; *cp_flags = 0; @@ -149,60 +157,66 @@ parse_cmd_args(int argc, char *argv[], uint16_t *pax_flags, int *verbose, int *c * #endif */ +#if defined(PTPAX) && defined(XTPAX) while((oc = getopt(argc, argv,":PpEeMmRrSsZzCcdFfLlvh")) != -1) +#elif defined(XTPAX) && !defined(PTPAX) + while((oc = getopt(argc, argv,":PpEeMmRrSsZzCcdvh")) != -1) +#else + while((oc = getopt(argc, argv,":PpEeMmRrSsZzvh")) != -1) +#endif { switch(oc) { case 'P': *pax_flags |= PF_PAGEEXEC; - compat |= 1; + setflags |= 1; break; case 'p': *pax_flags |= PF_NOPAGEEXEC; - compat |= 1; + setflags |= 1; break ; case 'E': *pax_flags |= PF_EMUTRAMP; - compat |= 1; + setflags |= 1; break; case 'e': *pax_flags |= PF_NOEMUTRAMP; - compat |= 1; + setflags |= 1; break ; case 'M': *pax_flags |= PF_MPROTECT; - compat |= 1; + setflags |= 1; break; case 'm': *pax_flags |= PF_NOMPROTECT; - compat |= 1; + setflags |= 1; break ; case 'R': *pax_flags |= PF_RANDMMAP; - compat |= 1; + setflags |= 1; break; case 'r': *pax_flags |= PF_NORANDMMAP; - compat |= 1; + setflags |= 1; break ; case 'S': *pax_flags |= PF_SEGMEXEC; - compat |= 1; + setflags |= 1; break; case 's': *pax_flags |= PF_NOSEGMEXEC; - compat |= 1; + setflags |= 1; break ; case 'Z': *pax_flags = PF_PAGEEXEC | PF_SEGMEXEC | PF_MPROTECT | PF_NOEMUTRAMP | PF_RANDMMAP ; - solitaire += 1; + solflags += 1; break ; case 'z': *pax_flags = PF_PAGEEXEC | PF_NOPAGEEXEC | PF_SEGMEXEC | PF_NOSEGMEXEC | PF_MPROTECT | PF_NOMPROTECT | PF_EMUTRAMP | PF_NOEMUTRAMP | PF_RANDMMAP | PF_NORANDMMAP ; - solitaire += 1; + solflags += 1; break; #ifdef XTPAX case 'C': @@ -217,12 +231,7 @@ parse_cmd_args(int argc, char *argv[], uint16_t *pax_flags, int *verbose, int *c solitaire += 1; *cp_flags = DELETE_XT_FLAGS; break; -#else - case 'C': - case 'c': - break; -#endif -#if defined(PTPAX) && defined(XTPAX) +#ifdef PTPAX case 'F': solitaire += 1; *cp_flags = COPY_PT_TO_XT_FLAGS; @@ -232,17 +241,14 @@ parse_cmd_args(int argc, char *argv[], uint16_t *pax_flags, int *verbose, int *c *cp_flags = COPY_XT_TO_PT_FLAGS; break; case 'L': + limitflags += 1; *limit = LIMIT_TO_PT_FLAGS; break; case 'l': + limitflags += 1; *limit = LIMIT_TO_XT_FLAGS; break; -#else - case 'F': - case 'f': - case 'L': - case 'l': - break; +#endif #endif case 'v': *verbose = 1; @@ -258,9 +264,10 @@ parse_cmd_args(int argc, char *argv[], uint16_t *pax_flags, int *verbose, int *c if( ( - (compat == 1 && solitaire == 0) || - (compat == 0 && solitaire == 1) || - (compat == 0 && solitaire == 0 && *verbose == 1) + (setflags == 1 && solflags == 0 && limitflags <= 1 && solitaire == 0) || //-PpEeMmRrSs [-L|-l] [-v] ELF + (setflags == 0 && solflags == 1 && limitflags <= 1 && solitaire == 0) || //-Z|-z [-L|-l] [-v] ELF + (setflags == 0 && solflags == 0 && limitflags == 0 && solitaire == 1) || //-C|-c|-d|-F|-f [-v] ELF + (setflags == 0 && solflags == 0 && limitflags == 0 && solitaire == 0 && *verbose == 1) // -v ELF ) && argv[optind] != NULL ) |