Skip to content

feat(install.sh): sudo {mkdir|cp} if necessary #432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

rouson
Copy link
Contributor

@rouson rouson commented Apr 8, 2021

This commit causes fpm to invoke mkdir and/or cp using sudo if
the user lacks write permissions to the installation destination on Unix-like
systems. Invoking sudo potentially prompts the user for a
password.

This commit causes fpm to invoke mkdir and/or cp using sudo if
the user does not have write permissions to the installation
destination. Invoking sudo potentially prompts the user for a
password.
@LKedward
Copy link
Member

LKedward commented Apr 8, 2021

My understanding of best practices with regards to sudo is that it should be left to the user to invoke manually at a top level. i.e. the correct procedure is to do sudo fpm ... rather than have fpm call sudo from within. This is much more transparent to the user and does not introduce interactivity to the fpm workflow. It should be also noted that sudo isn't available on all systems.

@rouson
Copy link
Contributor Author

rouson commented Apr 8, 2021

@LKedward I've always been advised to do the exact opposite. Think of it this way: fpm is now an approximately 21,000-line program and growing. Running sudo fpm ... gives the potential for every single line of code to execute with superuser privileges. That means a tremendous amount of havoc can be wreaked even just by mistake and worse yet if there's anything malicious that creeps into the code. By contrast, when sudo is run only for each command that needs it, the user will be prompted at least the first time and possibly each time. Also, the prompt will or at least should indicate what specific command will be granted sudo privileges.

Moreover, running sudo fpm ... implies that all files created along the way will require sudo rm ... to remove, which adds additional ways in which the process can go wrong: one slip with something like sudo rm -rf * executed mistakenly in the wrong place and the user ends up in really bad shape.

I strongly advise against recommending sudo fpm ....

@vmagnin
Copy link
Member

vmagnin commented Apr 8, 2021

Interesting discussion!
See my new post: https://fortran-lang.discourse.group/t/what-about-security-issues-in-fortran/102/15

@LKedward
Copy link
Member

LKedward commented Apr 8, 2021

Thanks for the explanation Damian @rouson, I agree with your concerns about elevating the entire fpm binary. Your point is particularly acute for fpm currently since it relies heavily on execute_command_line for much of it's file-system access (see also #166); this is something that we aim to phase-out completely with a proper file-system library (e.g. MarDiehl/stdlib_os).

With that said I am still unsure about the chosen methodology here to invoke sudo from within fpm. We can't use sudo if we want to switch to using a file-system API call in future. I am no expert here, particularly for cross-platform implementation, but I think a better approach would be to use system APIs to drop any elevated permissions immediately when fpm is started and then switch back only where needed. In POSIX, I think this can be achieved with getuid/seteuid etc.

@arjenmarkus
Copy link
Member

arjenmarkus commented Apr 8, 2021 via email

@awvwgk
Copy link
Member

awvwgk commented Apr 8, 2021

You should seldom run into a scenario where you have to use sudo in a build system. I have packaged for Arch Linux, msys2, brew and conda so far, Arch's makepkg even refuses to run under sudo. Usually a package manager will package in a local prefix instead of the system root, installing directly from the build system (good old sudo make install) is hardly ever a recommended strategy.

@rouson
Copy link
Contributor Author

rouson commented Apr 9, 2021

@awvwgk Your comment makes sense for individual users but presumably not for system administrators. Is the intention that fpm not be used by system administrators? I'm effectively the system administrator for the free Sourcery Institute Linux virtual machine that we use frequently in courses we teach and with consulting clients. The virtual machine runs Lubuntu Linux. I install packages in the virtual machine with sudo apt install ... frequently and I don't know of a better way (I tried Homebrew back when it was referred to as Linuxbrew on Linux and found it lacking despite it being very useful on macOS). I also use the virtual machine for my own work so it's important to have separate user accounts and I usually encrypt the accounts in the virtual machine for privacy reasons. That precludes "local" installation, if by that phrase you're referring to installing in a user's home directory.

The whole point of the virtual machine is to ensure that course attendees and clients have necessary software pre-installed so that we don't spend time on set-up. This necessitates installing to a common space. Also, the default install locations for many (most?) CMake packages is in a subdirectory of/usr so I'm not sure why it would be considered unusual to require sudo for installation.

@awvwgk
Copy link
Member

awvwgk commented Apr 9, 2021

I'd think it makes also (especially?) sense for system operators. I'm not familar with the dpkg / apt-get / .deb family of package managers, since I'm usually work with Arch Linux based distros. While the toolchains are named differently, I would expect the workflow to be similar:

  1. Write the package build file (PKGBUILD on Arch, debian/{control,rules,...} on Debian, ...)
  2. Build the package as user (makepkg on Arch, debuild -us -uc on Debian, ...)
  3. Install the package with sudo (sudo pacman -U <pkg> on Arch, sudo dpkg -i <pkg> on Debian, ...)

Usually, this is done by somebody else and you can just access the binary package by sudo pacman -S <name> / sudo apt-get install <name>. But for Arch based distros it is not uncommon for users to package themselves, partly because the distro is smaller than Debian/Ubuntu, but mainly because the process is streamlined and thoroughly documented. At least for me it seems like a natural thing to do when I encounter software I want to install but don't find in my package manager.

@milancurcic
Copy link
Member

I see merits to both sides of the argument.

I still prefer fpm not doing anything internally about permissions, if at all possible. It's not fpm's responsibility and it adds complexity to future development.

If you really need to install to system paths, then sudo it at your own risk.

So I prefer this be handled with a note in the docs a-la:

We don't recommend running fpm with administrator permissions. If you need to do that, for example for installing packages into system path, do it carefully and at your own risk.

@awvwgk
Copy link
Member

awvwgk commented Apr 9, 2021

We already have means to restrict fpm when running with elevated permissions, e.g. the install command supports a --no-rebuild:

fpm build
sudo fpm install --prefix=/usr --no-rebuild

Alternatively, there is always the do-it-yourself --runner variant available with

fpm run --runner "sudo install -Dm 755" -- /usr/bin/fpm

@everythingfunctional
Copy link
Member

I think this idea has merit. The security "principle of least privilege" says that elevated permissions should only be given when necessary. The whole fpm executable doesn't need escalated privileges, even for the command fpm install, so we should limit the places where privileges are escalated to the places that we know they're needed.

That said, we're not quite ready to do it in a cross-platform way reliably. We should create an issue to do this once we have a more fully featured os module. The use case of a system admin wanting to install an fpm package for all users is pretty likely, and saying to them "learn how to create a system package" or "trust that fpm won't do anything dangerous when run with sudo" I think is not a satisfying answer.

@ivan-pi
Copy link
Member

ivan-pi commented Apr 9, 2021

@rouson
Copy link
Contributor Author

rouson commented Apr 9, 2021

@awvwgk your latest comment is very helpful. I like the fpm build && sudo fpm install ... approach. I'm closing this pull request.

In retrospect, it would have been better for me to describe my use case in an issue before submitting this pull request. I was attempting to install fpm itself in the aforementioned virtual machine under /usr/local. This is the one scenario in which fpm build && sudo fpm install ... won't work (unless there's a prior fpm installation). @everythingfunctional just pointed out to me that the more appropriate place to invoke sudo in my scenario is inside install.sh. I will submit this feature request as an issue to solicit feedback and then create a new pull request to edit install.sh if there's consensus that my suggestion is acceptable.

@rouson rouson closed this Apr 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants