Last active
December 21, 2021 19:19
-
-
Save christierney/37f3b2d57d51adfa0cb6faed1f6971f9 to your computer and use it in GitHub Desktop.
Reprex demonstrating buggy behavior in docker-for-mac on M1 hardware. Attempting to build and run this image from an M1 machine using `--platform Linux/amd64` will result in an "Operation not permitted" error from one of the `initgroups` calls.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM ubuntu:bionic-20201119 | |
RUN export DEBIAN_FRONTEND=noninteractive && \ | |
apt-get update && \ | |
apt-get install -y \ | |
gcc && \ | |
rm -rf /var/lib/apt/lists/* | |
ARG USER_GID=1001 | |
ARG USER_UID=1001 | |
# Create a non-root user with known id:gid that our script will switch to | |
RUN groupadd -g $USER_GID notroot && \ | |
useradd -u $USER_UID -g notroot notroot | |
COPY ./forkandinit.c / | |
RUN gcc /forkandinit.c -o /forkandinit | |
CMD ["/forkandinit"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <grp.h> | |
#include <errno.h> | |
#include <pwd.h> | |
#include <sys/wait.h> | |
int main() { | |
errno = 0; | |
uid_t root = 0; | |
uid_t uid = 1001; // nonroot | |
gid_t gid = 1001; // nonroot | |
pid_t pid = 0; | |
pid_t terminated = 0; | |
int wstatus = 0; | |
printf("parent: dropping privileges, forking, and restoring privileges:\n"); | |
if (setresgid(-1, gid, getegid()) < 0) | |
perror("parent: setresgid error"); | |
if (setresuid(-1, uid, geteuid()) < 0) | |
perror("parent: setresuid error"); | |
printf("parent: forking\n"); | |
// emit buffered messages before forking. | |
fflush(stdout); | |
fflush(stderr); | |
pid = fork(); | |
if (pid == 0) { | |
// The child. | |
printf("child: forked\n"); | |
// Change the effective user to root. | |
if (seteuid(root) < 0) | |
perror("child: seteuid error"); | |
// Get user info to use in group calls | |
struct passwd* pPrivPasswd = getpwuid(root); | |
if (pPrivPasswd == NULL) | |
printf("child:failed to load root passwd data\n"); | |
// init supplemental groups | |
if (initgroups(pPrivPasswd->pw_name, pPrivPasswd->pw_gid) < 0) | |
perror("child: initgroups error"); | |
printf("child: done\n"); | |
} else { | |
// The parent. | |
printf("parent: waiting\n"); | |
terminated = wait(&wstatus); | |
printf("parent: done\n"); | |
} | |
return(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment