8000 Call prctl(2) with long integers, specify 5 arguments, and avoid casts by karelzak · Pull Request #3085 · util-linux/util-linux · GitHub
[go: up one dir, main page]

Skip to content

Call prctl(2) with long integers, specify 5 arguments, and avoid casts #3085

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Call prctl(2) with long integers, specify 5 arguments, and avoid casts
Since libc's prctl(2) wrapper is a variadic function, arguments must
have the right width.  Otherwise, the behavior is undefined.

Also, the 5 arguments must be specified always, or the behavior is also
undefined.  libc reads 5 values and passes them all to the kernel, so if
one is uninitialized, the kernel will receive garbagge, which could
result in EINVAL (most likely), or worse, a different action.

Also, avoid some casts to unsigned long, by changing the type of the
parameter to some local wrappers.

And use consistently 0L.  0UL is basically the same, and uses one more
character.  Keep it short.

Link: <https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit/?id=6698b096a6f5342cb9b338c237ed875a8635497a>
Link: <https://lore.kernel.org/linux-man/ddbdyaiptesjalgfmztxideej67e3yaob7ucsmbf6qvriwxiif@dohhxrqgwhrf/T/#med306b5b003f9cc7cc2de69fcdd7ee2d056d0954>
Cc: Xi Ruoyao <xry111@xry111.site>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
  • Loading branch information
alejandro-colomar authored and karelzak committed Jun 6, 2024
commit 828ea383348f01a2135f150870e9c6cff853241f
2 changes: 1 addition & 1 deletion include/seccomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ static int ul_set_seccomp_filter_spec_allow(const struct sock_fprog *prog)
return 0;
#endif

return prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog);
return prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog, 0L, 0L);
}

#endif /* UL_SECCOMP_H */
4 changes: 2 additions & 2 deletions lib/caputils.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
static int test_cap(unsigned int cap)
{
/* prctl returns 0 or 1 for valid caps, -1 otherwise */
return prctl(PR_CAPBSET_READ, cap, 0, 0, 0) >= 0;
return prctl(PR_CAPBSET_READ, cap, 0L, 0L, 0L) >= 0;
}

static int cap_last_by_bsearch(int *ret)
Expand Down Expand Up @@ -120,7 +120,7 @@ void cap_permitted_to_ambient(void)
continue;

if ((effective & (1ULL << cap))
&& prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0) < 0)
&& prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0L, 0L) < 0)
err(EXIT_FAILURE, _("prctl(PR_CAP_AMBIENT) failed"));
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/env.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,11 @@ char *safe_getenv(const char *arg)
if ((getuid() != geteuid()) || (getgid() != getegid()))
return NULL;
#ifdef HAVE_PRCTL
if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
if (prctl(PR_GET_DUMPABLE, 0L, 0L, 0L, 0L) == 0)
return NULL;
#else
#if (defined(linux) && defined(SYS_prctl))
if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0L, 0L, 0L, 0L) == 0)
return NULL;
#endif
#endif
Expand Down
4 changes: 2 additions & 2 deletions misc-utils/enosys.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,10 @@ int main(int argc, char **argv)
/* *SET* below will return EINVAL when either the filter is invalid or
* seccomp is not supported. To distinguish those cases do a *GET* here
*/
if (prctl(PR_GET_SECCOMP) == -1 && errno == EINVAL)
if (prctl(PR_GET_SECCOMP, 0L, 0L, 0L, 0L) == -1 && errno == EINVAL)
err(EXIT_NOTSUPP, _("Seccomp non-functional"));

if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
if (prctl(PR_SET_NO_NEW_PRIVS, 1L, 0L, 0L, 0L))
err_nosys(EXIT_FAILURE, _("Could not run prctl(PR_SET_NO_NEW_PRIVS)"));

if (ul_set_seccomp_filter_spec_allow(&prog))
Expand Down
6 changes: 3 additions & 3 deletions schedutils/coresched.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,20 +129,20 @@ static sched_core_cookie core_sched_get_cookie(pid_t pid)

static void core_sched_create_cookie(pid_t pid, sched_core_scope type)
{
if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_CREATE, pid, type, 0))
if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_CREATE, pid, type, 0L))
err(EXIT_FAILURE, _("Failed to create cookie for PID %d"), pid);
}

static void core_sched_pull_cookie(pid_t from)
{
if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_SHARE_FROM, from,
PR_SCHED_CORE_SCOPE_THREAD, 0))
PR_SCHED_CORE_SCOPE_THREAD, 0L))
err(EXIT_FAILURE, _("Failed to pull cookie from PID %d"), from);
}

static void core_sched_push_cookie(pid_t to, sched_core_scope type)
{
if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_SHARE_TO, to, type, 0))
if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_SHARE_TO, to, type, 0L))
err(EXIT_FAILURE, _("Failed to push cookie to PID %d"), to);
}

Expand Down
2 changes: 1 addition & 1 deletion sys-utils/setpriv-landlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ void do_landlock(const struct setpriv_landlock_opts *opts)
err(SETPRIV_EXIT_PRIVERR, _("adding landlock rule failed"));
}

if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1)
if (prctl(PR_SET_NO_NEW_PRIVS, 1L, 0L, 0L, 0L) == -1)
err(SETPRIV_EXIT_PRIVERR, _("disallow granting new privileges for landlock failed"));

if (landlock_restrict_self(fd, 0) == -1)
Expand Down
34 changes: 16 additions & 18 deletions sys-utils/setpriv.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ static void __attribute__((__noreturn__)) usage(void)
exit(EXIT_SUCCESS);
}

static int has_cap(enum cap_type which, unsigned int i)
static int has_cap(enum cap_type which, unsigned long i)
{
switch (which) {
case CAP_TYPE_EFFECTIVE:
Expand All @@ -174,8 +174,7 @@ static int has_cap(enum cap_type which, unsigned int i)
case CAP_TYPE_PERMITTED:
return capng_have_capability((capng_type_t)which, i);
case CAP_TYPE_AMBIENT:
return prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET,
(unsigned long) i, 0UL, 0UL);
return prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0L, 0L);
default:
warnx(_("invalid capability type"));
return -1;
Expand Down Expand Up @@ -223,7 +222,7 @@ static void dump_one_secbit(int *first, int *bits, int bit, const char *name)
static void dump_securebits(void)
{
int first = 1;
int bits = prctl(PR_GET_SECUREBITS, 0, 0, 0, 0);
int bits = prctl(PR_GET_SECUREBITS, 0L, 0L, 0L, 0L);

if (bits < 0) {
warnx(_("getting process secure bits failed"));
Expand Down Expand Up @@ -323,7 +322,7 @@ static void dump_pdeathsig(void)
{
int pdeathsig;

if (prctl(PR_GET_PDEATHSIG, &pdeathsig) != 0) {
if (prctl(PR_GET_PDEATHSIG, &pdeathsig, 0L, 0L, 0L) != 0) {
warn(_("get pdeathsig failed"));
return;
}
Expand Down Expand Up @@ -363,7 +362,7 @@ static void dump(int dumplevel)

dump_groups();

x = prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0);
x = prctl(PR_GET_NO_NEW_PRIVS, 0L, 0L, 0L, 0L);
if (0 <= x)
printf("no_new_privs: %d\n", x);
else
Expand Down Expand Up @@ -449,7 +448,7 @@ static void parse_groups(struct privctx *opts, const char *str)
static void parse_pdeathsig(struct privctx *opts, const char *str)
{
if (!strcmp(str, "keep")) {
if (prctl(PR_GET_PDEATHSIG, &opts->pdeathsig) != 0)
if (prctl(PR_GET_PDEATHSIG, &opts->pdeathsig, 0L, 0L, 0L) != 0)
errx(SETPRIV_EXIT_PRIVERR,
_("failed to get parent death signal"));
} else if (!strcmp(str, "clear")) {
Expand Down Expand Up @@ -495,8 +494,7 @@ static void bump_cap(unsigned int cap)
capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, cap);
}

static int cap_update(capng_act_t action,
enum cap_type type, unsigned int cap)
static int cap_update(capng_act_t action, enum cap_type type, unsigned long cap)
{
switch (type) {
case CAP_TYPE_EFFECTIVE:
Expand All @@ -510,10 +508,10 @@ static int cap_update(capng_act_t action,

if (action == CAPNG_ADD)
ret = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE,
(unsigned long) cap, 0UL, 0UL);
cap, 0L, 0L);
else
ret = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER,
(unsigned long) cap, 0UL, 0UL);
cap, 0L, 0L);

return ret;
}
Expand Down Expand Up @@ -565,7 +563,7 @@ static void parse_securebits(struct privctx *opts, const char *arg)
char *c;

opts->have_securebits = 1;
opts->securebits = prctl(PR_GET_SECUREBITS, 0, 0, 0, 0);
opts->securebits = prctl(PR_GET_SECUREBITS, 0L, 0L, 0L, 0L);
if (opts->securebits < 0)
err(SETPRIV_EXIT_PRIVERR, _("getting process secure bits failed"));

Expand Down Expand Up @@ -687,10 +685,10 @@ static void do_seccomp_filter(const char *file)
/* *SET* below will return EINVAL when either the filter is invalid or
* seccomp is not supported. To distinguish those cases do a *GET* here
*/
if (prctl(PR_GET_SECCOMP) == -1 && errno == EINVAL)
if (prctl(PR_GET_SECCOMP, 0L, 0L, 0L, 0L) == -1 && errno == EINVAL)
err(SETPRIV_EXIT_PRIVERR, _("Seccomp non-functional"));

if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
if (prctl(PR_SET_NO_NEW_PRIVS, 1L, 0L, 0L, 0L))
err(SETPRIV_EXIT_PRIVERR, _("Could not run prctl(PR_SET_NO_NEW_PRIVS)"));

if (ul_set_seccomp_filter_spec_allow(&prog))
Expand Down Expand Up @@ -1059,7 +1057,7 @@ int main(int argc, char **argv)
do_reset_environ(pw);
}

