Relax integer limits in argument handling of native Zygote loop
Previously, the picky version of atoi() would reject anything 7 digits
or more. We have many cases of 7-digit UID these days, so we need a
higher limit to make good use of native Zygote loop.
Relax this to allow parsing up to the integer type limit. This function
is only used for --setuid and --setgid parsing, and the corresponding
Java code also uses Integer.parseInt(). So we should end up having the
same limits as that (except that ours refuses to parse negative values).
Bug: 395628427
Test: manual; check absence of "forkRepeatedly terminated due to non-simple command" with Chrome
Change-Id: I621080d618a224460603d2318dd9984120c37cb4
diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
index e0cc055..c4259f4 100644
--- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
@@ -266,16 +266,24 @@
}
// Picky version of atoi(). No sign or unexpected characters allowed. Return -1 on failure.
static int digitsVal(char* start, char* end) {
+ constexpr int vmax = std::numeric_limits<int>::max();
int result = 0;
- if (end - start > 6) {
- return -1;
- }
for (char* dp = start; dp < end; ++dp) {
if (*dp < '0' || *dp > '9') {
- ALOGW("Argument failed integer format check");
+ ALOGW("Argument contains non-integer characters");
return -1;
}
- result = 10 * result + (*dp - '0');
+ int digit = *dp - '0';
+ if (result > vmax / 10) {
+ ALOGW("Argument exceeds int limit");
+ return -1;
+ }
+ result *= 10;
+ if (result > vmax - digit) {
+ ALOGW("Argument exceeds int limit");
+ return -1;
+ }
+ result += digit;
}
return result;
}