Code Monkey home page Code Monkey logo

su-exec's Introduction

su-exec

switch user and group id, setgroups and exec

Purpose

This is a simple tool that will simply execute a program with different privileges. The program will be executed directly and not run as a child, like su and sudo does, which avoids TTY and signal issues (see below).

Notice that su-exec depends on being run by the root user, non-root users do not have permission to change uid/gid.

Usage

su-exec user-spec command [ arguments... ]

user-spec is either a user name (e.g. nobody) or user name and group name separated with colon (e.g. nobody:ftp). Numeric uid/gid values can be used instead of names. Example:

$ su-exec apache:1000 /usr/sbin/httpd -f /opt/www/httpd.conf

TTY & parent/child handling

Notice how su will make ps be a child of a shell while su-exec just executes ps directly.

$ docker run -it --rm alpine:edge su postgres -c 'ps aux'
PID   USER     TIME   COMMAND
    1 postgres   0:00 ash -c ps aux
   12 postgres   0:00 ps aux
$ docker run -it --rm -v $PWD/su-exec:/sbin/su-exec:ro alpine:edge su-exec postgres ps aux
PID   USER     TIME   COMMAND
    1 postgres   0:00 ps aux

Why reinvent gosu?

This does more or less exactly the same thing as gosu but it is only 10kb instead of 1.8MB.

su-exec's People

Contributors

hlovdal avatar ncopa avatar spekulatius avatar tianon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

su-exec's Issues

Alpine Build?

So for building the docker image for alpine is it the same as gosu replacing .gosu-deps with su-exec ?

Can someone share there alpine image?

ENV GOSU_VERSION 1.14
RUN set -eux; \
	\
	apk add --no-cache --virtual .gosu-deps \
		ca-certificates \
		dpkg \
		gnupg \
	; \
	\
	dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
	wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
	wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
	\
# verify the signature
	export GNUPGHOME="$(mktemp -d)"; \
	gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
	gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
	command -v gpgconf && gpgconf --kill all || :; \
	rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
	\
# clean up fetch dependencies
	apk del --no-network .gosu-deps; \
	\
	chmod +x /usr/local/bin/gosu; \
# verify that the binary works
	gosu --version; \
	gosu nobody true

why it freeze?

I'm using Ubuntu Studio with low latency kernel (deeply merged with Debian repository packages, because I'm using Debian's repositories in main)

$ uname -a
Linux hostname 6.2.0-1017-lowlatency #17~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Nov  2 18:30:14 UTC 2 x86_64 GNU/Linux

And trying to run Postgresql container (postgres:16-alpine). And it doesn't work. It stuck beforepostgres process will be ran.

When I attach to container:

docker exec -it container_name bash

And run ps aux command, it shows me:

PID   USER     TIME  COMMAND
    1 root      4:41 su-exec postgres /usr/local/bin/docker-entrypoint.sh postgres
   16 root      0:00 bash
   22 root      0:00 ps aux

docker-entrypoint.sh stuck

When I try to run simple command like:

su-exec postgres ls

It just freezes and nothing happening until I press Ctrl+C

I have an another PC with usual Ubuntu 22.04 OS and same container and su-exec is working fine. It looks like also an environment problem so, I don't know how to reproduce it. However, it looks like that is a su-exec's bug too, because it even doesn't work being wrapped inside container. Any ideas? Should I provide some extra logs (and how to do it if yes)?

"setgroups" operation not permitted?

Hi, after installing su-exec on an Alpine-based image for Docker I tried running it and received the following output: su-exec: setgroups: Operation not permitted

Below is a simple Dockerfile and test showing what I'm seeing.

Dockerfile

FROM alpine

RUN  apk update
RUN  apk add --no-cache bash su-exec \
 &&  rm -rf /var/cache/apk/*

RUN addgroup -g 82 -S www-data \
 && adduser -u 82 -D -S -G www-data www-data

USER www-data

Command

# su-exec root /bin/bash
su-exec: setgroups: Operation not permitted

su -c doesn't make the shell stay around

On my machine when I run the README example I get:

$ docker run -it --rm alpine:edge su postgres -c 'ps aux'
Unable to find image 'alpine:edge' locally
edge: Pulling from library/alpine
ba7f5deea89d: Pull complete 
Digest: sha256:72fac243935dc4398718b67c2469eafa6ccdca0c6af3ae365d5bba92400c69cd
Status: Downloaded newer image for alpine:edge
PID   USER     TIME  COMMAND
    1 postgres  0:00 ps aux

Problem with tty when using su-exec inside a docker

I have an use-case where I execute su-exec command from the entrypoint.sh script inside docker. Problem is that executed program can not open default tty device (in my case '/dev/pts/0') because it is still owned by root while su-exec command is running.

I did a workaround by manually changing ownership of tty device before running command, but maybe this could be resolved in su-exec?

On error, exit status code should be different than zero (0)

When running su-exec with wrong parameters, you get the Usage: [...] text, but the exit status code is zero (0) which hides the problem on systems relying on status codes signals, e.g. CI environments or shell scripts using set -e

$ docker run --rm -ti alpine:3.7 sh
/ # apk add --no-cache su-exec=0.2-r0
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/1) Installing su-exec (0.2-r0)
Executing busybox-1.27.2-r7.trigger
OK: 4 MiB in 12 packages
/ # su-exec xxxx
Usage: su-exec user-spec command [args]
/ # echo $?
0

deb/rpm packages

Hello,
I've used su-exec and I like it since it's smaller than gosu, but most distributions don't package it (yet).

I could setup a build system for deb and rpm packages, so that those could be uploaded on github directly and pulled from there via curl/wget.

Would you be interested in such a contribution?

v0.3?

The last commit seems like an important improvement. Please tag it to generate a release tarball on github.

Packaging license in binary

Could we please have an option to print out the license? Basically trying to make sure that the binaries we use are complying with the MIT License out-of-the-box.

⚠️DANGER: Vulnerable by design! (on any system supporting TIOCSTI, such as Linux)

Hello,

I regret to inform you that any program which crosses privilege boundaries in the manner this program does without also restricting access to the parent TTY (which seems to be the main design (mis-)feature of this program), is fundamentally vulnerable by design on any system allowing the TIOCSTI ioctl on said TTY.

See: https://www.openwall.com/lists/oss-security/2017/06/03/9
See also: https://ruderich.org/simon/notes/su-sudo-from-root-tty-hijacking
See also: tianon/gosu#37

Linux still supports TIOCSTI, and refuses to change due to its unfortunate posture of tying its own hands to keep backwards-compatibility with userspace forever. OpenBSD has removed it, but your users are probably mainly Linux people.

One way to address this is to do exactly as you currently complain about other programs doing (parent staying alive to proxy io), which seems to be the entire reason you wrote this. There are non-portable ways of filtering TIOCSTI without proxying io and otherwise breaking parent TTY manipulation (see util-linux/util-linux@8e49250, for example), but this will not necessarily work on all systems, and IMO manipulation of TTYs across privilege boundaries sounds more like a bug than a feature to begin with as it may allow intended-to-be-deprivileged code from triggering undefined behavior in the parent context.

Consider adding an appropriately scary warning to README.md, and notifying any downstream consumers you are aware of.

Sorry to be the bearer of bad news.

'cd' command is not working

Once I execute
su-exec ubuntu cd /home
I got following output:
su-exec: cd: No such file or directory

On the other hand, once I execute su-exec ubuntu ls -l /home the command is working properly.
Output:
total 0

Generally, it is only cd not working for me. Thus, I find it as a bug.

BusyBox setuidgid

How is this different from doing:

# exec setuidgid $USER command

or

# exec chpst -u $USER: -U $USER: command

Those are BusyBox builtin commands.

question: empty variables expansion

BLAH is undefined

#!/usr/bin/env bash
set -x
su-exec do-the "${BLAH}" with-params

expands to su-exec do-the '' with-params

#!/usr/bin/env sh
set -x
su-exec do-the "${BLAH}" with-params

expands to su-exec do-the with-params

meanwhile

#!/usr/bin/env bash
set -x
su-exec do-the ${BLAH} with-params

expands to su-exec do-the with-params properly, but this is unsecure

As you may see in bash an empty variable has been surrounded by the single quotes and empty for sh.

Is that proper behavior for empty variables expansion?

Unable to execute a bash function

For example, if I have a bash function defined in a script:

function foo()
{
}

and trying to run it as another user in the same script:

su-exec user-foo foo

I would get an error, something similar to "file foo not exist ...."

As a compassion, the su command works in this scenario:

export -f foo
su user-foo -c foo

github release for a simple binary

Hi folks

It'd be very useful if a prebuilt binary for su-exec could be published on the github releases page here.

People who choose trust the repo can reasonably trust a binary uploaded to the repo's releases page too. Unless they link to a specific git commithash when they fetch su-exec.c and the makefile, and unless they review the whole thing whenever they change which git revision they build, they're trusting the repo anyway.

The vast majority of uses would be satisfied by an amd64 binary built for glibc 2.12 - for CentOS / RHEL 6.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.