Operating Systems 2021F Lecture 12

From Soma-notes

Video

Video from the lecture given on October 21, 2021 is now available:

Video is also available through Brightspace (Resources->Class zoom meetings->Cloud Recordings tab)

Notes

Lecture 12
----------
 - midterm interviews will be after the break, will post schedule
   for sign-ups
     - either volunteer or sign up when asked
 - if you did badly, don't worry
     - final exam can replace midterm grade (it is cumulative)
 - solutions will be posted once the midterm is graded (by the end of break, so by the end of the month)

 - interview is a ~10 minute meeting
   - we go through your answers, discussing questions where
     you missed points or had a really good answer
   - really, it is a review to make sure it was properly graded
   - only time there would be an issue is if it became clear
     what you know != what is in your answers
   - about half the time I increase grades (I don't decrease them
     if grading was too lenient)
   - if you want to appeal your grade on the midterm, do an interview
     (because the process is the same)
 - if you have concerns about any assignment grading, just message or email me, I will investigate
 
Tutorial 5
 - draft is posted now
 - will be adding eBPF-based content (need to add some opensnoop-based questions, maybe others)

Tutorial 5 is all about how the login process works
 - when you log in, what happens?
 - LOTS is happening, we won't cover it all
   - but you should get a mental model that lets you figure out
     details as you need to

grep is the command line search program
  - searches through specified files
  - can you regular expressions, but can treat is just as searching for plain text

What mental model should you have of what happens when you log in?
 - there's a program waiting for logins (sshd, logind, or something else)
 - when you connect to it, it creates a child to handle the new session
    - parent goes back to waiting for new login attempts
    - (parent is normally a daemon of some kind)
 - daemon child gets user input, decides whether access is granted or not
 - if access is granted, it changes its privileges to be that
   of the requested user and then starts that user's session
     - by execve'ing bash at some point, telling it to start a new session

Users & groups in UNIX
 - associated with every file is a user and a group
    - actually a uid and a gid, they are numbers
 - associated with every process is a uid and potentially multiple gid's.
    - but only one active gid

Permissions in UNIX are (traditionally) all about looking at uid's and gid's and deciding what is allowed based on that.

Root's uid is 0
 - kernel normally treats uid 0 as maximally privileged, i.e., if a process with uid 0 asks to do something, the kernel says YES
    - unless it is just impossible to do
    - (there are more advanced security mechanisms that limit root's privileges, but that is for much later in this class, if we have time)

To the kernel, there are no "users"
 - there are just processes and files with uid and gid labels
 - kernel doesn't have any concept of usernames

A key idea in UNIX is that kernel implements mechanism, not policy
 - defers policy to userspace
 - allows kernel to be flexible

Key questions
 - where are uid's and gid's stored for files?
 - where is the association between uid's and usernames
   (and gid's and group names) stored/maintained?

In networked UNIX systems (i.e., ones where people can log into many systems as if they were one system), there can be complex ways to store username/group info
  - LDAP
  - kerberos/hesiod (and even MS Acive Directory)
  - yp/nis
(These are WAY outside the scope of this class, and
are actually increasingly irrelevant.)


But all of these systems are extensions to the classic UNIX mechanisms of user and group info files:
  /etc/passwd
  /etc/group

(and /etc/shadow and /etc/gshadow)

In your home directory, dot files configure your environment
 - hidden by default by ls because there can be a lot of them

A user has access to all of the files in their directory
 - they can change them at will, and thus change their environment

Remember dot files are normally text files
 - so you edit them like any text file!

Passwords need to be stored, but not exactly
 - don't want people to just read the password file and know their password
 - instead, store passwords "hashed", one way function that can be used
   to verify the password

To see how traditional UNIX systems stored passwords, run
  "shadowconfig off" as root
  - disables shadow passwords

The passwd file needs to be world readable
 - so everyone can see what the uid<->username mapping is,
   and so they can run finger

But keeping password hashes accessible is a security risk
 - if I know your password hash, I can keep guessing
   until I figure it out
 - guessing passwords and testing password hashes is "password cracking"
   
So, how do we only allow privileged users to get password hashes?
 - move password hashes to /etc/shadow
 - do same for group passwords to /etc/gshadow

For every file, three groups of permissions are stored
  user
  group
  other

For each of these, we have three basic permissions
  read
  write
  execute

so 3 bits for three fields: 9 bits
 (there's a 4th bit for each, will discuss it later)

When you do ls -l, the first field tells the kind of file
 "-"  regular file
 "d"  directory
 "c"  character device
 "b"  block device
 "l"  symbolic link
 "p"  named pipe

We'll explain each of these later, for now just focus on files and directories.

The kernel is thus looking at each file's permission bits and uid/gid
whenever an open system call is made
 - it decides whether the process making the open has the right privileges
 - note it doesn't look at password hashes or anything like that,
   that is taken care of in userspace

man chmod will tell you some about permission bits

But how do we get the first user's process?
 - the login process must create a child that "becomes" the user
    - the setuid, setgid system calls allow a process to change
      their user ID
    - of course these system calls are privileged

This all works if a privileged process wants to become unprivileged.  But, what if I want to do a privileged operation as a regular user?
 - "setuid": when you have owner execute and the setuid bit set,
   when you do an execve of the file, the process will run
   with the permissions of the file owner (and not of the uid
   of the process that did the execve)
 - "setuid root" - executable is owned by root and has the setuid bit set

setuid executables, especially setuid root ones, are dangerous
 - can allow regular users to do things as root
 - if they aren't programmed well, vulnerablities
   can then allow unprivileged users to become root

So, then, how does sudo work?
 - it checks if the user is in the "sudo" group
 - if the user is, and they type in their password,
   run what they ask for as root (which it can, because
   sudo is setuid root)
(Complexity of sudo comes from being able to define rules
 on what commands can be run)

When you login, nothing special really is happening
  - it is just a privileged process getting a request,
    deciding whether it is allowed,
    and then creating a child to handle the request
  - only tricky bit is the child has to change its uid, gid
    in order to be the limited requested user, not root
    - if you don't drop privileges, you're letting
      regular users become root