Check the numeric parameters

This commit is contained in:
yixiangzhike 2021-11-08 11:24:18 +08:00
parent 37f46db5ce
commit 75b499c5b7
3 changed files with 219 additions and 2 deletions

View File

@ -0,0 +1,141 @@
From 9c4997d6592e5daf046a6968ac83cf615c51fbe1 Mon Sep 17 00:00:00 2001
From: "Andrew G. Morgan" <morgan@kernel.org>
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 <morgan@kernel.org>
---
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

View File

@ -0,0 +1,70 @@
From 8e1e967bc8d99a3233d51f67f6b88620cdff78dc Mon Sep 17 00:00:00 2001
From: "Andrew G. Morgan" <morgan@kernel.org>
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 <morgan@kernel.org>
---
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

View File

@ -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: 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,7 +70,11 @@ chmod +x %{buildroot}/%{_libdir}/*.so.*
%{_mandir}/man8/*.gz
%changelog
* Mon Sep 07 2020 Roberto Sassu <roberto.sassu@huawei.com> - 2.27-2
* Mon Nov 8 2021 yixiangzhike <yixiangzhike007@163.com> - 2.32-3
- capsh better error handling for integer parsing
- setcap clean up error handling of the ns rootid argument
* Mon Sep 07 2020 Roberto Sassu <roberto.sassu@huawei.com> - 2.32-2
- add Avoid-segfaulting-when-the-kernel-is-ahead-of-libcap.patch
* Thu Apr 16 2020 zhangchenfeng<zhangchenfeng1@huawei.com> - 2.32-1