Explanation of st_flags bits - objective-c

I'm writing a python script to delete files on MacOS, and I run into SIP protected files. I know the presence of st_flags more than likely mean I can't delete the file. Like here:
>>> os.stat(f).st_flags
524288
But I'm curious to know what that actually means. I looked in stat.h and see:
/*
* Definitions of flags stored in file flags word.
*
* Super-user and owner changeable flags.
*/
#define UF_SETTABLE 0x0000ffff /* mask of owner changeable flags */
#define UF_NODUMP 0x00000001 /* do not dump file */
#define UF_IMMUTABLE 0x00000002 /* file may not be changed */
#define UF_APPEND 0x00000004 /* writes to file may only append */
#define UF_OPAQUE 0x00000008 /* directory is opaque wrt. union */
/*
* The following bit is reserved for FreeBSD. It is not implemented
* in Mac OS X.
*/
/* #define UF_NOUNLINK 0x00000010 */ /* file may not be removed or renamed */
#define UF_COMPRESSED 0x00000020 /* file is compressed (some file-systems) */
/* UF_TRACKED is used for dealing with document IDs. We no longer issue
* notifications for deletes or renames for files which have UF_TRACKED set. */
#define UF_TRACKED 0x00000040
#define UF_DATAVAULT 0x00000080 /* entitlement required for reading */
/* and writing */
/* Bits 0x0100 through 0x4000 are currently undefined. */
#define UF_HIDDEN 0x00008000 /* hint that this item should not be */
/* displayed in a GUI */
/*
* Super-user changeable flags.
*/
#define SF_SUPPORTED 0x001f0000 /* mask of superuser supported flags */
#define SF_SETTABLE 0xffff0000 /* mask of superuser changeable flags */
#define SF_ARCHIVED 0x00010000 /* file is archived */
#define SF_IMMUTABLE 0x00020000 /* file may not be changed */
#define SF_APPEND 0x00040000 /* writes to file may only append */
#define SF_RESTRICTED 0x00080000 /* entitlement required for writing */
#define SF_NOUNLINK 0x00100000 /* Item may not be removed, renamed or mounted on */
I just dont quite see how it adds up to 524288. I mean I kinda get it, like permission bits, 1 or more in the 6th position from the right should mean SF_NOUNLINK is set, but where is the 5 coming from? 2 in the 5th position from the right means SF_IMMUTABLE is set, and 2nd position is 8, which is UF_DATAVAULT, which makes sense. The other values in positions 3-4, and the value of 5 (from right) I dont understand. Any pointers as how to read this?

Related

Mono 5 on Solaris Build issues

I am trying to build Mono on Solaris 10 and have ran into an issue with error "Posix system lacks support for recursive mutexes". I am trying to build this with gcc 3.4.3 and I have installed gmake, gar, granlib, and gstrip to replace their Solaris alternatives. I have found a possible solution, but I can not locate the blog that references this line "1) patch /usr/lib/pkgconfig/gthread-2.0.pc to replace the -mt option (see Jonel's blog)" located at https://lists.dot.net/pipermail/mono-list/2007-January/034101.html. The blog is no longer active. Does anyone have any ideas what the patch they are referring to may be? Thanks in advance.
Solaris 10 does support recursive mutexes.
Per the Solaris 10 pthread_mutexattr_settype man page:
PTHREAD_MUTEX_RECURSIVE
A thread attempting to relock this mutex without first unlocking it
will succeed in locking the mutex. The relocking deadlock that can
occur with mutexes of type PTHREAD_MUTEX_NORMAL cannot occur with
this type of mutex. Multiple locks of this mutex require the same
number of unlocks to release the mutex before another thread can
acquire the mutex. A thread attempting to unlock a mutex that another
thread has locked will return with an error. A thread attempting to
unlock an unlocked mutex will return with an error. This type of mutex
is only supported for mutexes whose process shared attribute is
PTHREAD_PROCESS_PRIVATE.
Also per the man page, the required compile/link options, and the proper #include statement:
cc –mt [ flag... ] file... –lpthread [ library... ]
#include <pthread.h>
Note the addition of -lpthread. I suspect the blog you're referring to said to replace -mt with -mt -lpthread.
(A bit more research into this problem, prodded by the Unix question How to install .net Mono on Solaris 11 (source code compile)? produced this answer, which I'm repeating here.)
The exact value that you set _XOPEN_SOURCE to doesn't matter. Mono is incorrectly defining the _XOPEN_SOURCE_EXTENDED macro:
case "${host}" in
*solaris* )
AC_MSG_CHECKING(for Solaris XPG4 support)
if test -f /usr/lib/libxnet.so; then
CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600"
CPPFLAGS="$CPPFLAGS -D__EXTENSIONS__"
CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED=1" <-- WRONG
LIBS="$LIBS -lxnet"
The _XOPEN_SOURCE_EXTENDED macro does not exist in either the POSIX 6 or the POSIX 7 standard.
Even Linux agrees that _XOPEN_SOURCE_EXTENDED should not be defined here. Per the Linux feature_test_macros man page:
_XOPEN_SOURCE_EXTENDED
If this macro is defined, and _XOPEN_SOURCE is defined, then expose definitions corresponding to the XPG4v2 (SUSv1) UNIX extensions (UNIX 95). Defining _XOPEN_SOURCE with a value of 500 or more also produces the same effect as defining _XOPEN_SOURCE_EXTENDED. Use of _XOPEN_SOURCE_EXTENDED in new source code should be avoided.
Since defining _XOPEN_SOURCE with a value of 500 or more has the same effect as defining _XOPEN_SOURCE_EXTENDED, the latter (obsolete) feature test macro is generally not described in the SYNOPSIS in man pages.
Note the precise wording:
If this macro (_XOPEN_SOURCE_EXTENDED) is defined, and _XOPEN_SOURCE is defined, then expose definitions corresponding to the XPG4v2 (SUSv1) UNIX extensions (UNIX 95). ...
Defining _XOPEN_SOURCE to any value while also defining _XOPEN_SOURCE_EXTENDED results in XPG4v2, and that's NOT the XPG6 necessary to get recursive mutexes.
You're likely running into this check in the Solaris 11 /usr/include/sys/feature_tests.h:
/*
* It is invalid to compile an XPG3, XPG4, XPG4v2, or XPG5 application
* using c99. The same is true for POSIX.1-1990, POSIX.2-1992, POSIX.1b,
* and POSIX.1c applications. Likewise, it is invalid to compile an XPG6
* or a POSIX.1-2001 application with anything other than a c99 or later
* compiler. Therefore, we force an error in both cases.
*/
#if defined(_STDC_C99) && (defined(__XOPEN_OR_POSIX) && !defined(_XPG6))
#error "Compiler or options invalid for pre-UNIX 03 X/Open applications \
and pre-2001 POSIX applications"
#elif !defined(_STDC_C99) && \
(defined(__XOPEN_OR_POSIX) && defined(_XPG6))
#error "Compiler or options invalid; UNIX 03 and POSIX.1-2001 applications \
require the use of c99"
#endif
_XPG6 gets defined earlier in the file, in this block:
/*
* Use of _XOPEN_SOURCE
*
* The following X/Open specifications are supported:
*
* X/Open Portability Guide, Issue 3 (XPG3)
* X/Open CAE Specification, Issue 4 (XPG4)
* X/Open CAE Specification, Issue 4, Version 2 (XPG4v2)
* X/Open CAE Specification, Issue 5 (XPG5)
* Open Group Technical Standard, Issue 6 (XPG6), also referred to as
* IEEE Std. 1003.1-2001 and ISO/IEC 9945:2002.
*
* XPG4v2 is also referred to as UNIX 95 (SUS or SUSv1).
* XPG5 is also referred to as UNIX 98 or the Single Unix Specification,
* Version 2 (SUSv2)
* XPG6 is the result of a merge of the X/Open and POSIX specifications
* and as such is also referred to as IEEE Std. 1003.1-2001 in
* addition to UNIX 03 and SUSv3.
*
* When writing a conforming X/Open application, as per the specification
* requirements, the appropriate feature test macros must be defined at
* compile time. These are as follows. For more info, see standards(5).
*
* Feature Test Macro Specification
* ------------------------------------------------ -------------
* _XOPEN_SOURCE XPG3
* _XOPEN_SOURCE && _XOPEN_VERSION = 4 XPG4
* _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED = 1 XPG4v2
* _XOPEN_SOURCE = 500 XPG5
* _XOPEN_SOURCE = 600 (or POSIX_C_SOURCE=200112L) XPG6
*
* In order to simplify the guards within the headers, the following
* implementation private test macros have been created. Applications
* must NOT use these private test macros as unexpected results will
* occur.
*
* Note that in general, the use of these private macros is cumulative.
* For example, the use of _XPG3 with no other restrictions on the X/Open
* namespace will make the symbols visible for XPG3 through XPG6
* compilation environments. The use of _XPG4_2 with no other X/Open
* namespace restrictions indicates that the symbols were introduced in
* XPG4v2 and are therefore visible for XPG4v2 through XPG6 compilation
* environments, but not for XPG3 or XPG4 compilation environments.
*
* _XPG3 X/Open Portability Guide, Issue 3 (XPG3)
* _XPG4 X/Open CAE Specification, Issue 4 (XPG4)
* _XPG4_2 X/Open CAE Specification, Issue 4, Version 2 (XPG4v2/UNIX 95/SUS)
* _XPG5 X/Open CAE Specification, Issue 5 (XPG5/UNIX 98/SUSv2)
* _XPG6 Open Group Technical Standard, Issue 6 (XPG6/UNIX 03/SUSv3)
*/
/* X/Open Portability Guide, Issue 3 */
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE - 0 < 500) && \
(_XOPEN_VERSION - 0 < 4) && !defined(_XOPEN_SOURCE_EXTENDED)
#define _XPG3
/* X/Open CAE Specification, Issue 4 */
#elif (defined(_XOPEN_SOURCE) && _XOPEN_VERSION - 0 == 4)
#define _XPG4
#define _XPG3
/* X/Open CAE Specification, Issue 4, Version 2 */
#elif (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE_EXTENDED - 0 == 1)
#define _XPG4_2
#define _XPG4
#define _XPG3
/* X/Open CAE Specification, Issue 5 */
#elif (_XOPEN_SOURCE - 0 == 500)
#define _XPG5
#define _XPG4_2
#define _XPG4
#define _XPG3
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 199506L
/* Open Group Technical Standard , Issue 6 */
#elif (_XOPEN_SOURCE - 0 == 600) || (_POSIX_C_SOURCE - 0 == 200112L)
#define _XPG6
#define _XPG5
#define _XPG4_2
#define _XPG4
#define _XPG3
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#undef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#endif

