X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=support%2Fnsm%2Ffile.c;fp=support%2Fnsm%2Ffile.c;h=5476446966028528f4d5a0e1a4cf6e1161c335a1;hp=5dd52c1e2640fb2effd07004c8902700811aa775;hb=1ca82a963ace17397bd7ec09f5e0707badd7c254;hpb=ddb095f82becc94c8e3a2429cc755dee5d1808c9 diff --git a/support/nsm/file.c b/support/nsm/file.c index 5dd52c1..5476446 100644 --- a/support/nsm/file.c +++ b/support/nsm/file.c @@ -338,10 +338,10 @@ nsm_is_default_parentdir(void) * * Returns true if successful, or false if some error occurred. */ +#ifdef HAVE_SYS_CAPABILITY_H static _Bool nsm_clear_capabilities(void) { -#ifdef HAVE_SYS_CAPABILITY_H cap_t caps; caps = cap_from_text("cap_net_bind_service=ep"); @@ -357,10 +357,60 @@ nsm_clear_capabilities(void) } (void)cap_free(caps); -#endif return true; } +#define CAP_BOUND_PROCFILE "/proc/sys/kernel/cap-bound" +static _Bool +prune_bounding_set(void) +{ +#ifdef PR_CAPBSET_DROP + int ret; + unsigned long i; + struct stat st; + + /* + * Prior to kernel 2.6.25, the capabilities bounding set was a global + * value. Check to see if /proc/sys/kernel/cap-bound exists and don't + * bother to clear the bounding set if it does. + */ + ret = stat(CAP_BOUND_PROCFILE, &st); + if (!ret) { + xlog(L_WARNING, "%s exists. Not attempting to clear " + "capabilities bounding set.", + CAP_BOUND_PROCFILE); + return true; + } else if (errno != ENOENT) { + /* Warn, but attempt to clear the bounding set anyway. */ + xlog(L_WARNING, "Unable to stat %s: %m", CAP_BOUND_PROCFILE); + } + + /* prune the bounding set to nothing */ + for (i = 0; i <= CAP_LAST_CAP; ++i) { + ret = prctl(PR_CAPBSET_DROP, i, 0, 0, 0); + if (ret) { + xlog(L_ERROR, "Unable to prune capability %lu from " + "bounding set: %m", i); + return false; + } + } +#endif /* PR_CAPBSET_DROP */ + return true; +} +#else /* !HAVE_SYS_CAPABILITY_H */ +static _Bool +nsm_clear_capabilities(void) +{ + return true; +} + +static _Bool +prune_bounding_set(void) +{ + return true; +} +#endif /* HAVE_SYS_CAPABILITY_H */ + /** * nsm_drop_privileges - drop root privileges * @pidfd: file descriptor of a pid file @@ -393,6 +443,9 @@ nsm_drop_privileges(const int pidfd) return false; } + if (!prune_bounding_set()) + return false; + if (st.st_uid == 0) { xlog_warn("Running as root. " "chown %s to choose different user", nsm_base_dirname);