aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2022-08-05 20:43:05 -0700
committerAndrew G. Morgan <morgan@kernel.org>2022-08-05 20:43:05 -0700
commitfc437fd8308b4ee4d8e3053d51471883946f9b04 (patch)
treea0acacefad61ebe02dd3631237399caa1f465c34
parent7db9589038d88b88111582da7681d33e1177f636 (diff)
downloadlibcap-fc437fd8308b4ee4d8e3053d51471883946f9b04.tar.gz
Fix an issue with bash displaying an error.
Also down size the default capabilities needed by the 'sucap' su program. This is aimed at addressing: https://bugzilla.kernel.org/show_bug.cgi?id=215926 Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r--contrib/sucap/Makefile12
-rw-r--r--contrib/sucap/su.c43
2 files changed, 41 insertions, 14 deletions
diff --git a/contrib/sucap/Makefile b/contrib/sucap/Makefile
index c58d5c4..df61ed5 100644
--- a/contrib/sucap/Makefile
+++ b/contrib/sucap/Makefile
@@ -1,12 +1,18 @@
topdir=$(shell pwd)/../..
include ../../Make.Rules
+# This line is here to link against the in-tree copy of libcap.so
+LINKEXTRA=-Wl,-rpath,$(topdir)/libcap
+DEPS=../../libcap/libcap.so
+
all: su
-su: su.c
- $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DPAM_APP_NAME=\"sucap\" -o $@ $< -lpam -lpam_misc -lcap
+su: su.c $(DEPS)
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DPAM_APP_NAME=\"sucap\" $< -o $@ $(LINKEXTRA) -lpam -lpam_misc $(LIBCAPLIB)
# to permit all ambient capabilities, this needs all permitted.
- sudo setcap =p ./su
+ # sudo setcap =p ./su
+ # to permit all inheritable, as CAP_PURE1E needs, we don't need as much
+ sudo setcap cap_chown,cap_setgid,cap_setuid,cap_dac_read_search,cap_setpcap=p ./su
clean:
rm -f su su.o *~
diff --git a/contrib/sucap/su.c b/contrib/sucap/su.c
index c8cc05f..e3dfe70 100644
--- a/contrib/sucap/su.c
+++ b/contrib/sucap/su.c
@@ -149,20 +149,26 @@ static void checkfds(void)
if (fstat(1, &st) == -1) {
fd = open("/dev/null", O_WRONLY);
- if (fd == -1) exit(1);
+ if (fd == -1) goto badfds;
if (fd != 1) {
- if (dup2(fd, 1) == -1) exit(1);
- if (close(fd) == -1) exit(1);
+ if (dup2(fd, 1) == -1) goto badfds;
+ if (close(fd) == -1) goto badfds;
}
}
if (fstat(2, &st) == -1) {
fd = open("/dev/null", O_WRONLY);
- if (fd == -1) exit(1);
+ if (fd == -1) goto badfds;
if (fd != 2) {
- if (dup2(fd, 2) == -1) exit(1);
- if (close(fd) == -1) exit(1);
+ if (dup2(fd, 2) == -1) goto badfds;
+ if (close(fd) == -1) goto badfds;
}
}
+
+ return;
+
+badfds:
+ perror("bad filedes");
+ exit(1);
}
/*
@@ -1210,6 +1216,11 @@ static int set_credentials(cap_t all, int login,
}
uid = pw->pw_uid;
+ if (uid == 0) {
+ D(("user is superuser: %s", user));
+ *retval = PAM_CRED_ERR;
+ return 1;
+ }
*uid_p = uid;
shell = x_strdup(pw->pw_shell);
@@ -1226,11 +1237,18 @@ static int set_credentials(cap_t all, int login,
*retval = PAM_CRED_ERR;
return 1;
}
- if (pam_misc_setenv(pamh, "HOME", pw->pw_dir, 0) != PAM_SUCCESS) {
- D(("failed to set HOME"));
- *retval = PAM_CRED_ERR;
- return 1;
- }
+ }
+
+ /* bash requires these be set to the target user values */
+ if (pam_misc_setenv(pamh, "HOME", pw->pw_dir, 0) != PAM_SUCCESS) {
+ D(("failed to set HOME"));
+ *retval = PAM_CRED_ERR;
+ return 1;
+ }
+ if (pam_misc_setenv(pamh, "USER", user, 0) != PAM_SUCCESS) {
+ D(("failed to set USER"));
+ *retval = PAM_CRED_ERR;
+ return 1;
}
current = cap_get_proc();
@@ -1613,5 +1631,8 @@ auth_exit:
}
su_exit:
+ if (status != 0) {
+ perror(PAM_APP_NAME " failed");
+ }
exit(status); /* transparent exit */
}