How to understand the memory protection scheme of IBM/370? - memory-management

I was confused when I met a problem while reading "Operating System Concepts"(7th edition) which is :
In the IBM/370, memory protection is provided through the use of keys. A key is a 4-bit quantity. Each 2K block of memory has a key (the storage key) associated with it. The CPU also has a key (the protection key) associated with it. A store operation is allowed only if both keys are equal, or if either is zero. Which of the following memory-management schemes could be used successfully with this hardware?
a. Bare machine
b. Single-user system
c. Multiprogramming with a fixed number of processes
d. Multiprogramming with a variable number of processes
e. Paging
f. Segmentation
I have some problems about that: How were such keys calculated? Why it provided another way of "either is zero" while the first way was already seemingly secure?(I mean what is "either is zero" used for and under what circumstance "either is zero" is efficient instead of matching two keys to see if they are the same.)

Disclaimer: this is not an informed answer, just an opinion
The "either is zero" seems to enable scenarios
CPU currently holds the zero protection key so it runs without restrictions in the god/root/kernel mode
memory block guarded by the zero key means that anyone can access it without any bureaucracy, it's covered by "public domain license"
Answer for "how were such keys calculated" by the Operating System would require some archaeology work. Starting point:
IBM Systems Reference Library, IBM System/360 Principles of Operation
Page 17
System Structure → Protection Features
...When the store-protection feature is installed, attempts to modify storage are monitored...
Two instructions - SET STORAGE KEY and INSERT STORAGE KEY - are provided for assigning and inspecting the code in a key. The same code may be used in many keys.
A user's right of access to storage is identified by a four-bit protection key. For references caused by the CPU, the protection key in the current PSW is used; access by channels are controlled by the protection key assigned to the associated I/O operation...
See also:
Wikipedia: IBM System/360
Wikipedia: IBM System/370

Related

How to identify rooted device?

Using the Android Management API, I would like to identify if a device has been rooted.
I found the attribute "devicePosture" and the possible values for this attribute are listed in this documentation here.
However, for me, it was not clear what these items mean.
For example:
Does the type "POTENTIALLY_COMPROMISED" mean that the device is rooted or just had its bootloader unlocked?
Does the "AT_RISK" type mean that you have a virus version of android (or something similar)?
Thank you for your help.
You can check this link , Also to answer some of your questions with regards to device posture.
The value of the security posture determines the current device state and the policies applied. Or in other terms it reflects how secure the device is
1.) “POTENTIALLY_COMPROMISED” value means that either SafetyNet's ctsProfileMatch check or basicIntegrity check fail or this device may be compromised and corporate data may be accessible to unauthorized actors. It covers both bootloader unlocked and rooted scenarios[1].
2.) "AT_RISK” value means that both SafetyNet's ctsProfileMatch check and basicIntegrity check pass but fails to meet requirements set by the policy (e.g. device's password state, etc.).
To determine whether what fails you can check the PostureDetail, SecurityRisk Value
[1] To understand what SafetyNet's ctsProfileMatch and basicIntegrity fields mean, you can check this link, which also explains what scenarios correspond to the combination of the value of the two checks.

data structure for page-aligned entries

I need to store many page-aligned entries, each entry is page-sized; basically I need to collect/bind together memory pages. The only requirement that I need to be able to check whether entry already exists upon adding by matching the machine-word-sized key. It is not possible to override the entry; if the same key is used, the existing entry must be found.
The function to add/replace the entry receives some machine-word-sized key (32/64 bits), checks if there is a page-aligned entry which contains the same key. If there is no entry, it is created via mmap, and is added with the required key. The C declaration of the entry looks like this:
struct entry {
uintptr_t key; /* machine-word-sized key */
unsigned char meta[]; /* this space may be used for storing in data structure */
};
The caller receives the key and takes the decision whether to use the existing entry or to allocate a new one. That is, the key must be looked up, and pages must be just collected to allow removal in a loop.
All I need are adding the entry and removing all entries (no specific order imposed); since I use each entry as epoll.data.ptr, I don't need even fast lookup after adding the entry. Given that each entry has some space for meta-data, I'm OK to dedicate some of this space to payload required to store the entry in the data structure.
I thought about using a hash table. I have no math or crypto background, so generating a good hash is a problem. I tried looking at several well-known hashes, but it seems that they are quite generic, i.e. intended to work with any data. However, my case seems to be very specific: there is no way user would use the table directly and conditions (page-aligned and page-sized entries plus word-sized key) are unlikely to change.
The questions are:
Am I right that hash table is OK for this case? If yes, what kind of hash would you suggest? If the hash table is linked-list based, it'd better be intrusive (i.e. all required meta is better to be inside the entry, not outside, like Linux kernel's struct list_head).
I was also looking at page tables, like described at https://wiki.osdev.org/Paging. However, it concentrates mostly on how MMU does its job, and I'm not sure whether I can adopt it to purely software implementation and how can I apply these concepts. Since machine-word-sized key must be used for inserting the entry, the concepts from this link only show how to organize pages effectively for page-to-page mappings.
I currently need to care only of 4096-bytes pages, but generic case is better (i.e. some algorithm which operates on PAGE_SIZE, be it 4K, 8K or whatever). It would be also nice the data structure does not assume page-sized (though page-aligned is a strict requirement, since all memory is obtained via mmap).

UNIX system call to unset the reference bit of a specific page in page table?

I'm trying to count hits of a specific set of pages, by hacking the reference bits in the page table. Is there any system call or any other way to unset reference bits (in UNIX-like systems)?
A page table is the data structure used by a virtual memory system in a computer operating system to store the mapping between virtual addresses and physical addresses. (https://en.wikipedia.org/wiki/Page_table)
In unix-like systems there is a bit associated with each page table entry, called "reference" bit, which indicates if a page was accessed since the bit was unset.
The linux kernel unsets these reference bits periodically and checks a while after that to know what pages have been accessed, in order to detect "hot" pages. But this information is very coarse grain and low-precision since it doesn't say anything about the number of accesses and their time.
I want to count accesses to specific pages during shorter epochs by unsetting reference bits then check if the pages have been accessed after a short time.
Therefore, I was wondering if there is any system call or CPU interrupt which provides means to unset "reference bits". Otherwise, I need to dive deep into kernel to see what goes on down there.
There is no API for resetting the page reference bits. Page management is a very twitchy aspect of kernel tuning and no one wants to upset it. Of course you could modify the kernel to your needs.
Instead, you might look into Valgrind which is a debugging and profiling tool for running a single program. Ordinarily it detects subtle memory errors such as detecting use of a dynamic memory block after it has been freed.
If you need page management information for the system as a whole, I think the most expedient solution is hacking the kernel.

How to protect a random number seed?

I'm writing an application to protect passwords from key sniffers and screen retrievers. I have the user type in an easy-to-remember keyword or phrase (i.e, "password123", "amazon.com", "gmail") and I use that string to create a longer and stronger password which is loaded into the clipboard. I want the application to be completely anonymous, so I don't save any information. To generate the passwords, I use a random number generator. I need a way for the user to carry around their seed that isn't vulnerable to key sniffers or screen retrievers. I'm thinking a hardware token like a YubiKey, but I would like something more easier and more mainstream. I tried using behavioral biometrics, but I managed to replicate them with a program too easily. Any better ideas?
What you are suggesting is a more than vulnerable approach.
First of all, there are open source and proven-correct algorithms and applications for the problem you are targeting. In security questions it is never a good idea to go and develop applications for critical operations (and handling passwords is always a critical operation) on your own, especially reinventing the wheel is almost in every case an endeavor doomed to fail.
Your approach is problematic in several points:
To be anonymous the app needs to copy/paste or in-place-generate the password needed for some action. You will have a hard time avoiding screen retrievers capture that if you do not do some magic on OS level.
Using one(!) random seed to protect several passwords makes each of them weaker than it was before.
Carrying this random seed on a usb key and freely plugging it into all kinds of computers that you cannot control is a problem as each of them may be potentially malicious. The random seed could be silently retrieved, altered or deleted.
To give you some things to get paranoid about, google e.g. blue pill and you will see that the real problems dwell on another machine layer than the application you are talking about.
Instead have a look at the following approaches:
2 factor authentication (2FA) against malicious software and hardware stealing your passwords on type-in. See e.g. Google Authenticator.
Secure operating systems against such software entering your system and retrieving your passwords. See e.g. QubesOS
Read-only drives with secure / anonymous OS for usage on foreign and potentially dangerous machines even for very critical tasks such as banking. See e.g. Tails OS on a dvd (not a usb key!)
Virtual machines to capsule potentially malicious tasks. See e.g. VirtualBox
Trustable password safes like KeyPassX
In a nutshell: You can write such an application but it will most likely not be practical nor secure nor by so usable. Sorry about that.

Global mapping of one subscript dimension to another database

I have a vendor defined database (about 140GB total) on Caché 2007. It uses the old style MUMPS programming environment and accesses globals directly in a hierarchical style. There is one global that accounts for about 75% of the total database size. The first subscript in this table is an artificial integer account number. The next 2-3 subscripts are constant subrecord identifiers that break up blocks of fields and denote repeating sub record kinds.
One of these repeating subrecords (record type 30) is for notes on an account. Because of the way the system is used, this dimension accounts for a very large portion of the global's total space; I'd estimate it to be at least 50%. Because of the way Caché stores data physically in the database, a scan of this global ends up loading all or most of these notes as a side effect even though they aren't relevant to most operations. It has the effect of greatly increasing the cost of IO operations on the global, especially when you only want one tiny detail from a bunch of accounts.
Example subscript references for this global:
^ACCT(3461,10,1)="SOME^DATA"
^ACCT(3461,10,2)="MORE^DATA"
...
^ACCT(3461,30,1)="NOTE1 blah blah"
^ACCT(3461,30,2)="NOTE2 blah blah"
...
^ACCT(3461,30,100)="NOTE100 blah blah"
I can't change the design of the database. It's controlled by an outside vendor and there is a large amount of MUMPS style hardcoded references in the database. I'm thinking that a big reason that batch operations are so slow on the system are due to the high cost of these mostly irrelevant notes coming along for the IO ride whenever account data is accessed. Scanning this whole global (i.e. when there is no useful application maintained index) takes at least 8 hours.
One thought I had is to shift the note data from being stored along side other details in the global to a separate database file by using the global mapping facility described in the Guide to Using Caché Globals and Guide to System Administration. If I could map all the subscript 30s to a separate database file in the same Caché database, most data operations (the ones that don't even care about notes) wouldn't be bringing those in to memory along with the details they do care about.
In the global structure guide (1st link), this looks plausible as they show a particular 2nd subscript mapping separately than the 1st subscript. What they don't show in any of the examples is what the syntax is to make that happen. In the "Add a new global mapping" screen in the Caché Management Portal, I should be able to do something like
Global name: ACCT
Subscripts to be mapped: (BEGIN:END)(30)
But whatever variations I try in the syntax, I always get ERROR #657: Invalid subscript in reference 1 subscript #1.
StackExchange note: This question would possibly be better suited to dba.stackexchange.com but there are apparently zero Intersystems questions there and I don't think it would get any attention.
Unfortunately, while it's possible to map 2nd level subscripts of a particular node, it's not possible to map 2nd level subscripts of all nodes.
There is an experienced Performance team on WRC, did you try to contact them?

Resources