if (opts.nnp && prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1)
if (opts.nnp && prctl(PR_SET_NO_NEW_PRIVS, 1L, 0L, 0L, 0L) == -1)
err(EXIT_FAILURE, _("disallow granting new privileges failed"));

if (opts.selinux_label)
Expand All @@ -1069,7 +1067,7 @@ int main(int argc, char **argv)
if (opts.seccomp_filter)
do_seccomp_filter(opts.seccomp_filter);

if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
if (prctl(PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L) == -1)
err(EXIT_FAILURE, _("keep process capabilities failed"));

/* We're going to want CAP_SETPCAP, CAP_SETUID, and CAP_SETGID if
Expand Down Expand Up @@ -1102,7 +1100,7 @@ int main(int argc, char **argv)
err(SETPRIV_EXIT_PRIVERR, _("setgroups failed"));
}

if (opts.have_securebits && prctl(PR_SET_SECUREBITS, opts.securebits, 0, 0, 0) != 0)
if (opts.have_securebits && prctl(PR_SET_SECUREBITS, opts.securebits, 0L, 0L, 0L) != 0)
err(SETPRIV_EXIT_PRIVERR, _("set process securebits failed"));

if (opts.bounding_set) {
Expand All @@ -1123,7 +1121,7 @@ int main(int argc, char **argv)
}

/* Clear or set parent death signal */
if (opts.pdeathsig && prctl(PR_SET_PDEATHSIG, opts.pdeathsig < 0 ? 0 : opts.pdeathsig) != 0)
if (opts.pdeathsig && prctl(PR_SET_PDEATHSIG, opts.pdeathsig < 0 ? 0L : opts.pdeathsig, 0L, 0L, 0L) != 0)
err(SETPRIV_EXIT_PRIVERR, _("set parent death signal failed"));

do_landlock(&opts.landlock);
Expand Down
2 changes: 1 addition & 1 deletion tests/helpers/test_mkfds.c
Original file line number Diff line number Diff line change
Expand Up @@ -4372,7 +4372,7 @@ static void list_parameters(const char *factory_name)

static void rename_self(const char *comm)
{
if (prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0) < 0)
if (prctl(PR_SET_NAME, (unsigned long)comm, 0L, 0L, 0L) < 0)
err(EXIT_FAILURE, "failed to rename self via prctl: %s", comm);
}

Expand Down
0