diff --git a/backport-capsh-better-error-handling-for-integer-parsing.patch b/backport-capsh-better-error-handling-for-integer-parsing.patch new file mode 100644 index 0000000000000000000000000000000000000000..57506e69cfc88d33a942202f1c4535f2710c0f3c --- /dev/null +++ b/backport-capsh-better-error-handling-for-integer-parsing.patch @@ -0,0 +1,141 @@ +From 9c4997d6592e5daf046a6968ac83cf615c51fbe1 Mon Sep 17 00:00:00 2001 +From: "Andrew G. Morgan" +Date: Sat, 6 Nov 2021 08:45:06 -0700 +Subject: [PATCH] capsh: better error handling for integer parsing. + +Bug reported by meitingli: + + https://bugzilla.kernel.org/show_bug.cgi?id=214911 + +Signed-off-by: Andrew G. Morgan +--- + progs/capsh.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 40 insertions(+), 9 deletions(-) + +diff --git a/progs/capsh.c b/progs/capsh.c +index 2295359..4f568c3 100644 +--- a/progs/capsh.c ++++ b/progs/capsh.c +@@ -40,6 +40,35 @@ + + #define MAX_GROUPS 100 /* max number of supplementary groups for user */ + ++/* parse a non-negative integer with some error handling */ ++static unsigned long nonneg_uint(const char *text, const char *prefix, int *ok) ++{ ++ char *remains; ++ unsigned long value; ++ ssize_t len = strlen(text); ++ ++ if (len == 0 || *text == '-') { ++ goto fail; ++ } ++ value = strtoul(text, &remains, 0); ++ if (*remains) { ++ goto fail; ++ } ++ if (ok != NULL) { ++ *ok = 1; ++ } ++ return value; ++ ++fail: ++ if (ok == NULL) { ++ fprintf(stderr, "%s: want non-negative integer, got \"%s\"\n", ++ prefix, text); ++ exit(1); ++ } ++ *ok = 0; ++ return 0; ++} ++ + static char *binary(unsigned long value) + { + static char string[8*sizeof(unsigned long) + 1]; +@@ -667,7 +696,7 @@ int main(int argc, char *argv[], char *envp[]) + unsigned value; + int set; + +- value = strtoul(argv[i]+7, NULL, 0); ++ value = nonneg_uint(argv[i]+7, "invalid --keep value", NULL); + set = prctl(PR_SET_KEEPCAPS, value); + if (set < 0) { + fprintf(stderr, "prctl(PR_SET_KEEPCAPS, %u) failed: %s\n", +@@ -724,7 +753,7 @@ int main(int argc, char *argv[], char *envp[]) + } else if (!strncmp("--secbits=", argv[i], 10)) { + unsigned value; + int status; +- value = strtoul(argv[i]+10, NULL, 0); ++ value = nonneg_uint(argv[i]+10, "invalid --secbits value", NULL); + status = cap_set_secbits(value); + if (status < 0) { + fprintf(stderr, "failed to set securebits to 0%o/0x%x\n", +@@ -737,8 +766,9 @@ int main(int argc, char *argv[], char *envp[]) + fprintf(stderr, "already forked\n"); + exit(1); + } +- value = strtoul(argv[i]+10, NULL, 0); ++ value = nonneg_uint(argv[i]+10, "invalid --forkfor value", NULL); + if (value == 0) { ++ fprintf(stderr, "require non-zero --forkfor value\n"); + goto usage; + } + child = fork(); +@@ -753,7 +783,8 @@ int main(int argc, char *argv[], char *envp[]) + pid_t result; + unsigned value; + +- value = strtoul(argv[i]+9, NULL, 0); ++ value = nonneg_uint(argv[i]+9, "invalid --killit signo value", ++ NULL); + if (!child) { + fprintf(stderr, "no forked process to kill\n"); + exit(1); +@@ -779,7 +810,7 @@ int main(int argc, char *argv[], char *envp[]) + unsigned value; + int status; + +- value = strtoul(argv[i]+6, NULL, 0); ++ value = nonneg_uint(argv[i]+6, "invalid --uid value", NULL); + status = setuid(value); + if (status < 0) { + fprintf(stderr, "Failed to set uid=%u: %s\n", +@@ -790,7 +821,7 @@ int main(int argc, char *argv[], char *envp[]) + unsigned value; + int status; + +- value = strtoul(argv[i]+10, NULL, 0); ++ value = nonneg_uint(argv[i]+10, "invalid --cap-uid value", NULL); + status = cap_setuid(value); + if (status < 0) { + fprintf(stderr, "Failed to cap_setuid(%u): %s\n", +@@ -801,7 +832,7 @@ int main(int argc, char *argv[], char *envp[]) + unsigned value; + int status; + +- value = strtoul(argv[i]+6, NULL, 0); ++ value = nonneg_uint(argv[i]+6, "invalid --gid value", NULL); + status = setgid(value); + if (status < 0) { + fprintf(stderr, "Failed to set gid=%u: %s\n", +@@ -1009,7 +1040,7 @@ int main(int argc, char *argv[], char *envp[]) + } else if (!strncmp("--is-uid=", argv[i], 9)) { + unsigned value; + uid_t uid; +- value = strtoul(argv[i]+9, NULL, 0); ++ value = nonneg_uint(argv[i]+9, "invalid --is-uid value", NULL); + uid = getuid(); + if (uid != value) { + fprintf(stderr, "uid: got=%d, want=%d\n", uid, value); +@@ -1018,7 +1049,7 @@ int main(int argc, char *argv[], char *envp[]) + } else if (!strncmp("--is-gid=", argv[i], 9)) { + unsigned value; + gid_t gid; +- value = strtoul(argv[i]+9, NULL, 0); ++ value = nonneg_uint(argv[i]+9, "invalid --is-gid value", NULL); + gid = getgid(); + if (gid != value) { + fprintf(stderr, "gid: got=%d, want=%d\n", gid, value); +-- +1.8.3.1 + diff --git a/backport-setcap-clean-up-error-handling-of-the-ns-rootid-argument.patch b/backport-setcap-clean-up-error-handling-of-the-ns-rootid-argument.patch new file mode 100644 index 0000000000000000000000000000000000000000..11ee31629605f149cc7a204d6b41e37140851149 --- /dev/null +++ b/backport-setcap-clean-up-error-handling-of-the-ns-rootid-argument.patch @@ -0,0 +1,70 @@ +From 8e1e967bc8d99a3233d51f67f6b88620cdff78dc Mon Sep 17 00:00:00 2001 +From: "Andrew G. Morgan" +Date: Sat, 6 Nov 2021 08:02:20 -0700 +Subject: [PATCH] setcap: clean up error handling of the ns rootid argument. + +Bug reported by Artem S. Tashkinov: + +https://bugzilla.kernel.org/show_bug.cgi?id=214909 + +Signed-off-by: Andrew G. Morgan +--- + progs/setcap.c | 35 ++++++++++++++++++++++++++++++----- + 1 file changed, 30 insertions(+), 5 deletions(-) + +diff --git a/progs/setcap.c b/progs/setcap.c +index 442685d..fe985cd 100644 +--- a/progs/setcap.c ++++ b/progs/setcap.c +@@ -22,6 +22,35 @@ static void usage(void) + exit(1); + } + ++/* parse a positive integer with some error handling */ ++static unsigned long pos_uint(const char *text, const char *prefix, int *ok) ++{ ++ char *remains; ++ unsigned long value; ++ ssize_t len = strlen(text); ++ ++ if (len == 0 || *text == '-') { ++ goto fail; ++ } ++ value = strtoul(text, &remains, 0); ++ if (*remains || value == 0) { ++ goto fail; ++ } ++ if (ok != NULL) { ++ *ok = 1; ++ } ++ return value; ++ ++fail: ++ if (ok == NULL) { ++ fprintf(stderr, "%s: want positive integer, got \"%s\"\n", ++ prefix, text); ++ exit(1); ++ } ++ *ok = 0; ++ return 0; ++} ++ + #define MAXCAP 2048 + + static int read_caps(int quiet, const char *filename, char *buffer) +@@ -93,11 +122,7 @@ int main(int argc, char **argv) + exit(1); + } + --argc; +- rootid = (uid_t) atoi(*++argv); +- if (rootid+1 < 2) { +- fprintf(stderr, "invalid rootid!=0 of '%s'", *argv); +- exit(1); +- } ++ rootid = (uid_t) pos_uint(*++argv, "bad ns rootid", NULL); + continue; + } + +-- +1.8.3.1 + diff --git a/libcap.spec b/libcap.spec index 73d602be6e74b23f93a4238f2bda76fdf2ef7f4d..f636cb59cd0060f9e353638658fbb955fb7ab389 100644 --- a/libcap.spec +++ b/libcap.spec @@ -1,6 +1,6 @@ Name: libcap Version: 2.32 -Release: 2 +Release: 3 Summary: A library for getting and setting POSIX.1e draft 15 capabilities License: GPLv2 URL: https://sites.google.com/site/fullycapable @@ -8,6 +8,8 @@ Source0: https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/%{n Patch0: libcap-buildflags.patch Patch1: backport-Avoid-segfaulting-when-the-kernel-is-ahead-of-libcap.patch +Patch2: backport-capsh-better-error-handling-for-integer-parsing.patch +Patch3: backport-setcap-clean-up-error-handling-of-the-ns-rootid-argument.patch BuildRequires: libattr-devel pam-devel perl-interpreter gcc @@ -68,6 +70,13 @@ chmod +x %{buildroot}/%{_libdir}/*.so.* %{_mandir}/man8/*.gz %changelog +* Mon Nov 8 2021 yixiangzhike - 2.32-3 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC: capsh better error handling for integer parsing + setcap clean up error handling of the ns rootid argument + * Wed Aug 11 2021 panxiaohe - 2.32-2 - Type:bugfix - ID:NA