assertion from valgrind mc_main.c

My valgrind runs reports errors like this
Memcheck: mc_main.c:8292 (mc_pre_clo_init): Assertion 'MAX_PRIMARY_ADDRESS == 0x1FFFFFFFFFULL' failed.
What does this mean? Is it a valgrind internal error or an error from my program?
This is a valgrind internal error. This is very weird, as this failed
assertion is a self check done very early on.
You should file a bug on valgrind bugzilla, reporting all the needed
details (version, platform, ...)
From the Valgrind source code (from git HEAD)
/* Only change this. N_PRIMARY_MAP *must* be a power of 2. */
#if VG_WORDSIZE == 4
/* cover the entire address space */
# define N_PRIMARY_BITS 16
#else
/* Just handle the first 128G fast and the rest via auxiliary
primaries. If you change this, Memcheck will assert at startup.
See the definition of UNALIGNED_OR_HIGH for extensive comments. */
# define N_PRIMARY_BITS 21
#endif
/* Do not change this. */
#define N_PRIMARY_MAP ( ((UWord)1) << N_PRIMARY_BITS)
/* Do not change this. */
#define MAX_PRIMARY_ADDRESS (Addr)((((Addr)65536) * N_PRIMARY_MAP)-1)
...
tl_assert(MAX_PRIMARY_ADDRESS == 0x1FFFFFFFFFULL);
So it looks like something has been changed that shouldn't have been.

relocation section header information in .elf file

My apology for my poor English, really having a hard time understanding what is the sh_info field contains for relocation section, following is what I get from the ELF document:
It says
sh_info : contains the section header index of the section to which the relocation applies
sh_link: contains the section header index of the associated symbol table.
Clearly: sh_info is not about the symbol table section that the relocation section relates to, whose information is stored in sh_link.
Based on my understanding: when relocating a symbol, three sections are related: the relocation section, the symbol table section, and the section which contains symbols' definition for symbols in the symbol table.
Assumption 1: So I assume sh_info is about the third section mentioned ahead
-----However, when I go through the sample code for relocation, my assumption seems not match
static int elf_do_reloc(Elf32_Ehdr *hdr, Elf32_Rel *rel, Elf32_Shdr *reltab) {
Elf32_Shdr *target = elf_section(hdr, reltab->sh_info);
int addr = (int)hdr + target->sh_offset;
int *ref = (int *)(addr + rel->r_offset);
// Symbol value
int symval = 0;
if(ELF32_R_SYM(rel->r_info) != SHN_UNDEF) {
symval = elf_get_symval(hdr, reltab->sh_link, ELF32_R_SYM(rel->r_info));
if(symval == ELF_RELOC_ERR) return ELF_RELOC_ERR;
}
-----Sicce r_info is a field only entry in relocation section contains
which means sh_info is the index of the relocation section itself. < Assumption 2
What confuses me more is the an example someone else posts, reading elf file example
it seems the sh_info field information is nothing related to my previous 2 assumptions
Could anyone please help explain what does sh_info really contains?
About the "confusing example", maybe relocation part got deleted but only mention of sh_info is related to parsing of (dynamic) symbols name and (as show in image in your question) that field has different meaning for SHT_SYMTAB and SHT_DYNSYM (number of items in section + 1).
Section #0A OFF: 0x000015F8
Name: .rela.plt (0x00000084)
Type: SHT_RELA (0x00000004)
Flags: -a-
Addr: 0x004003E8
Offset: 0x000003E8
Size: 0x00000090
Link: 0x00000005
Info 0x0000000C
Section #05 OFF: 0x000014B8
Name: .dynsym (0x0000004E)
Type: SHT_DYNSYM (0x0000000B)
Flags: -a-
Addr: 0x00400280
Offset: 0x00000280
Size: 0x000000A8
Link: 0x00000006
Info 0x00000001
Section #0C OFF: 0x00001678
Name: .plt (0x00000089)
Type: SHT_PROGBITS (0x00000001)
Flags: -ax
Addr: 0x004004A0
Offset: 0x000004A0
Size: 0x00000070
Link: 0x00000000
Info 0x00000000
You can see that sh_link points to .dynsym section and sh_info points to .plt section (which contains executable memory).
So sh_link is symbol table and sh_info is executable section that gets modified.
Basically your document says it all already, but here are some more references.
Chapter on Sections [Figure 4-12: sh_link and sh_info Interpretation]:
sh_link - The section header index of the associated symbol table.
sh_info - The section header index of the section to which the relocation applies.
Also there's a chapter on relocation:
A relocation section references two other sections: a symbol table and a section to modify. The section header's sh_info and sh_link members, described in ``Sections'' above, specify these relationships. Relocation entries for different object files have slightly different interpretations for the r_offset member.
In relocatable files, r_offset holds a section offset. The relocation section itself describes how to modify another section in the file; relocation offsets designate a storage unit within the second section.
In executable and shared object files, r_offset holds a virtual address. To make these files' relocation entries more useful for the dynamic linker, the section offset (file interpretation) gives way to a virtual address (memory interpretation).
And just for fun... Here are (search page) relocation types for x86 on Linux:
#define R_X86_64_NONE 0 /* No reloc */
#define R_X86_64_64 1 /* Direct 64 bit */
#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
#define R_X86_64_PLT32 4 /* 32 bit PLT address */
#define R_X86_64_COPY 5 /* Copy symbol at runtime */
#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
#define R_X86_64_RELATIVE 8 /* Adjust by program base */
#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative
offset to GOT */
#define R_X86_64_32 10 /* Direct 32 bit zero extended */
#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
#define R_X86_64_16 12 /* Direct 16 bit zero extended */
#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
#define R_X86_64_8 14 /* Direct 8 bit sign extended */
#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */

Sending signals from DCL command line on OpenVMS

I'm trying to send a signal via the command line on an OpenVMS server. Using Perl I have set up signal handlers between processes and Perl on VMS is able to send Posix signals. In addition, C++ programs are able to send and handle signals too. However, the problem I run into is that the processes could be running on another node in the cluster and I need to write a utility script to remotely send a signal to them.
I'm trying to avoid writing a new script and would rather simply execute a command remotely to send the signal from the command line. I need to send SIGUSR1, which translates to C$_SIGUSR1 for OpenVMS.
Thanks.
As far as I know, there is no supported command line interface to do this. But you can accomplish the task by calling an undocumented system service called SYS$SIGPRC(). This system service can deliver any condition value to the target process, not just POSIX signals. Here's the interface described in standard format:
FORMAT
SYS$SIGPRC process-id ,[process-name] ,condition-code
RETURNS
OpenVMS usage: cond_value
type: longword (unsigned)
access: write only
mechanism: by value
ARGUMENTS
process-id
OpenVMS usage: process_id
type: longword (unsigned)
access: modify
mechanism: by reference
Process identifier of the process for which is to receive the signal. The
process-id argument is the address of an unsigned longword containing the
process identifier. If you do not specify process-id, process-name is
used.
The process-id is updated to contain the process identifier actually
used, which may be different from what you originally requested if you
specified process-name.
process-name
OpenVMS usage: process_name
type: character string
access: read only
mechanism: by descriptor
A 1 to 15 character string specifying the name of the process for
which will receive the signal. The process-name argument is the
address of a descriptor pointing to the process name string. The name
must correspond exactly to the name of the process that is to receive
the signal; SYS$SIGPRC does not allow trailing blanks or abbreviations.
If you do not specify process-name, process-id is used. If you specify
neither process-name nor process-id, the caller's process is used.
Also, if you do not specify process-name and you specify zero for
process-id, the caller's process is used.
condition-value
OpenVMS usage: cond_value
type: longword (unsigned)
access: read only
mechanism: by value
OpenVMS 32-bit condition value. The condition-value argument is
an unsigned longword that contains the condition value delivered
to the process as a signal.
CONDITION VALUES RETURNED
SS$_NORMAL The service completed successfully
SS$_NONEXPR Specified process does not exist
SS$_NOPRIV The process does not have the privilege to signal
the specified process
SS$_IVLOGNAM The process name string has a length of 0 or has
more than 15 characters
(plus I suspect there are other possible returns having to do
with various cluster communications issues)
EXAMPLE CODE
#include <stdio.h>
#include <stdlib.h>
#include <ssdef.h>
#include <stsdef.h>
#include <descrip.h>
#include <errnodef.h>
#include <lib$routines.h>
int main (int argc, char *argv[]) {
/*
**
** To build:
**
** $ cc sigusr1
** $ link sigusr1
**
** Run example:
**
** $ sigusr1 := $dev:[dir]sigusr1.exe
** $ sigusr1 20206E53
**
*/
static unsigned int pid;
static unsigned int r0_status;
extern unsigned int sys$sigprc (unsigned int *,
struct dsc$descriptor_s *,
int);
if (argc < 2) {
(void)fprintf (stderr, "Usage: %s PID\n",
argv[0]);
exit (EXIT_SUCCESS);
}
sscanf (argv[1], "%x", &pid);
r0_status = sys$sigprc (&pid, 0, C$_SIGUSR1);
if (!$VMS_STATUS_SUCCESS (r0_status)) {
(void)lib$signal (r0_status);
}
}

Increasing number of BPF devices on AIX

Anyone know how to increase the number of BPF devices in AIX 5.2/5.3 above the supposed system default of four? i.e. running more than four tcpdump processes concurrently?
The answer I think is "IMPOSSIBLE".
The reason is to read the header file /usr/include/net/bpf.h:
(mine is AIX 5.2)
Then u come across:
#define NBPFILTER 4
/* Flags to set the appropriate minor device */
#define BPF0 0x1 /* /dev/bpf0 */
#define BPF1 0x2 /* /dev/bpf1 */
#define BPF2 0x4 /* /dev/bpf2 */
#define BPF3 0x8 /* /dev/bpf3 */
So the number "4" is in fact hardcoded into the source code, and each of the above bpfX is all preprogrammed up to 4.