[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sudo make install

From: Bob Proulx
Subject: Re: sudo make install
Date: Sun, 19 Apr 2015 18:31:53 -0600
User-agent: Mutt/1.5.23 (2014-03-12)

Michael Heerdegen wrote:
> I think I got it right - but got confused by the octal notation of the
> umask and the optional leading zero.  I didn't find any explanation of
> how the umask is interpreted for different numbers of digits.  I tried
> "umask 0002", and saw from the umask -S output that it was what I
> wanted.

Okay.  Let me quickly run through an octal file permission review.  Or
maybe not so quickly.  This turned into a very long email with a lot
of details.

The traditional Unix file permissions are a collection of bits.  Each
bit is given a specific meaning.  These are represented in octal since
at the time octal was the convenient form for representing a
collection of bits.  There were 36-bit word machines for example.
Ten years later or so I think hex would be more likely used over
octal.  Today the standard is to use symbolic modes.  Those are
more portable across operating systems.  (Think Cygwin for example.)

The leading zero means an octal value follows.  02 is bits 1, and 0 or
binary 0010.  The umask 07 means binary 0111.

File permissions are listed mostly in the same order as they are
displayed by 'ls -l'.

For example "drwxr-xr-x" decodes as:
  user readable
  user writable
  user searchable (the execute bit means search for directories)
  group readable
  group searchable
  group not writable
  other readable
  other searchable
  other not writable

Some bits are overloaded.  The setuid and setgid bits are overloaded
on top of the 'x' bits.  The sticky bit ('t') is overloaded on the
other 'x' bit.

We have been talking about /usr/local drwxrwsr-x:
  user readable, writable, searchable
  group readable, writable, searchable
  set-group-id is set (s is on x bit)
  other readable, searchable, not writable

For a sticky bit example /tmp drwxrwxrwt:
  user readable, writable, searchable
  group readable, writable, searchable
  other readable, writable, searchable
  sticky bit is set (t is on x bit)

The collection of bits puts the three setuid, setguid, sticky bits
just ahead of the rest of the permissions.  These two commands are
exactly the same.

  chmod 02775 someshareddir
  chmod u=rwx,g+rwxs,o+rx someshareddir

The 02775 is the bits 010 111 111 101.  Or broken out individually:

  0 setuid
  1 setgid
  0 sticky

  1 read user
  1 write user
  1 execute (search) user

  1 read group
  1 write group
  1 execute (search) group

  1 read other
  0 write other
  1 execute (search) other

Umask is similar.  A umask of 022, typical of System V configurations
where all users are in a 'users' group, is this:

 0 read group
 1 write group
 0 execute (search) group

 0 read other
 1 write other
 0 execute (search) other

The umask is a mask.  Bits that are set there mask out other bits.
The zeros do nothing.  The ones mask out that bit.  Therefore a umask
of 022 masks out group write and other write.

  address@hidden:/tmp/junk$ umask 022
  address@hidden:/tmp/junk$ date > date022
  address@hidden:/tmp/junk$ ls -l date022
  -rw-r--r-- 1 rwp photos 29 Apr 18 13:10 date022

A umask of 02, typical of modern User-Private-Group systems, is this:

 0 read other
 1 write other
 0 execute (search) other

A umask of 02 only masks out the other write bit.

  address@hidden:/tmp/junk$ umask 02
  address@hidden:/tmp/junk$ date > date02
  address@hidden:/tmp/junk$ ls -l date02
  -rw-rw-r-- 1 rwp photos 29 Apr 18 13:10 date02

> I didn't find any explanation of how the umask is interpreted for
> different numbers of digits.  I tried "umask 0002", and saw from the
> umask -S output that it was what I wanted.

The extra zeros traditionally did nothing since after having a leading
zero to indicate that the number was octal the extra zeros were simply
zero and did nothing.  2 interpreted as decimal, 02 octal, 0x2 hex,
or 0000002 octal are all two.  Same as 0x02 or 0x00002.  The leading
zero indicates octal and for numbers less than seven are the same as
if there wasn't a leading zero.  But 08 would mean an octal 8.  That
is an invalid base for that number.

  address@hidden:~$ umask 08
  bash: umask: 08: octal number out of range

Same thing for 09.  Can't be octal since octal can only be 0-7.

> I tried "umask 0002", and saw from the umask -S output that it was
> what I wanted.

Very clever!  Yes.  The umask -S option will print out the result
using symbolic modes.

  address@hidden:~$ umask 02
  address@hidden:~$ umask -S

Sure I have used the octal modes forever.  Sure I could keep using
them.  But I believe the symbolic modes are easier to use.  Therefore
I advocate for the symbolic modes over the octal modes.  Also when
using setgid bits the symbolic modes work intuitively while the octal
modes do not with GNU coreutils chmod.

  address@hidden:/tmp$ ll -d junk
  drwxrwsr-x 2 rwp photos 4096 Apr 18 13:10 junk
  address@hidden:/tmp$ chmod 0775 junk
  address@hidden:/tmp$ ll -d junk
  drwxrwsr-x 2 rwp photos 4096 Apr 18 13:10 junk

The GNU coreutils chmod made an active decision to NOT clear the
setguid bit with chmod 0775.  This is different from traditional
systems which would have cleared that bit then.  To set it with octal
one would use:

  chmod 02775

To clear it on traditional systems (and older coreutils) would have

  chmod 0775

But that no longer clears the setgid bit.  Now you would need an

  chmod g-s

The sticky bit is another overloaded bit that means different things
in different contexts.  On a file it used to be a hint to the
operating system that the pages once loaded into memory should stay
loaded in memory.  A hint that the executable is often used and would
benefit users if it stayed in memory instead of being loaded from disk
each time.  I think it actually meant loaded in swap not memory.
Under the idea that loading from swap to memory was faster than
loading from file system and executing loader fixups.  This usage is
rather obsolescent these days.  I think the Linux kernel ignores it.
(Not sure and would be happy for a correction.)

On a directory such as /tmp it means that only the owner of the file
can remove the file.

  man 2 unlink

       EPERM or EACCES
              The directory containing pathname has the sticky  bit  (S_ISVTX)
              set  and  the  process's effective UID is neither the UID of the
              file to be deleted nor that of the directory containing it,  and
              the  process  is  not  privileged  (Linux:  does  not  have  the
              CAP_FOWNER capability).

> I also understood the role of the sticky bit set for "/usr/share":

You mean the setguid bit not the sticky bit.  And /usr/local not
/usr/share.  I think you derped there.  :-)

  address@hidden:/tmp$ ll -d /tmp /usr/share /usr/local
  drwxrwxrwt   6 root root  4096 Apr 19 18:10 /tmp
  drwxr-xr-x 170 root root  4096 Apr 18 19:22 /usr/share
  drwxrwsr-x  12 root staff 4096 Apr 11 22:43 /usr/local

> it causes the files I created there to be group owned by "staff"
> even when it is not my primary group.

Yes.  Exactly!

> But after all, it doesn't work as expected.  When I do "make
> install", even with the correct umask in effect, installed stuff in
> /usr/local is not group writable.  Looking at the output of "make
> install", "make" seems to set the umask explicitly itself:
> --8<---------------cut here---------------start------------->8---
> [...]
> Installing utilities for users to run.
> umask 022 && /bin/mkdir -p "/usr/local/bin"

So they set the umask explicitly to 022 there.  Hmm...  Not so
friendly doing that there.  It overrides what the user has set.

If it is only files created then that should be okay anyway.  Files
would be seldom modified by a group.  Hopefully no directories would
be created or they would be created with a different than desired set
of permission bits.  The above tries to create /usr/local/bin but that
will always have existed so will mostly be a noop unless it was
previously deleted.

That umask above is on a single line of the Makefile and should
evaporate after that line is done.  This is different from a script
where the effect would have been persistent for as long as the shell
lives.  In a Makefile each line is a separate shell process.

> for file in etags ctags emacsclient  ebrowse ; do \
>   /usr/bin/install -c  ${file} \
>     "/usr/local/bin"/` \
>       echo ${file} | sed -e 's/$//' -e 's,x,x,' \
>     ` || exit; \
> done
> make[1]: Leaving directory '/home/micha/software/emacs/lib-src'
> if test "no" = "no"; then \
>   /usr/bin/install -c  src/emacs "/usr/local/bin/`echo emacs-25.0.50 | sed 
> 's,x,x,'`" || exit 1 ; \
>   chmod 1755 "/usr/local/bin/`echo emacs-25.0.50 | sed 's,x,x,'`" || true; \

Here they are explicitly setting +t,u=rwx,g=rx,o=rx which sets that
obsolescent sticky bit on the executable and overrides the group

> This prevents me from getting the result you suggested.

Yes it does prevent this from working as I said.  I would say that is
darn unfriendly of them!  Probably worth a bug report.

Emacs is an old project and I suspect this is a remnant that has been
around for a very long time.

Things like this are probably there to avoid problems when people have
a 'umask 077' in effect.  If someone installs then the result would be
unusuable for anyone except that user since 077 masks off all of the
permissions for group and other.  I assume that at one time in the
past someone had a problem with such a umask setting and therefore
explicitly set the bits in the installation in order to avoid that

This is a good example of a seesaw problem.  Also known as a
teeter-totter.  One side goes up.  The other side goes down.  An
example where you can't please everyone.  There will always be the
opposite combination that is unhappy with the behavior.

However...  If all of the directories exist and have the desired
permissions then I expect those permissions will be preserved.  That
means that repeated 'make install' runs would update the files but not
change the directory permissions.

It is the directory permissions that are the critical permissions.
The directories hold the group staff access.  As long as you have
directory write access then that should be sufficient.  Let's discuss
this further if it is not.  And if it is not then that would
definitely be a worthy bug report.

Whew!  Long message!  Sorry for boring everyone but the details are
important and there were a lot of details to talk about.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]