mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2025-08-17 18:40:43 -04:00
16.0: Import and verify picks
https://review.lineageos.org/q/topic:P_asb_2022-05 https://review.lineageos.org/q/topic:P_asb_2022-06 https://review.lineageos.org/q/topic:P_asb_2022-07 https://review.lineageos.org/q/topic:P_asb_2022-08 https://review.lineageos.org/q/topic:P_asb_2022-09 https://review.lineageos.org/q/topic:P_asb_2022-10 https://review.lineageos.org/q/topic:P_asb_2022-11 https://review.lineageos.org/q/topic:P_asb_2022-12 https://review.lineageos.org/q/topic:P_asb_2023-01 https://review.lineageos.org/q/topic:P_asb_2023-02 https://review.lineageos.org/q/topic:P_asb_2023-03 https://review.lineageos.org/q/topic:P_asb_2023-04 https://review.lineageos.org/q/topic:P_asb_2023-05 https://review.lineageos.org/q/topic:P_asb_2023-06 https://review.lineageos.org/q/topic:P_asb_2023-07 accounted for via manifest change: https://review.lineageos.org/c/LineageOS/android_external_freetype/+/361250 https://review.lineageos.org/q/topic:P_asb_2023-08 accounted for via manifest change: https://review.lineageos.org/c/LineageOS/android_external_freetype/+/364606 accounted for via patches: https://review.lineageos.org/c/LineageOS/android_system_ca-certificates/+/365328 https://review.lineageos.org/q/topic:P_asb_2023-09 https://review.lineageos.org/q/topic:P_asb_2023-10 https://review.lineageos.org/q/topic:P_asb_2023-11 accounted for via patches: https://review.lineageos.org/c/LineageOS/android_system_ca-certificates/+/374916 https://review.lineageos.org/q/topic:P_asb_2023-12 https://review.lineageos.org/q/topic:P_asb_2024-01 https://review.lineageos.org/q/topic:P_asb_2024-02 https://review.lineageos.org/q/topic:P_asb_2024-03 https://review.lineageos.org/q/topic:P_asb_2024-04 Signed-off-by: Tavi <tavi@divested.dev>
This commit is contained in:
parent
7162b237d3
commit
082bc48c32
271 changed files with 25987 additions and 42 deletions
45
Patches/LineageOS-16.0/android_external_aac/332775.patch
Normal file
45
Patches/LineageOS-16.0/android_external_aac/332775.patch
Normal file
|
@ -0,0 +1,45 @@
|
|||
From e40800a613eb89b5b4c701774c3cecc1c2b7dd6c Mon Sep 17 00:00:00 2001
|
||||
From: Fraunhofer IIS FDK <audio-fdk@iis.fraunhofer.de>
|
||||
Date: Tue, 5 Apr 2022 18:53:20 +0200
|
||||
Subject: [PATCH] Reject invalid out of band config in
|
||||
transportDec_OutOfBandConfig() and skip re-allocation.
|
||||
|
||||
Bug: 224314979
|
||||
Bug: 221734266
|
||||
Test: adb shell /data/fuzz/arm64/C2FuzzerAacDec/C2FuzzerAacDec /data/local/tmp/clusterfuzz-testcase-minimized-C2FuzzerAacDec-5461414938804224
|
||||
Test: adb shell /data/fuzz/arm64/C2FuzzerAacDec/C2FuzzerAacDec /data/local/tmp/clusterfuzz-testcase-minimized-C2FuzzerAacDec-5062403589275648
|
||||
|
||||
Change-Id: I64e7fe1b258be2f59c6d39c0b7b699fa881d79e6
|
||||
Merged-In: I64e7fe1b258be2f59c6d39c0b7b699fa881d79e6
|
||||
(cherry picked from commit eb07c22519d94e573f2a02947094acd2219dc07a)
|
||||
Merged-In: I64e7fe1b258be2f59c6d39c0b7b699fa881d79e6
|
||||
---
|
||||
libMpegTPDec/src/tpdec_lib.cpp | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp
|
||||
index 1d8b7b3..c2dc964 100644
|
||||
--- a/libMpegTPDec/src/tpdec_lib.cpp
|
||||
+++ b/libMpegTPDec/src/tpdec_lib.cpp
|
||||
@@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
+© Copyright 1995 - 2022 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||
Forschung e.V. All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@@ -351,6 +351,12 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp,
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ /* if an error is detected terminate config parsing to avoid that an invalid
|
||||
+ * config is accepted in the second pass */
|
||||
+ if (err != TRANSPORTDEC_OK) {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (err == TRANSPORTDEC_OK && fConfigFound) {
|
55
Patches/LineageOS-16.0/android_external_dtc/342096.patch
Normal file
55
Patches/LineageOS-16.0/android_external_dtc/342096.patch
Normal file
|
@ -0,0 +1,55 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andre Przywara <andre.przywara@arm.com>
|
||||
Date: Mon, 21 Sep 2020 17:52:50 +0100
|
||||
Subject: [PATCH] FROMGIT: libfdt: fdt_offset_ptr(): Fix comparison warnings
|
||||
|
||||
With -Wsign-compare, compilers warn about mismatching signedness in
|
||||
comparisons in fdt_offset_ptr().
|
||||
|
||||
This mostly stems from "offset" being passed in as a signed integer,
|
||||
even though the function would not really tolerate negative values.
|
||||
|
||||
Short of changing the prototype, check that offset is not negative, and
|
||||
use an unsigned type internally.
|
||||
|
||||
Bug: 230794395
|
||||
Test: manual - see bug
|
||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
||||
Message-Id: <20200921165303.9115-2-andre.przywara@arm.com>
|
||||
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Change-Id: I33c4ac27780d6bdd46c5504a839c0827c9c76bfc
|
||||
Merged-In: Idb30ae90e2b263d1dd2e931ef1d3662a23812120
|
||||
Merged-In: Ice02ecc84d6e9ab30773d039a54664b259979521
|
||||
(cherry picked from commit 35c4c2b27acf66c217865451eeecf09bc82dae66)
|
||||
Merged-In: I33c4ac27780d6bdd46c5504a839c0827c9c76bfc
|
||||
---
|
||||
libfdt/fdt.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libfdt/fdt.c b/libfdt/fdt.c
|
||||
index 22286a1..5baaed3 100644
|
||||
--- a/libfdt/fdt.c
|
||||
+++ b/libfdt/fdt.c
|
||||
@@ -76,15 +76,19 @@ int fdt_check_header(const void *fdt)
|
||||
|
||||
const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
|
||||
{
|
||||
- unsigned absoffset = offset + fdt_off_dt_struct(fdt);
|
||||
+ unsigned int uoffset = offset;
|
||||
+ unsigned int absoffset = offset + fdt_off_dt_struct(fdt);
|
||||
|
||||
- if ((absoffset < offset)
|
||||
+ if (offset < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if ((absoffset < uoffset)
|
||||
|| ((absoffset + len) < absoffset)
|
||||
|| (absoffset + len) > fdt_totalsize(fdt))
|
||||
return NULL;
|
||||
|
||||
if (fdt_version(fdt) >= 0x11)
|
||||
- if (((offset + len) < offset)
|
||||
+ if (((uoffset + len) < uoffset)
|
||||
|| ((offset + len) > fdt_size_dt_struct(fdt)))
|
||||
return NULL;
|
||||
|
49
Patches/LineageOS-16.0/android_external_dtc/344161.patch
Normal file
49
Patches/LineageOS-16.0/android_external_dtc/344161.patch
Normal file
|
@ -0,0 +1,49 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mike McTernan <mikemcternan@google.com>
|
||||
Date: Fri, 22 Jul 2022 11:44:33 +0100
|
||||
Subject: [PATCH] Fix integer wrap sanitisation.
|
||||
|
||||
Test: make check
|
||||
Bug: 239630493
|
||||
Bug: 242096164
|
||||
Change-Id: I232155e7f7a54271a6a3e3a7cd91ed6bbabc051f
|
||||
Merged-In: I232155e7f7a54271a6a3e3a7cd91ed6bbabc051f
|
||||
(cherry picked from commit 05dec6d1827dc7016cad11c4ddfe8f965bceddb7)
|
||||
(cherry picked from commit 61e10c9c53b170ff8a5612ba4ec79e51d58e5eb3)
|
||||
Merged-In: I232155e7f7a54271a6a3e3a7cd91ed6bbabc051f
|
||||
---
|
||||
libfdt/fdt.c | 14 ++++++++++----
|
||||
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libfdt/fdt.c b/libfdt/fdt.c
|
||||
index 5baaed3..ed7e947 100644
|
||||
--- a/libfdt/fdt.c
|
||||
+++ b/libfdt/fdt.c
|
||||
@@ -124,9 +124,15 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
|
||||
lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
|
||||
if (!lenp)
|
||||
return FDT_END; /* premature end */
|
||||
- /* skip-name offset, length and value */
|
||||
- offset += sizeof(struct fdt_property) - FDT_TAGSIZE
|
||||
- + fdt32_to_cpu(*lenp);
|
||||
+
|
||||
+ /* skip-name offset, length */
|
||||
+ offset += sizeof(struct fdt_property) - FDT_TAGSIZE;
|
||||
+
|
||||
+ if (!fdt_offset_ptr(fdt, offset, fdt32_to_cpu(*lenp)))
|
||||
+ return FDT_END; /* premature end */
|
||||
+
|
||||
+ /* skip value */
|
||||
+ offset += fdt32_to_cpu(*lenp);
|
||||
break;
|
||||
|
||||
case FDT_END:
|
||||
@@ -138,7 +144,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
|
||||
return FDT_END;
|
||||
}
|
||||
|
||||
- if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
|
||||
+ if (offset <= startoffset || !fdt_offset_ptr(fdt, startoffset, offset - startoffset))
|
||||
return FDT_END; /* premature end */
|
||||
|
||||
*nextoffset = FDT_TAGALIGN(offset);
|
41
Patches/LineageOS-16.0/android_external_dtc/345891.patch
Normal file
41
Patches/LineageOS-16.0/android_external_dtc/345891.patch
Normal file
|
@ -0,0 +1,41 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pierre-Cl=C3=A9ment=20Tosi?= <ptosi@google.com>
|
||||
Date: Tue, 13 Sep 2022 16:58:15 +0100
|
||||
Subject: [PATCH] libfdt: fdt_path_offset_namelen: Reject empty paths
|
||||
|
||||
Make empty paths result in FDT_ERR_BADPATH.
|
||||
|
||||
Per the specification (v0.4-rc4):
|
||||
|
||||
> The convention for specifying a device path is:
|
||||
> /node-name-1/node-name-2/node-name-N
|
||||
>
|
||||
> The path to the root node is /.
|
||||
>
|
||||
> A unit address may be omitted if the full path to the
|
||||
> node is unambiguous.
|
||||
|
||||
Bug: 246465319
|
||||
Test: libfdt_fuzzer # clusterfuzz/testcase-detail/4530863420604416
|
||||
Change-Id: I14ab0a074ab994c1f598243d2d5795d2cd9a853a
|
||||
(cherry picked from commit 3c28f3e3a1724c288d19f1b1a139cf57bfe1af33)
|
||||
(cherry picked from commit d10c84c4bc78e8ebd8c6ebf70126ad3cb0ba1c46)
|
||||
Merged-In: I14ab0a074ab994c1f598243d2d5795d2cd9a853a
|
||||
---
|
||||
libfdt/fdt_ro.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
|
||||
index 08de2cc..3b65f16 100644
|
||||
--- a/libfdt/fdt_ro.c
|
||||
+++ b/libfdt/fdt_ro.c
|
||||
@@ -188,6 +188,9 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)
|
||||
|
||||
FDT_CHECK_HEADER(fdt);
|
||||
|
||||
+ if (namelen < 1)
|
||||
+ return -FDT_ERR_BADPATH;
|
||||
+
|
||||
/* see if we have an alias */
|
||||
if (*path != '/') {
|
||||
const char *q = memchr(path, '/', end - p);
|
26
Patches/LineageOS-16.0/android_external_expat/338353.patch
Normal file
26
Patches/LineageOS-16.0/android_external_expat/338353.patch
Normal file
|
@ -0,0 +1,26 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sadaf Ebrahimi <sadafebrahimi@google.com>
|
||||
Date: Mon, 23 May 2022 22:34:43 +0000
|
||||
Subject: [PATCH] Prevent integer overflow in copyString
|
||||
|
||||
Bug: http://b/221384482
|
||||
Change-Id: Ibdcb5dc24ee8886a04c2e29bd6ddccf29ece73ad
|
||||
(cherry picked from commit e25c84037506951dfe74a5fae1627fe22bc0ebf4)
|
||||
Merged-In: Ibdcb5dc24ee8886a04c2e29bd6ddccf29ece73ad
|
||||
---
|
||||
lib/xmlparse.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/xmlparse.c b/lib/xmlparse.c
|
||||
index 90a237f3..67f661b5 100644
|
||||
--- a/lib/xmlparse.c
|
||||
+++ b/lib/xmlparse.c
|
||||
@@ -7175,7 +7175,7 @@ static XML_Char *
|
||||
copyString(const XML_Char *s,
|
||||
const XML_Memory_Handling_Suite *memsuite)
|
||||
{
|
||||
- int charsRequired = 0;
|
||||
+ size_t charsRequired = 0;
|
||||
XML_Char *result;
|
||||
|
||||
/* First determine how long the string is */
|
29
Patches/LineageOS-16.0/android_external_expat/338354.patch
Normal file
29
Patches/LineageOS-16.0/android_external_expat/338354.patch
Normal file
|
@ -0,0 +1,29 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sadaf Ebrahimi <sadafebrahimi@google.com>
|
||||
Date: Thu, 2 Jun 2022 19:32:22 +0000
|
||||
Subject: [PATCH] Prevent XML_GetBuffer signed integer overflow
|
||||
|
||||
Bug: http://b/221255869
|
||||
Change-Id: I38758fae8c71184f728f95e6073457cdb86bcc29
|
||||
(cherry picked from commit d6a09f1b7fb24dd03dc58e45062ad951a37ff8e3)
|
||||
Merged-In: I38758fae8c71184f728f95e6073457cdb86bcc29
|
||||
---
|
||||
lib/xmlparse.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/lib/xmlparse.c b/lib/xmlparse.c
|
||||
index 67f661b5..1d6e722d 100644
|
||||
--- a/lib/xmlparse.c
|
||||
+++ b/lib/xmlparse.c
|
||||
@@ -2040,6 +2040,11 @@ XML_GetBuffer(XML_Parser parser, int len)
|
||||
keep = (int)(parser->m_bufferPtr - parser->m_buffer);
|
||||
if (keep > XML_CONTEXT_BYTES)
|
||||
keep = XML_CONTEXT_BYTES;
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (keep > INT_MAX - neededSize) {
|
||||
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
|
||||
+ return NULL;
|
||||
+ }
|
||||
neededSize += keep;
|
||||
#endif /* defined XML_CONTEXT_BYTES */
|
||||
if (neededSize <= parser->m_bufferLim - parser->m_buffer) {
|
54
Patches/LineageOS-16.0/android_external_expat/338355.patch
Normal file
54
Patches/LineageOS-16.0/android_external_expat/338355.patch
Normal file
|
@ -0,0 +1,54 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sadaf Ebrahimi <sadafebrahimi@google.com>
|
||||
Date: Fri, 3 Jun 2022 03:40:21 +0000
|
||||
Subject: [PATCH] Prevent integer overflow in function doProlog
|
||||
|
||||
Bug: http://b/221256678
|
||||
Change-Id: I6fe381103f4eb287726d1ccb5bfec99db160ffe4
|
||||
(cherry picked from commit 257f1d3777240016d3ccd74a61cd7d0e0efcaae3)
|
||||
Merged-In: I6fe381103f4eb287726d1ccb5bfec99db160ffe4
|
||||
---
|
||||
lib/xmlparse.c | 20 +++++++++++++-------
|
||||
1 file changed, 13 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/lib/xmlparse.c b/lib/xmlparse.c
|
||||
index 1d6e722d..7d91ed2b 100644
|
||||
--- a/lib/xmlparse.c
|
||||
+++ b/lib/xmlparse.c
|
||||
@@ -5187,23 +5187,29 @@ doProlog(XML_Parser parser,
|
||||
if (dtd->in_eldecl) {
|
||||
ELEMENT_TYPE *el;
|
||||
const XML_Char *name;
|
||||
- int nameLen;
|
||||
- const char *nxt = (quant == XML_CQUANT_NONE
|
||||
- ? next
|
||||
- : next - enc->minBytesPerChar);
|
||||
+ size_t nameLen;
|
||||
+ const char *nxt
|
||||
+ = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
|
||||
int myindex = nextScaffoldPart(parser);
|
||||
if (myindex < 0)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
dtd->scaffold[myindex].type = XML_CTYPE_NAME;
|
||||
dtd->scaffold[myindex].quant = quant;
|
||||
el = getElementType(parser, enc, s, nxt);
|
||||
- if (!el)
|
||||
+ if (! el)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
name = el->name;
|
||||
dtd->scaffold[myindex].name = name;
|
||||
nameLen = 0;
|
||||
- for (; name[nameLen++]; );
|
||||
- dtd->contentStringLen += nameLen;
|
||||
+ for (; name[nameLen++];)
|
||||
+ ;
|
||||
+
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (nameLen > UINT_MAX - dtd->contentStringLen) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ dtd->contentStringLen += (unsigned)nameLen;
|
||||
if (parser->m_elementDeclHandler)
|
||||
handleDefault = XML_FALSE;
|
||||
}
|
247
Patches/LineageOS-16.0/android_external_expat/338356.patch
Normal file
247
Patches/LineageOS-16.0/android_external_expat/338356.patch
Normal file
|
@ -0,0 +1,247 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sadaf Ebrahimi <sadafebrahimi@google.com>
|
||||
Date: Wed, 15 Jun 2022 04:14:33 +0000
|
||||
Subject: [PATCH] Prevent more integer overflows
|
||||
|
||||
Bug: http://b/219942275
|
||||
Change-Id: I7489f59564e0053a4a46bb8c362f7c36ab0b3c9d
|
||||
Merged-In: Ic5c8087ee64e6faafcf013cef9536c042eb8a09d
|
||||
(cherry picked from commit 15a1f35dddde9c1a0a626972349a59642abd345a)
|
||||
Merged-In: I7489f59564e0053a4a46bb8c362f7c36ab0b3c9d
|
||||
---
|
||||
lib/xmlparse.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 150 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/xmlparse.c b/lib/xmlparse.c
|
||||
index 7d91ed2b..121b63f7 100644
|
||||
--- a/lib/xmlparse.c
|
||||
+++ b/lib/xmlparse.c
|
||||
@@ -3187,13 +3187,38 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
|
||||
|
||||
/* get the attributes from the tokenizer */
|
||||
n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
|
||||
+
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (n > INT_MAX - nDefaultAtts) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+
|
||||
if (n + nDefaultAtts > parser->m_attsSize) {
|
||||
int oldAttsSize = parser->m_attsSize;
|
||||
ATTRIBUTE *temp;
|
||||
#ifdef XML_ATTR_INFO
|
||||
XML_AttrInfo *temp2;
|
||||
#endif
|
||||
+
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE)
|
||||
+ || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+
|
||||
parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
|
||||
+
|
||||
+ /* Detect and prevent integer overflow.
|
||||
+ * The preprocessor guard addresses the "always false" warning
|
||||
+ * from -Wtype-limits on platforms where
|
||||
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
|
||||
+#if UINT_MAX >= SIZE_MAX
|
||||
+ if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) {
|
||||
+ parser->m_attsSize = oldAttsSize;
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE));
|
||||
if (temp == NULL) {
|
||||
parser->m_attsSize = oldAttsSize;
|
||||
@@ -3201,6 +3226,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
|
||||
}
|
||||
parser->m_atts = temp;
|
||||
#ifdef XML_ATTR_INFO
|
||||
+ /* Detect and prevent integer overflow.
|
||||
+ * The preprocessor guard addresses the "always false" warning
|
||||
+ * from -Wtype-limits on platforms where
|
||||
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
|
||||
+# if UINT_MAX >= SIZE_MAX
|
||||
+ if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) {
|
||||
+ parser->m_attsSize = oldAttsSize;
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+# endif
|
||||
+
|
||||
temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo));
|
||||
if (temp2 == NULL) {
|
||||
parser->m_attsSize = oldAttsSize;
|
||||
@@ -3509,9 +3545,31 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
|
||||
tagNamePtr->prefixLen = prefixLen;
|
||||
for (i = 0; localPart[i++];)
|
||||
; /* i includes null terminator */
|
||||
+
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (binding->uriLen > INT_MAX - prefixLen
|
||||
+ || i > INT_MAX - (binding->uriLen + prefixLen)) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+
|
||||
n = i + binding->uriLen + prefixLen;
|
||||
if (n > binding->uriAlloc) {
|
||||
TAG *p;
|
||||
+
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (n > INT_MAX - EXPAND_SPARE) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+ /* Detect and prevent integer overflow.
|
||||
+ * The preprocessor guard addresses the "always false" warning
|
||||
+ * from -Wtype-limits on platforms where
|
||||
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
|
||||
+#if UINT_MAX >= SIZE_MAX
|
||||
+ if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
|
||||
if (!uri)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
@@ -3612,6 +3670,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
|
||||
if (parser->m_freeBindingList) {
|
||||
b = parser->m_freeBindingList;
|
||||
if (len > b->uriAlloc) {
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (len > INT_MAX - EXPAND_SPARE) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ /* Detect and prevent integer overflow.
|
||||
+ * The preprocessor guard addresses the "always false" warning
|
||||
+ * from -Wtype-limits on platforms where
|
||||
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
|
||||
+#if UINT_MAX >= SIZE_MAX
|
||||
+ if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
XML_Char *temp = (XML_Char *)REALLOC(parser, b->uri,
|
||||
sizeof(XML_Char) * (len + EXPAND_SPARE));
|
||||
if (temp == NULL)
|
||||
@@ -3625,6 +3698,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
|
||||
b = (BINDING *)MALLOC(parser, sizeof(BINDING));
|
||||
if (!b)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
+
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (len > INT_MAX - EXPAND_SPARE) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+ /* Detect and prevent integer overflow.
|
||||
+ * The preprocessor guard addresses the "always false" warning
|
||||
+ * from -Wtype-limits on platforms where
|
||||
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
|
||||
+#if UINT_MAX >= SIZE_MAX
|
||||
+ if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
|
||||
+ return XML_ERROR_NO_MEMORY;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
|
||||
if (!b->uri) {
|
||||
FREE(parser, b);
|
||||
@@ -6025,7 +6113,24 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
|
||||
}
|
||||
else {
|
||||
DEFAULT_ATTRIBUTE *temp;
|
||||
+
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (type->allocDefaultAtts > INT_MAX / 2) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
int count = type->allocDefaultAtts * 2;
|
||||
+
|
||||
+ /* Detect and prevent integer overflow.
|
||||
+ * The preprocessor guard addresses the "always false" warning
|
||||
+ * from -Wtype-limits on platforms where
|
||||
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
|
||||
+#if UINT_MAX >= SIZE_MAX
|
||||
+ if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
temp = (DEFAULT_ATTRIBUTE *)
|
||||
REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
|
||||
if (temp == NULL)
|
||||
@@ -6700,8 +6805,20 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
|
||||
/* check for overflow (table is half full) */
|
||||
if (table->used >> (table->power - 1)) {
|
||||
unsigned char newPower = table->power + 1;
|
||||
+
|
||||
+ /* Detect and prevent invalid shift */
|
||||
+ if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
size_t newSize = (size_t)1 << newPower;
|
||||
unsigned long newMask = (unsigned long)newSize - 1;
|
||||
+
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (newSize > (size_t)(-1) / sizeof(NAMED *)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
size_t tsize = newSize * sizeof(NAMED *);
|
||||
NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
|
||||
if (!newV)
|
||||
@@ -7067,6 +7184,20 @@ nextScaffoldPart(XML_Parser parser)
|
||||
if (dtd->scaffCount >= dtd->scaffSize) {
|
||||
CONTENT_SCAFFOLD *temp;
|
||||
if (dtd->scaffold) {
|
||||
+ /* Detect and prevent integer overflow */
|
||||
+ if (dtd->scaffSize > UINT_MAX / 2u) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ /* Detect and prevent integer overflow.
|
||||
+ * The preprocessor guard addresses the "always false" warning
|
||||
+ * from -Wtype-limits on platforms where
|
||||
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
|
||||
+#if UINT_MAX >= SIZE_MAX
|
||||
+ if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
temp = (CONTENT_SCAFFOLD *)
|
||||
REALLOC(parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
|
||||
if (temp == NULL)
|
||||
@@ -7143,9 +7274,26 @@ build_model (XML_Parser parser)
|
||||
XML_Content *ret;
|
||||
XML_Content *cpos;
|
||||
XML_Char * str;
|
||||
- int allocsize = (dtd->scaffCount * sizeof(XML_Content)
|
||||
- + (dtd->contentStringLen * sizeof(XML_Char)));
|
||||
|
||||
+ /* Detect and prevent integer overflow.
|
||||
+ * The preprocessor guard addresses the "always false" warning
|
||||
+ * from -Wtype-limits on platforms where
|
||||
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
|
||||
+#if UINT_MAX >= SIZE_MAX
|
||||
+ if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+#endif
|
||||
+ if (dtd->scaffCount * sizeof(XML_Content)
|
||||
+ > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content)
|
||||
+ + (dtd->contentStringLen * sizeof(XML_Char)));
|
||||
ret = (XML_Content *)MALLOC(parser, allocsize);
|
||||
if (!ret)
|
||||
return NULL;
|
35
Patches/LineageOS-16.0/android_external_expat/349328.patch
Normal file
35
Patches/LineageOS-16.0/android_external_expat/349328.patch
Normal file
|
@ -0,0 +1,35 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sadaf Ebrahimi <sadafebrahimi@google.com>
|
||||
Date: Wed, 16 Nov 2022 16:31:05 +0000
|
||||
Subject: [PATCH] Fix overeager DTD destruction (fixes #649)
|
||||
|
||||
Bug: http://b/255449293
|
||||
Test: TreeHugger
|
||||
Change-Id: I15ba529c07a6b868484bd5972be154c07cd97cc6
|
||||
(cherry picked from commit eb8f10fb1f4eb13c5a2ba1edbfd64b5f2a50ff4a)
|
||||
Merged-In: I15ba529c07a6b868484bd5972be154c07cd97cc6
|
||||
---
|
||||
lib/xmlparse.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/xmlparse.c b/lib/xmlparse.c
|
||||
index 121b63f7..90089ab7 100644
|
||||
--- a/lib/xmlparse.c
|
||||
+++ b/lib/xmlparse.c
|
||||
@@ -1013,7 +1013,15 @@ parserCreate(const XML_Char *encodingName,
|
||||
poolInit(&parser->m_temp2Pool, &(parser->m_mem));
|
||||
parserInit(parser, encodingName);
|
||||
|
||||
- if (encodingName && !parser->m_protocolEncodingName) {
|
||||
+ if (encodingName && ! parser->m_protocolEncodingName) {
|
||||
+ if (dtd) {
|
||||
+ // We need to stop the upcoming call to XML_ParserFree from happily
|
||||
+ // destroying parser->m_dtd because the DTD is shared with the parent
|
||||
+ // parser and the only guard that keeps XML_ParserFree from destroying
|
||||
+ // parser->m_dtd is parser->m_isParamEntity but it will be set to
|
||||
+ // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all).
|
||||
+ parser->m_dtd = NULL;
|
||||
+ }
|
||||
XML_ParserFree(parser);
|
||||
return NULL;
|
||||
}
|
38
Patches/LineageOS-16.0/android_external_zlib/351909.patch
Normal file
38
Patches/LineageOS-16.0/android_external_zlib/351909.patch
Normal file
|
@ -0,0 +1,38 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sadaf Ebrahimi <sadafebrahimi@google.com>
|
||||
Date: Tue, 22 Nov 2022 22:00:13 +0000
|
||||
Subject: [PATCH] Fix a bug when getting a gzip header extra field with
|
||||
inflate().
|
||||
|
||||
If the extra field was larger than the space the user provided with
|
||||
inflateGetHeader(), and if multiple calls of inflate() delivered
|
||||
the extra header data, then there could be a buffer overflow of the
|
||||
provided space. This commit assures that provided space is not
|
||||
exceeded.
|
||||
|
||||
Bug: http://b/242299736
|
||||
Test: TreeHugger
|
||||
|
||||
Change-Id: I4eabb3e135c1568e06b2b9740651a3ae11b21140
|
||||
(cherry picked from commit 1c4806afd7ae034aa9f86df35d4341a0b175a90a)
|
||||
Merged-In: I4eabb3e135c1568e06b2b9740651a3ae11b21140
|
||||
---
|
||||
src/inflate.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/inflate.c b/src/inflate.c
|
||||
index ac333e8..cd01857 100644
|
||||
--- a/src/inflate.c
|
||||
+++ b/src/inflate.c
|
||||
@@ -759,8 +759,9 @@ int flush;
|
||||
if (copy > have) copy = have;
|
||||
if (copy) {
|
||||
if (state->head != Z_NULL &&
|
||||
- state->head->extra != Z_NULL) {
|
||||
- len = state->head->extra_len - state->length;
|
||||
+ state->head->extra != Z_NULL &&
|
||||
+ (len = state->head->extra_len - state->length) <
|
||||
+ state->head->extra_max) {
|
||||
zmemcpy(state->head->extra + len, next,
|
||||
len + copy > state->head->extra_max ?
|
||||
state->head->extra_max - len : copy);
|
67
Patches/LineageOS-16.0/android_frameworks_av/344167.patch
Normal file
67
Patches/LineageOS-16.0/android_frameworks_av/344167.patch
Normal file
|
@ -0,0 +1,67 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Edwin Wong <edwinwong@google.com>
|
||||
Date: Tue, 21 Jun 2022 01:36:43 +0000
|
||||
Subject: [PATCH] RESTRICT AUTOMERGE - [Fix vulnerability] setSecurityLevel in
|
||||
clearkey
|
||||
|
||||
Potential race condition in clearkey setSecurityLevel.
|
||||
|
||||
POC test in http://go/ag/19083795
|
||||
|
||||
Test: sts-tradefed run sts-dynamic-develop -m StsHostTestCases -t android.security.sts.CVE_2022_2209#testPocCVE_2022_2209
|
||||
|
||||
Bug: 235601882
|
||||
Change-Id: I6447fb539ef0cb395772c61e6f3e1504ccde331b
|
||||
(cherry picked from commit dab37c25e3337387809fd35c7cd46abf76088b83)
|
||||
Merged-In: I6447fb539ef0cb395772c61e6f3e1504ccde331b
|
||||
---
|
||||
drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp | 2 ++
|
||||
drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h | 8 +++++++-
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
|
||||
index 0737851acc..923e4d500e 100644
|
||||
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
|
||||
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
|
||||
@@ -381,6 +381,7 @@ Return<void> DrmPlugin::getSecurityLevel(const hidl_vec<uint8_t>& sessionId,
|
||||
return Void();
|
||||
}
|
||||
|
||||
+ Mutex::Autolock lock(mSecurityLevelLock);
|
||||
std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr =
|
||||
mSecurityLevel.find(sid);
|
||||
if (itr == mSecurityLevel.end()) {
|
||||
@@ -411,6 +412,7 @@ Return<Status> DrmPlugin::setSecurityLevel(const hidl_vec<uint8_t>& sessionId,
|
||||
return Status::ERROR_DRM_SESSION_NOT_OPENED;
|
||||
}
|
||||
|
||||
+ Mutex::Autolock lock(mSecurityLevelLock);
|
||||
std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr =
|
||||
mSecurityLevel.find(sid);
|
||||
if (itr != mSecurityLevel.end()) {
|
||||
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
|
||||
index 7d9650f4bf..5360623aef 100644
|
||||
--- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
|
||||
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
|
||||
@@ -323,7 +323,8 @@ private:
|
||||
std::vector<KeyValue> mPlayPolicy;
|
||||
std::map<std::string, std::string> mStringProperties;
|
||||
std::map<std::string, std::vector<uint8_t> > mByteArrayProperties;
|
||||
- std::map<std::vector<uint8_t>, SecurityLevel> mSecurityLevel;
|
||||
+ std::map<std::vector<uint8_t>, SecurityLevel> mSecurityLevel
|
||||
+ GUARDED_BY(mSecurityLevelLock);
|
||||
sp<IDrmPluginListener> mListener;
|
||||
SessionLibrary *mSessionLibrary;
|
||||
int64_t mOpenSessionOkCount;
|
||||
@@ -332,6 +333,11 @@ private:
|
||||
uint32_t mNextSecureStopId;
|
||||
android::Mutex mPlayPolicyLock;
|
||||
|
||||
+ DeviceFiles mFileHandle GUARDED_BY(mFileHandleLock);
|
||||
+ Mutex mFileHandleLock;
|
||||
+ Mutex mSecureStopLock;
|
||||
+ Mutex mSecurityLevelLock;
|
||||
+
|
||||
CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin);
|
||||
};
|
||||
|
242
Patches/LineageOS-16.0/android_frameworks_av/349329.patch
Normal file
242
Patches/LineageOS-16.0/android_frameworks_av/349329.patch
Normal file
|
@ -0,0 +1,242 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Essick <essick@google.com>
|
||||
Date: Thu, 1 Dec 2022 21:02:09 -0600
|
||||
Subject: [PATCH] move MediaCodec metrics processing to looper thread
|
||||
|
||||
consolidate to avoid concurrency/mutex problems.
|
||||
|
||||
Bug: 256087846
|
||||
Bug: 245860753
|
||||
Test: atest CtsMediaV2TestCases
|
||||
Test: atest CtsMediaCodecTestCases
|
||||
Merged-In: Ie77f0028cab8091edd97d3a60ad4c80da3092cfe
|
||||
Merged-In: I56eceb6b12ce14348d3f9f2944968e70c6086aa8
|
||||
Merged-In: I94b0a2ac029dc0b90a93e9ed844768e9da5259b9
|
||||
Merged-In: I739248436a4801a4b9a96395f481640f2956cedf
|
||||
Change-Id: If5269d3efcd7c262020e580fe84fe89261a1af60
|
||||
(cherry picked from commit 0ccdce19f669cd628ab6d116c131efc8d15707ee)
|
||||
Merged-In: If5269d3efcd7c262020e580fe84fe89261a1af60
|
||||
---
|
||||
media/libstagefright/MediaCodec.cpp | 102 ++++++++++++++----
|
||||
.../include/media/stagefright/MediaCodec.h | 3 +
|
||||
2 files changed, 86 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
|
||||
index 353e40702f..cd1d24b06b 100644
|
||||
--- a/media/libstagefright/MediaCodec.cpp
|
||||
+++ b/media/libstagefright/MediaCodec.cpp
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <media/IResourceManagerService.h>
|
||||
#include <media/MediaCodecBuffer.h>
|
||||
#include <media/MediaAnalyticsItem.h>
|
||||
+// RBE do i need to add this? #include <media/MediaMetrics.h> // RBE
|
||||
#include <media/stagefright/foundation/ABuffer.h>
|
||||
#include <media/stagefright/foundation/ADebug.h>
|
||||
#include <media/stagefright/foundation/AMessage.h>
|
||||
@@ -546,6 +547,14 @@ MediaCodec::~MediaCodec() {
|
||||
mResourceManagerService->removeResource(getId(mResourceManagerClient));
|
||||
|
||||
flushAnalyticsItem();
|
||||
+
|
||||
+ // clean up any saved AnalyticsItem stored in the configuration message
|
||||
+ if (mConfigureMsg != nullptr) {
|
||||
+ MediaAnalyticsItem *oldItem = nullptr;
|
||||
+ if (mConfigureMsg->findPointer("metrics", (void**) &oldItem)) {
|
||||
+ delete oldItem;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
void MediaCodec::initAnalyticsItem() {
|
||||
@@ -570,6 +579,8 @@ void MediaCodec::updateAnalyticsItem() {
|
||||
return;
|
||||
}
|
||||
|
||||
+ Mutex::Autolock _lock(mMetricsLock);
|
||||
+
|
||||
if (mLatencyHist.getCount() != 0 ) {
|
||||
mAnalyticsItem->setInt64(kCodecLatencyMax, mLatencyHist.getMax());
|
||||
mAnalyticsItem->setInt64(kCodecLatencyMin, mLatencyHist.getMin());
|
||||
@@ -632,7 +643,10 @@ void MediaCodec::updateEphemeralAnalytics(MediaAnalyticsItem *item) {
|
||||
}
|
||||
|
||||
void MediaCodec::flushAnalyticsItem() {
|
||||
+ // update does its own mutex locking
|
||||
updateAnalyticsItem();
|
||||
+
|
||||
+ Mutex::Autolock _lock(mMetricsLock);
|
||||
if (mAnalyticsItem != NULL) {
|
||||
// don't log empty records
|
||||
if (mAnalyticsItem->count() > 0) {
|
||||
@@ -1018,16 +1032,22 @@ status_t MediaCodec::configure(
|
||||
uint32_t flags) {
|
||||
sp<AMessage> msg = new AMessage(kWhatConfigure, this);
|
||||
|
||||
- if (mAnalyticsItem != NULL) {
|
||||
+ MediaAnalyticsItem *newItem = new MediaAnalyticsItem(kCodecKeyName);
|
||||
+
|
||||
+ if (newItem != NULL) {
|
||||
int32_t profile = 0;
|
||||
if (format->findInt32("profile", &profile)) {
|
||||
- mAnalyticsItem->setInt32(kCodecProfile, profile);
|
||||
+ newItem->setInt32(kCodecProfile, profile);
|
||||
}
|
||||
int32_t level = 0;
|
||||
if (format->findInt32("level", &level)) {
|
||||
- mAnalyticsItem->setInt32(kCodecLevel, level);
|
||||
+ newItem->setInt32(kCodecLevel, level);
|
||||
}
|
||||
- mAnalyticsItem->setInt32(kCodecEncoder, (flags & CONFIGURE_FLAG_ENCODE) ? 1 : 0);
|
||||
+ newItem->setInt32(kCodecEncoder, (flags & CONFIGURE_FLAG_ENCODE) ? 1 : 0);
|
||||
+
|
||||
+ newItem->setCString(kCodecCodec, mInitName.c_str());
|
||||
+ newItem->setCString(kCodecMode, mIsVideo ? kCodecModeVideo : kCodecModeAudio);
|
||||
+
|
||||
}
|
||||
|
||||
if (mIsVideo) {
|
||||
@@ -1037,17 +1057,17 @@ status_t MediaCodec::configure(
|
||||
mRotationDegrees = 0;
|
||||
}
|
||||
|
||||
- if (mAnalyticsItem != NULL) {
|
||||
- mAnalyticsItem->setInt32(kCodecWidth, mVideoWidth);
|
||||
- mAnalyticsItem->setInt32(kCodecHeight, mVideoHeight);
|
||||
- mAnalyticsItem->setInt32(kCodecRotation, mRotationDegrees);
|
||||
+ if (newItem != NULL) {
|
||||
+ newItem->setInt32(kCodecWidth, mVideoWidth);
|
||||
+ newItem->setInt32(kCodecHeight, mVideoHeight);
|
||||
+ newItem->setInt32(kCodecRotation, mRotationDegrees);
|
||||
int32_t maxWidth = 0;
|
||||
if (format->findInt32("max-width", &maxWidth)) {
|
||||
- mAnalyticsItem->setInt32(kCodecMaxWidth, maxWidth);
|
||||
+ newItem->setInt32(kCodecMaxWidth, maxWidth);
|
||||
}
|
||||
int32_t maxHeight = 0;
|
||||
if (format->findInt32("max-height", &maxHeight)) {
|
||||
- mAnalyticsItem->setInt32(kCodecMaxHeight, maxHeight);
|
||||
+ newItem->setInt32(kCodecMaxHeight, maxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1075,6 +1095,15 @@ status_t MediaCodec::configure(
|
||||
ALOGW("Crypto or descrambler should be given for secure codec");
|
||||
}
|
||||
|
||||
+ // recover space of any previous saved baseline analytics info
|
||||
+ if (mConfigureMsg != nullptr) {
|
||||
+ MediaAnalyticsItem *oldItem = nullptr;
|
||||
+ if (mConfigureMsg->findPointer("metrics", (void **) &oldItem)) {
|
||||
+ delete oldItem;
|
||||
+ }
|
||||
+ }
|
||||
+ msg->setPointer("metrics", newItem);
|
||||
+
|
||||
// save msg for reset
|
||||
mConfigureMsg = msg;
|
||||
|
||||
@@ -1530,20 +1559,36 @@ status_t MediaCodec::getMetrics(MediaAnalyticsItem * &reply) {
|
||||
|
||||
reply = NULL;
|
||||
|
||||
- // shouldn't happen, but be safe
|
||||
- if (mAnalyticsItem == NULL) {
|
||||
- return UNKNOWN_ERROR;
|
||||
+ sp<AMessage> msg = new AMessage(kWhatGetMetrics, this);
|
||||
+ sp<AMessage> response;
|
||||
+ status_t err;
|
||||
+ if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
|
||||
+ return err;
|
||||
}
|
||||
|
||||
- // update any in-flight data that's not carried within the record
|
||||
- updateAnalyticsItem();
|
||||
+ CHECK(response->findPointer("metrics", (void **) &reply));
|
||||
|
||||
- // send it back to the caller.
|
||||
- reply = mAnalyticsItem->dup();
|
||||
+ return OK;
|
||||
+}
|
||||
|
||||
- updateEphemeralAnalytics(reply);
|
||||
+// runs on the looper thread (for mutex purposes)
|
||||
+void MediaCodec::onGetMetrics(const sp<AMessage>& msg) {
|
||||
|
||||
- return OK;
|
||||
+ MediaAnalyticsItem *results = nullptr;
|
||||
+
|
||||
+ sp<AReplyToken> replyID;
|
||||
+ CHECK(msg->senderAwaitsResponse(&replyID));
|
||||
+
|
||||
+ // RBE is it always non-null at this point?
|
||||
+ if (mAnalyticsItem != nullptr) {
|
||||
+ updateAnalyticsItem();
|
||||
+ results = mAnalyticsItem->dup();
|
||||
+ updateEphemeralAnalytics(results);
|
||||
+ }
|
||||
+
|
||||
+ sp<AMessage> response = new AMessage;
|
||||
+ response->setPointer("metrics", results);
|
||||
+ response->postReply(replyID);
|
||||
}
|
||||
|
||||
status_t MediaCodec::getInputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const {
|
||||
@@ -2381,6 +2426,13 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
|
||||
break;
|
||||
}
|
||||
|
||||
+ case kWhatGetMetrics:
|
||||
+ {
|
||||
+ onGetMetrics(msg);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
case kWhatConfigure:
|
||||
{
|
||||
sp<AReplyToken> replyID;
|
||||
@@ -2397,6 +2449,18 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
|
||||
sp<AMessage> format;
|
||||
CHECK(msg->findMessage("format", &format));
|
||||
|
||||
+ // start with a copy of the passed metrics info for use in this run
|
||||
+ MediaAnalyticsItem *handle;
|
||||
+ CHECK(msg->findPointer("metrics", (void **) &handle));
|
||||
+ if (handle != nullptr) {
|
||||
+ if (mAnalyticsItem != nullptr) {
|
||||
+ flushAnalyticsItem();
|
||||
+ }
|
||||
+ mAnalyticsItem = handle->dup();
|
||||
+ // and set some additional metrics values
|
||||
+ initAnalyticsItem();
|
||||
+ }
|
||||
+
|
||||
int32_t push;
|
||||
if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) {
|
||||
mFlags |= kFlagPushBlankBuffersOnShutdown;
|
||||
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
|
||||
index 7f6aae6281..b9f5c0b239 100644
|
||||
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
|
||||
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
|
||||
@@ -257,6 +257,7 @@ private:
|
||||
kWhatSetCallback = 'setC',
|
||||
kWhatSetNotification = 'setN',
|
||||
kWhatDrmReleaseCrypto = 'rDrm',
|
||||
+ kWhatGetMetrics = 'getM',
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -320,11 +321,13 @@ private:
|
||||
sp<Surface> mSurface;
|
||||
SoftwareRenderer *mSoftRenderer;
|
||||
|
||||
+ Mutex mMetricsLock;
|
||||
MediaAnalyticsItem *mAnalyticsItem;
|
||||
void initAnalyticsItem();
|
||||
void updateAnalyticsItem();
|
||||
void flushAnalyticsItem();
|
||||
void updateEphemeralAnalytics(MediaAnalyticsItem *item);
|
||||
+ void onGetMetrics(const sp<AMessage>& msg);
|
||||
|
||||
sp<AMessage> mOutputFormat;
|
||||
sp<AMessage> mInputFormat;
|
75
Patches/LineageOS-16.0/android_frameworks_av/359729.patch
Normal file
75
Patches/LineageOS-16.0/android_frameworks_av/359729.patch
Normal file
|
@ -0,0 +1,75 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Essick <essick@google.com>
|
||||
Date: Mon, 27 Mar 2023 18:16:46 -0500
|
||||
Subject: [PATCH] Fix NuMediaExtractor::readSampleData buffer Handling
|
||||
|
||||
readSampleData() did not initialize buffer before filling it,
|
||||
leading to OOB memory references. Correct and clarify the book
|
||||
keeping around output buffer management.
|
||||
|
||||
Bug: 275418191
|
||||
Test: CtsMediaExtractorTestCases w/debug messages
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:943fc12219b21d2a98f0ddc070b9b316a6f5d412)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:84c69bca81175feb2fd97ebb22e432ee41572786)
|
||||
Merged-In: Ie744f118526f100d82a312c64f7c6fcf20773b6d
|
||||
Change-Id: Ie744f118526f100d82a312c64f7c6fcf20773b6d
|
||||
---
|
||||
media/libstagefright/NuMediaExtractor.cpp | 14 +++++++++-----
|
||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
|
||||
index 4a7d6ca7ad..90ddcb81c3 100644
|
||||
--- a/media/libstagefright/NuMediaExtractor.cpp
|
||||
+++ b/media/libstagefright/NuMediaExtractor.cpp
|
||||
@@ -607,9 +607,11 @@ status_t NuMediaExtractor::appendVorbisNumPageSamples(
|
||||
numPageSamples = -1;
|
||||
}
|
||||
|
||||
+ // insert, including accounting for the space used.
|
||||
memcpy((uint8_t *)buffer->data() + mbuf->range_length(),
|
||||
&numPageSamples,
|
||||
sizeof(numPageSamples));
|
||||
+ buffer->setRange(buffer->offset(), buffer->size() + sizeof(numPageSamples));
|
||||
|
||||
uint32_t type;
|
||||
const void *data;
|
||||
@@ -658,6 +660,8 @@ status_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
|
||||
|
||||
ssize_t minIndex = fetchAllTrackSamples();
|
||||
|
||||
+ buffer->setRange(0, 0); // start with an empty buffer
|
||||
+
|
||||
if (minIndex < 0) {
|
||||
return ERROR_END_OF_STREAM;
|
||||
}
|
||||
@@ -673,25 +677,25 @@ status_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
|
||||
sampleSize += sizeof(int32_t);
|
||||
}
|
||||
|
||||
+ // capacity() is ok since we cleared out the buffer
|
||||
if (buffer->capacity() < sampleSize) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+ const size_t srclen = it->mBuffer->range_length();
|
||||
const uint8_t *src =
|
||||
(const uint8_t *)it->mBuffer->data()
|
||||
+ it->mBuffer->range_offset();
|
||||
|
||||
- memcpy((uint8_t *)buffer->data(), src, it->mBuffer->range_length());
|
||||
+ memcpy((uint8_t *)buffer->data(), src, srclen);
|
||||
+ buffer->setRange(0, srclen);
|
||||
|
||||
status_t err = OK;
|
||||
if (info->mTrackFlags & kIsVorbis) {
|
||||
+ // adjusts range when it inserts the extra bits
|
||||
err = appendVorbisNumPageSamples(it->mBuffer, buffer);
|
||||
}
|
||||
|
||||
- if (err == OK) {
|
||||
- buffer->setRange(0, sampleSize);
|
||||
- }
|
||||
-
|
||||
return err;
|
||||
}
|
||||
|
32
Patches/LineageOS-16.0/android_frameworks_av/366126.patch
Normal file
32
Patches/LineageOS-16.0/android_frameworks_av/366126.patch
Normal file
|
@ -0,0 +1,32 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shruti Bihani <shrutibihani@google.com>
|
||||
Date: Thu, 6 Jul 2023 08:41:56 +0000
|
||||
Subject: [PATCH] Fix Segv on unknown address error flagged by fuzzer test.
|
||||
|
||||
The error is thrown when the destructor tries to free pointer memory.
|
||||
This is happening for cases where the pointer was not initialized. Initializing it to a default value fixes the error.
|
||||
|
||||
Bug: 245135112
|
||||
Test: Build mtp_host_property_fuzzer and run on the target device
|
||||
(cherry picked from commit 3afa6e80e8568fe63f893fa354bc79ef91d3dcc0)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d44311374e41a26b28db56794c9a7890a13a6972)
|
||||
Merged-In: I255cd68b7641e96ac47ab81479b9b46b78c15580
|
||||
Change-Id: I255cd68b7641e96ac47ab81479b9b46b78c15580
|
||||
---
|
||||
media/mtp/MtpProperty.h | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h
|
||||
index bfd5f7f59a..1eb8874af1 100644
|
||||
--- a/media/mtp/MtpProperty.h
|
||||
+++ b/media/mtp/MtpProperty.h
|
||||
@@ -26,6 +26,9 @@ namespace android {
|
||||
class MtpDataPacket;
|
||||
|
||||
struct MtpPropertyValue {
|
||||
+ // pointer str initialized to NULL so that free operation
|
||||
+ // is not called for pre-assigned value
|
||||
+ MtpPropertyValue() : str (NULL) {}
|
||||
union {
|
||||
int8_t i8;
|
||||
uint8_t u8;
|
79
Patches/LineageOS-16.0/android_frameworks_av/374924.patch
Normal file
79
Patches/LineageOS-16.0/android_frameworks_av/374924.patch
Normal file
|
@ -0,0 +1,79 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shruti Bihani <shrutibihani@google.com>
|
||||
Date: Mon, 10 Jul 2023 08:53:42 +0000
|
||||
Subject: [PATCH] Fix for heap buffer overflow issue flagged by fuzzer test.
|
||||
|
||||
OOB write occurs when a value is assigned to a buffer index which is greater than the buffer size. Adding a check on buffer bounds fixes the issue.
|
||||
|
||||
Similar checks have been added wherever applicable on other such methods of the class.
|
||||
|
||||
Bug: 243463593
|
||||
Test: Build mtp_packet_fuzzer and run on the target device
|
||||
(cherry picked from commit a669e34bb8e6f0f7b5d7a35144bd342271a24712)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:1401a723899766632363129265b30d433ac69c44)
|
||||
Merged-In: Icd0f2307803a1a35e655bc08d9d4cca5e2b58a9b
|
||||
Change-Id: Icd0f2307803a1a35e655bc08d9d4cca5e2b58a9b
|
||||
---
|
||||
media/mtp/MtpPacket.cpp | 40 +++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 31 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp
|
||||
index 3dd4248e4c..917967cf17 100644
|
||||
--- a/media/mtp/MtpPacket.cpp
|
||||
+++ b/media/mtp/MtpPacket.cpp
|
||||
@@ -92,24 +92,46 @@ void MtpPacket::copyFrom(const MtpPacket& src) {
|
||||
}
|
||||
|
||||
uint16_t MtpPacket::getUInt16(int offset) const {
|
||||
- return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
|
||||
+ if ((unsigned long)(offset+2) <= mBufferSize) {
|
||||
+ return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
|
||||
+ }
|
||||
+ else {
|
||||
+ ALOGE("offset for buffer read is greater than buffer size!");
|
||||
+ abort();
|
||||
+ }
|
||||
}
|
||||
|
||||
uint32_t MtpPacket::getUInt32(int offset) const {
|
||||
- return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
|
||||
- ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset];
|
||||
+ if ((unsigned long)(offset+4) <= mBufferSize) {
|
||||
+ return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
|
||||
+ ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset];
|
||||
+ }
|
||||
+ else {
|
||||
+ ALOGE("offset for buffer read is greater than buffer size!");
|
||||
+ abort();
|
||||
+ }
|
||||
}
|
||||
|
||||
void MtpPacket::putUInt16(int offset, uint16_t value) {
|
||||
- mBuffer[offset++] = (uint8_t)(value & 0xFF);
|
||||
- mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
|
||||
+ if ((unsigned long)(offset+2) <= mBufferSize) {
|
||||
+ mBuffer[offset++] = (uint8_t)(value & 0xFF);
|
||||
+ mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
|
||||
+ }
|
||||
+ else {
|
||||
+ ALOGE("offset for buffer write is greater than buffer size!");
|
||||
+ }
|
||||
}
|
||||
|
||||
void MtpPacket::putUInt32(int offset, uint32_t value) {
|
||||
- mBuffer[offset++] = (uint8_t)(value & 0xFF);
|
||||
- mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
|
||||
- mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
|
||||
- mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
|
||||
+ if ((unsigned long)(offset+4) <= mBufferSize) {
|
||||
+ mBuffer[offset++] = (uint8_t)(value & 0xFF);
|
||||
+ mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
|
||||
+ mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
|
||||
+ mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
|
||||
+ }
|
||||
+ else {
|
||||
+ ALOGE("offset for buffer write is greater than buffer size!");
|
||||
+ }
|
||||
}
|
||||
|
||||
uint16_t MtpPacket::getContainerCode() const {
|
106
Patches/LineageOS-16.0/android_frameworks_av/377765.patch
Normal file
106
Patches/LineageOS-16.0/android_frameworks_av/377765.patch
Normal file
|
@ -0,0 +1,106 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Toni Heidenreich <tonihei@google.com>
|
||||
Date: Wed, 6 Sep 2023 12:49:33 +0000
|
||||
Subject: [PATCH] httplive: fix use-after-free
|
||||
|
||||
Implement a mutex to ensure secure multi-threaded
|
||||
access to the KeyedVector in MetaDataBase.
|
||||
Concurrent access by different threads can lead
|
||||
to accessing the wrong memory location due to
|
||||
potential changes in the vector
|
||||
|
||||
Bug: 298057702
|
||||
Test: HTTP Live Streaming test
|
||||
(cherry picked from https://partner-android-review.googlesource.com/q/commit:a2dfb31957a9d5358d0219a0eda7dcb5b0fff5fe)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:90fb4ca425444429ada6ce0de1c13d35829bc196)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3c1d9613ef64e01d2e81c4aa44c90dcd8ca958b9)
|
||||
Merged-In: I46b05c85d9c39f4ce549efc160c08a0646c9fd0a
|
||||
Change-Id: I46b05c85d9c39f4ce549efc160c08a0646c9fd0a
|
||||
|
||||
Change-Id: Ibad99da2ee0d9259844c32f954e6db290043e45b
|
||||
---
|
||||
media/libmediaextractor/MetaDataBase.cpp | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/media/libmediaextractor/MetaDataBase.cpp b/media/libmediaextractor/MetaDataBase.cpp
|
||||
index bfea6f1537..a3c623e354 100644
|
||||
--- a/media/libmediaextractor/MetaDataBase.cpp
|
||||
+++ b/media/libmediaextractor/MetaDataBase.cpp
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include <mutex>
|
||||
+
|
||||
#include <media/stagefright/foundation/ADebug.h>
|
||||
#include <media/stagefright/foundation/AString.h>
|
||||
#include <media/stagefright/foundation/hexdump.h>
|
||||
@@ -75,6 +77,7 @@ struct MetaDataBase::Rect {
|
||||
|
||||
|
||||
struct MetaDataBase::MetaDataInternal {
|
||||
+ std::mutex mLock;
|
||||
KeyedVector<uint32_t, MetaDataBase::typed_data> mItems;
|
||||
};
|
||||
|
||||
@@ -99,10 +102,12 @@ MetaDataBase::~MetaDataBase() {
|
||||
}
|
||||
|
||||
void MetaDataBase::clear() {
|
||||
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
|
||||
mInternalData->mItems.clear();
|
||||
}
|
||||
|
||||
bool MetaDataBase::remove(uint32_t key) {
|
||||
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
|
||||
ssize_t i = mInternalData->mItems.indexOfKey(key);
|
||||
|
||||
if (i < 0) {
|
||||
@@ -249,6 +254,7 @@ bool MetaDataBase::setData(
|
||||
uint32_t key, uint32_t type, const void *data, size_t size) {
|
||||
bool overwrote_existing = true;
|
||||
|
||||
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
|
||||
ssize_t i = mInternalData->mItems.indexOfKey(key);
|
||||
if (i < 0) {
|
||||
typed_data item;
|
||||
@@ -266,6 +272,7 @@ bool MetaDataBase::setData(
|
||||
|
||||
bool MetaDataBase::findData(uint32_t key, uint32_t *type,
|
||||
const void **data, size_t *size) const {
|
||||
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
|
||||
ssize_t i = mInternalData->mItems.indexOfKey(key);
|
||||
|
||||
if (i < 0) {
|
||||
@@ -280,6 +287,7 @@ bool MetaDataBase::findData(uint32_t key, uint32_t *type,
|
||||
}
|
||||
|
||||
bool MetaDataBase::hasData(uint32_t key) const {
|
||||
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
|
||||
ssize_t i = mInternalData->mItems.indexOfKey(key);
|
||||
|
||||
if (i < 0) {
|
||||
@@ -426,6 +434,7 @@ static void MakeFourCCString(uint32_t x, char *s) {
|
||||
|
||||
String8 MetaDataBase::toString() const {
|
||||
String8 s;
|
||||
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
|
||||
for (int i = mInternalData->mItems.size(); --i >= 0;) {
|
||||
int32_t key = mInternalData->mItems.keyAt(i);
|
||||
char cc[5];
|
||||
@@ -440,6 +449,7 @@ String8 MetaDataBase::toString() const {
|
||||
}
|
||||
|
||||
void MetaDataBase::dumpToLog() const {
|
||||
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
|
||||
for (int i = mInternalData->mItems.size(); --i >= 0;) {
|
||||
int32_t key = mInternalData->mItems.keyAt(i);
|
||||
char cc[5];
|
||||
@@ -451,6 +461,7 @@ void MetaDataBase::dumpToLog() const {
|
||||
|
||||
status_t MetaDataBase::writeToParcel(Parcel &parcel) {
|
||||
status_t ret;
|
||||
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
|
||||
size_t numItems = mInternalData->mItems.size();
|
||||
ret = parcel.writeUint32(uint32_t(numItems));
|
||||
if (ret) {
|
31
Patches/LineageOS-16.0/android_frameworks_av/379788.patch
Normal file
31
Patches/LineageOS-16.0/android_frameworks_av/379788.patch
Normal file
|
@ -0,0 +1,31 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Songyue Han <songyueh@google.com>
|
||||
Date: Tue, 3 Oct 2023 22:40:14 +0000
|
||||
Subject: [PATCH] Fix convertYUV420Planar16ToY410 overflow issue for
|
||||
unsupported cropwidth.
|
||||
|
||||
Bug: 300476626
|
||||
Test: color_conversion_fuzzer
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:de2ad0fad97d6d97d1e01f0e8d8309536eb268b4)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:745ab99f7343bc236b88b9d63cd7b06ab192f9e9)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:aa8298ec8eb903e1e3dd915fa24f32e1aea1f76c)
|
||||
Merged-In: I8631426188af3c5f9b6c1ff6a0039254c252f733
|
||||
Change-Id: I8631426188af3c5f9b6c1ff6a0039254c252f733
|
||||
---
|
||||
media/libstagefright/colorconversion/ColorConverter.cpp | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp
|
||||
index a1873bc5c4..94356b0b0c 100644
|
||||
--- a/media/libstagefright/colorconversion/ColorConverter.cpp
|
||||
+++ b/media/libstagefright/colorconversion/ColorConverter.cpp
|
||||
@@ -592,7 +592,8 @@ status_t ColorConverter::convertYUV420Planar16ToY410(
|
||||
|
||||
uint32_t u01, v01, y01, y23, y45, y67, uv0, uv1;
|
||||
size_t x = 0;
|
||||
- for (; x < src.cropWidth() - 3; x += 4) {
|
||||
+ // x % 4 is always 0 so x + 3 will never overflow.
|
||||
+ for (; x + 3 < src.cropWidth(); x += 4) {
|
||||
u01 = *((uint32_t*)ptr_u); ptr_u += 2;
|
||||
v01 = *((uint32_t*)ptr_v); ptr_v += 2;
|
||||
|
35
Patches/LineageOS-16.0/android_frameworks_av/383562.patch
Normal file
35
Patches/LineageOS-16.0/android_frameworks_av/383562.patch
Normal file
|
@ -0,0 +1,35 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ashish Kumar Gupta <kumarashishg@google.com>
|
||||
Date: Tue, 21 Nov 2023 08:48:43 +0530
|
||||
Subject: [PATCH] Update mtp packet buffer
|
||||
|
||||
Currently, the buffer size is not changed when the packet size is increased. Ideally, the buffer size should be larger than the packet size. In our case, when the packet size is increased, we must reallocate the buffer of MTP packet.
|
||||
|
||||
Bug: 300007708
|
||||
Test: build and flash the device. Check MTP works
|
||||
Test: run fuzzer locally
|
||||
(cherry picked from commit e1494a2d8e7eee25d7ea5469be43740e97294c99)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5c0f99beb6fa5ff920caf5b0d06aaebc8e9eab24)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:edf60c63243903b9f27f58f4954c599470d011fd)
|
||||
Merged-In: I98398a9e15962e6d5f08445ee7b17f5d61a3a528
|
||||
Change-Id: I98398a9e15962e6d5f08445ee7b17f5d61a3a528
|
||||
---
|
||||
media/mtp/MtpPacket.cpp | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp
|
||||
index 917967cf17..d7567141d6 100644
|
||||
--- a/media/mtp/MtpPacket.cpp
|
||||
+++ b/media/mtp/MtpPacket.cpp
|
||||
@@ -168,8 +168,10 @@ void MtpPacket::setParameter(int index, uint32_t value) {
|
||||
return;
|
||||
}
|
||||
int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t);
|
||||
- if (mPacketSize < offset + sizeof(uint32_t))
|
||||
+ if (mPacketSize < offset + sizeof(uint32_t)) {
|
||||
mPacketSize = offset + sizeof(uint32_t);
|
||||
+ allocate(mPacketSize);
|
||||
+ }
|
||||
putUInt32(offset, value);
|
||||
}
|
||||
|
105
Patches/LineageOS-16.0/android_frameworks_av/385670.patch
Normal file
105
Patches/LineageOS-16.0/android_frameworks_av/385670.patch
Normal file
|
@ -0,0 +1,105 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Haripriya Deshmukh <haripriya.deshmukh@ittiam.com>
|
||||
Date: Tue, 19 Sep 2023 20:42:45 +0000
|
||||
Subject: [PATCH] Validate OMX Params for VPx encoders
|
||||
|
||||
Bug: 273936274
|
||||
Bug: 273937171
|
||||
Bug: 273937136
|
||||
Bug: 273936553
|
||||
Bug: 273936601
|
||||
Test: POC in bug descriptions
|
||||
(cherry picked from https://partner-android-review.googlesource.com/q/commit:022086b76536cd2e19a44053271190bdf6e181f7)
|
||||
(cherry picked from commit 0e4ca1cb5c16af8f1dfb0ae41941c16c104d38e8)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:90641b2799fd3940cdf0bf8a73b2f76839e651a6)
|
||||
Merged-In: I9bb17112d9f0217b6af0343afecc9c943453b757
|
||||
Change-Id: I9bb17112d9f0217b6af0343afecc9c943453b757
|
||||
---
|
||||
media/libstagefright/codecs/on2/enc/SoftVP8Encoder.cpp | 10 ++++++++++
|
||||
media/libstagefright/codecs/on2/enc/SoftVP9Encoder.cpp | 10 ++++++++++
|
||||
media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp | 9 +++++++++
|
||||
3 files changed, 29 insertions(+)
|
||||
|
||||
diff --git a/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.cpp
|
||||
index 04737a9ccf..9198b7c327 100644
|
||||
--- a/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.cpp
|
||||
+++ b/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.cpp
|
||||
@@ -120,6 +120,11 @@ OMX_ERRORTYPE SoftVP8Encoder::internalSetParameter(OMX_INDEXTYPE index,
|
||||
|
||||
OMX_ERRORTYPE SoftVP8Encoder::internalGetVp8Params(
|
||||
OMX_VIDEO_PARAM_VP8TYPE* vp8Params) {
|
||||
+ if (!isValidOMXParam(vp8Params)) {
|
||||
+ android_errorWriteLog(0x534e4554, "273936274");
|
||||
+ return OMX_ErrorBadParameter;
|
||||
+ }
|
||||
+
|
||||
if (vp8Params->nPortIndex != kOutputPortIndex) {
|
||||
return OMX_ErrorUnsupportedIndex;
|
||||
}
|
||||
@@ -133,6 +138,11 @@ OMX_ERRORTYPE SoftVP8Encoder::internalGetVp8Params(
|
||||
|
||||
OMX_ERRORTYPE SoftVP8Encoder::internalSetVp8Params(
|
||||
const OMX_VIDEO_PARAM_VP8TYPE* vp8Params) {
|
||||
+ if (!isValidOMXParam(vp8Params)) {
|
||||
+ android_errorWriteLog(0x534e4554, "273937171");
|
||||
+ return OMX_ErrorBadParameter;
|
||||
+ }
|
||||
+
|
||||
if (vp8Params->nPortIndex != kOutputPortIndex) {
|
||||
return OMX_ErrorUnsupportedIndex;
|
||||
}
|
||||
diff --git a/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.cpp
|
||||
index 1ea1c85f76..f8495c2da4 100644
|
||||
--- a/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.cpp
|
||||
+++ b/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.cpp
|
||||
@@ -119,6 +119,11 @@ OMX_ERRORTYPE SoftVP9Encoder::internalSetParameter(
|
||||
|
||||
OMX_ERRORTYPE SoftVP9Encoder::internalGetVp9Params(
|
||||
OMX_VIDEO_PARAM_VP9TYPE *vp9Params) {
|
||||
+ if (!isValidOMXParam(vp9Params)) {
|
||||
+ android_errorWriteLog(0x534e4554, "273936553");
|
||||
+ return OMX_ErrorBadParameter;
|
||||
+ }
|
||||
+
|
||||
if (vp9Params->nPortIndex != kOutputPortIndex) {
|
||||
return OMX_ErrorUnsupportedIndex;
|
||||
}
|
||||
@@ -133,6 +138,11 @@ OMX_ERRORTYPE SoftVP9Encoder::internalGetVp9Params(
|
||||
|
||||
OMX_ERRORTYPE SoftVP9Encoder::internalSetVp9Params(
|
||||
const OMX_VIDEO_PARAM_VP9TYPE *vp9Params) {
|
||||
+ if (!isValidOMXParam(vp9Params)) {
|
||||
+ android_errorWriteLog(0x534e4554, "273937136");
|
||||
+ return OMX_ErrorBadParameter;
|
||||
+ }
|
||||
+
|
||||
if (vp9Params->nPortIndex != kOutputPortIndex) {
|
||||
return OMX_ErrorUnsupportedIndex;
|
||||
}
|
||||
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
|
||||
index f6257b1556..173bbe37d6 100644
|
||||
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
|
||||
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
|
||||
@@ -484,6 +484,11 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetBitrateParams(
|
||||
|
||||
OMX_ERRORTYPE SoftVPXEncoder::internalGetAndroidVpxParams(
|
||||
OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vpxAndroidParams) {
|
||||
+ if (!isValidOMXParam(vpxAndroidParams)) {
|
||||
+ android_errorWriteLog(0x534e4554, "273936601");
|
||||
+ return OMX_ErrorBadParameter;
|
||||
+ }
|
||||
+
|
||||
if (vpxAndroidParams->nPortIndex != kOutputPortIndex) {
|
||||
return OMX_ErrorUnsupportedIndex;
|
||||
}
|
||||
@@ -500,6 +505,10 @@ OMX_ERRORTYPE SoftVPXEncoder::internalGetAndroidVpxParams(
|
||||
|
||||
OMX_ERRORTYPE SoftVPXEncoder::internalSetAndroidVpxParams(
|
||||
const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vpxAndroidParams) {
|
||||
+ if (!isValidOMXParam(vpxAndroidParams)) {
|
||||
+ android_errorWriteLog(0x534e4554, "273937551");
|
||||
+ return OMX_ErrorBadParameter;
|
||||
+ }
|
||||
if (vpxAndroidParams->nPortIndex != kOutputPortIndex) {
|
||||
return OMX_ErrorUnsupportedIndex;
|
||||
}
|
34
Patches/LineageOS-16.0/android_frameworks_av/385671.patch
Normal file
34
Patches/LineageOS-16.0/android_frameworks_av/385671.patch
Normal file
|
@ -0,0 +1,34 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Haripriya Deshmukh <haripriya.deshmukh@ittiam.com>
|
||||
Date: Tue, 5 Dec 2023 18:32:38 +0000
|
||||
Subject: [PATCH] Fix out of bounds read and write in onQueueFilled in outQueue
|
||||
|
||||
Bug: 276442130
|
||||
Test: POC in bug descriptions
|
||||
(cherry picked from https://partner-android-review.googlesource.com/q/commit:7aef41e59412e2f95bab5de7e33f5f04bb808643)
|
||||
(cherry picked from commit 8f4cfda9fc75f1e9ba3b6dee3fbffda4b6111d64)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:208e430bc6380fafafca8041b239f835263a9d47)
|
||||
Merged-In: Ic230d10048193a785f185dc6a7de6f455f9318c1
|
||||
Change-Id: Ic230d10048193a785f185dc6a7de6f455f9318c1
|
||||
---
|
||||
media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
|
||||
index fda70280a7..b78ac4325a 100644
|
||||
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
|
||||
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
|
||||
@@ -308,8 +308,11 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) {
|
||||
outHeader->nFilledLen = frameSize;
|
||||
|
||||
List<BufferInfo *>::iterator it = outQueue.begin();
|
||||
- while ((*it)->mHeader != outHeader) {
|
||||
- ++it;
|
||||
+ while (it != outQueue.end() && (*it)->mHeader != outHeader) {
|
||||
+ ++it;
|
||||
+ }
|
||||
+ if (it == outQueue.end()) {
|
||||
+ return;
|
||||
}
|
||||
|
||||
BufferInfo *outInfo = *it;
|
146
Patches/LineageOS-16.0/android_frameworks_base/330961.patch
Normal file
146
Patches/LineageOS-16.0/android_frameworks_base/330961.patch
Normal file
|
@ -0,0 +1,146 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Pietal <mpietal@google.com>
|
||||
Date: Fri, 1 Oct 2021 11:03:16 -0400
|
||||
Subject: [PATCH] Keyguard - Treat messsages to lock with priority
|
||||
|
||||
When switching users and attempting to lock the device, the sysui main
|
||||
thread becomes overwhelmed with events, creating a significant lag
|
||||
between the time a message is posted and processed on the main
|
||||
thread. This can be dangerous when these events are critical for
|
||||
security, such as calls coming from PhoneWindowManager#lockNow() that
|
||||
call KeyguardViewMediator#doKeyguardTimeout(). On older devices with
|
||||
slower CPUs and less memory, the delay in processing can be
|
||||
significant (15 - 30s).
|
||||
|
||||
The result of not prioritizing these events leads to a window of time
|
||||
where a guest user can switch back to the owner, and gain access to
|
||||
the owner's homescreen without needing to unlock the device with the
|
||||
owner's credentials.
|
||||
|
||||
As a mitigation, prioritize two events originating in two specific
|
||||
methods to make sure the device locks as soon as possible as well as
|
||||
have the system server preemptively update its local cache.
|
||||
|
||||
Bug: 151095871
|
||||
Test: Very manual race condition - follow steps listed in bug
|
||||
Change-Id: I7585a0a5eeb308e0e32a4f77f581556d883b5cda
|
||||
Merged-In: I7585a0a5eeb308e0e32a4f77f581556d883b5cda
|
||||
(cherry picked from commit 28c53ab8bca26af58b45625c1ebba8b9051c107d)
|
||||
(cherry picked from commit 563fdf4259d0e28fd960acbb63431e146707d11b)
|
||||
Merged-In: I7585a0a5eeb308e0e32a4f77f581556d883b5cda
|
||||
---
|
||||
.../internal/policy/IKeyguardStateCallback.aidl | 2 +-
|
||||
.../systemui/keyguard/KeyguardViewMediator.java | 16 +++++++++++-----
|
||||
.../policy/keyguard/KeyguardServiceWrapper.java | 6 ++++++
|
||||
.../policy/keyguard/KeyguardStateMonitor.java | 8 +++++++-
|
||||
4 files changed, 25 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
|
||||
index 8e454db4cb04..a8003a1169e9 100644
|
||||
--- a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
|
||||
+++ b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
|
||||
@@ -16,7 +16,7 @@
|
||||
package com.android.internal.policy;
|
||||
|
||||
interface IKeyguardStateCallback {
|
||||
- void onShowingStateChanged(boolean showing);
|
||||
+ void onShowingStateChanged(boolean showing, int userId);
|
||||
void onSimSecureStateChanged(boolean simSecure);
|
||||
void onInputRestrictedStateChanged(boolean inputRestricted);
|
||||
void onTrustedChanged(boolean trusted);
|
||||
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
|
||||
index 305370d5964b..bac481c8e478 100644
|
||||
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
|
||||
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
|
||||
@@ -1291,7 +1291,9 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
public void doKeyguardTimeout(Bundle options) {
|
||||
mHandler.removeMessages(KEYGUARD_TIMEOUT);
|
||||
Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT, options);
|
||||
- mHandler.sendMessage(msg);
|
||||
+ // Treat these messages with priority - A call to timeout means the device should lock
|
||||
+ // as soon as possible and not wait for other messages on the thread to process first.
|
||||
+ mHandler.sendMessageAtFrontOfQueue(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1488,12 +1490,15 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
* @see #handleShow
|
||||
*/
|
||||
private void showLocked(Bundle options) {
|
||||
- Trace.beginSection("KeyguardViewMediator#showLocked aqcuiring mShowKeyguardWakeLock");
|
||||
+ Trace.beginSection("KeyguardViewMediator#showLocked acquiring mShowKeyguardWakeLock");
|
||||
if (DEBUG) Log.d(TAG, "showLocked");
|
||||
// ensure we stay awake until we are finished displaying the keyguard
|
||||
mShowKeyguardWakeLock.acquire();
|
||||
Message msg = mHandler.obtainMessage(SHOW, options);
|
||||
- mHandler.sendMessage(msg);
|
||||
+ // Treat these messages with priority - This call can originate from #doKeyguardTimeout,
|
||||
+ // meaning the device should lock as soon as possible and not wait for other messages on
|
||||
+ // the thread to process first.
|
||||
+ mHandler.sendMessageAtFrontOfQueue(msg);
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
@@ -1652,6 +1657,7 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
case KEYGUARD_TIMEOUT:
|
||||
synchronized (KeyguardViewMediator.this) {
|
||||
doKeyguardLocked((Bundle) msg.obj);
|
||||
+ notifyDefaultDisplayCallbacks(mShowing);
|
||||
}
|
||||
break;
|
||||
case DISMISS:
|
||||
@@ -2213,7 +2219,7 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
for (int i = size - 1; i >= 0; i--) {
|
||||
IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i);
|
||||
try {
|
||||
- callback.onShowingStateChanged(showing);
|
||||
+ callback.onShowingStateChanged(showing, KeyguardUpdateMonitor.getCurrentUser());
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed to call onShowingStateChanged", e);
|
||||
if (e instanceof DeadObjectException) {
|
||||
@@ -2261,7 +2267,7 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
mKeyguardStateCallbacks.add(callback);
|
||||
try {
|
||||
callback.onSimSecureStateChanged(mUpdateMonitor.isSimPinSecure());
|
||||
- callback.onShowingStateChanged(mShowing);
|
||||
+ callback.onShowingStateChanged(mShowing, KeyguardUpdateMonitor.getCurrentUser());
|
||||
callback.onInputRestrictedStateChanged(mInputRestricted);
|
||||
callback.onTrustedChanged(mUpdateMonitor.getUserHasTrust(
|
||||
KeyguardUpdateMonitor.getCurrentUser()));
|
||||
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
|
||||
index 4e848686254a..cf5c587e0494 100644
|
||||
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
|
||||
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
|
||||
@@ -192,6 +192,12 @@ public class KeyguardServiceWrapper implements IKeyguardService {
|
||||
|
||||
@Override // Binder interface
|
||||
public void doKeyguardTimeout(Bundle options) {
|
||||
+ int userId = mKeyguardStateMonitor.getCurrentUser();
|
||||
+ if (mKeyguardStateMonitor.isSecure(userId)) {
|
||||
+ // Preemptively inform the cache that the keyguard will soon be showing, as calls to
|
||||
+ // doKeyguardTimeout are a signal to lock the device as soon as possible.
|
||||
+ mKeyguardStateMonitor.onShowingStateChanged(true, userId);
|
||||
+ }
|
||||
try {
|
||||
mService.doKeyguardTimeout(options);
|
||||
} catch (RemoteException e) {
|
||||
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
|
||||
index dbf96aa9eee6..c49c31d2ce07 100644
|
||||
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
|
||||
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
|
||||
@@ -92,8 +92,14 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
|
||||
return mHasLockscreenWallpaper;
|
||||
}
|
||||
|
||||
+ public int getCurrentUser() {
|
||||
+ return mCurrentUserId;
|
||||
+ }
|
||||
+
|
||||
@Override // Binder interface
|
||||
- public void onShowingStateChanged(boolean showing) {
|
||||
+ public void onShowingStateChanged(boolean showing, int userId) {
|
||||
+ if (userId != mCurrentUserId) return;
|
||||
+
|
||||
mIsShowing = showing;
|
||||
|
||||
mCallback.onShowingChanged();
|
38
Patches/LineageOS-16.0/android_frameworks_base/330962.patch
Normal file
38
Patches/LineageOS-16.0/android_frameworks_base/330962.patch
Normal file
|
@ -0,0 +1,38 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Pinyao Ting <pinyaoting@google.com>
|
||||
Date: Thu, 3 Mar 2022 18:24:37 +0000
|
||||
Subject: [PATCH] Verify caller before auto granting slice permission
|
||||
|
||||
Currently SliceManagerService#checkSlicePermission does not verify the
|
||||
caller's identity. This leads to a security vulnerability because
|
||||
checkSlicePermission does more than checking the permission as opposed
|
||||
to simply return a boolean value -- it additionally grants slice access
|
||||
under a certain condition. A malicious app can spoof the calling package
|
||||
to acquire slice access.
|
||||
|
||||
This CL verifies the caller before granting slice access.
|
||||
|
||||
Bug: 208232850, 179699767
|
||||
Test: manual
|
||||
Change-Id: I2539c9ff5ea977c91bb58185c95280b4d533a520
|
||||
Merged-In: I2539c9ff5ea977c91bb58185c95280b4d533a520
|
||||
(cherry picked from commit 5bd2196c537ae42a5c1626bdc23c3c6db41fb97f)
|
||||
(cherry picked from commit 3c92d74d7d74e1d781ae1b071da97b3b2cbc6be9)
|
||||
Merged-In: I2539c9ff5ea977c91bb58185c95280b4d533a520
|
||||
---
|
||||
.../core/java/com/android/server/slice/SliceManagerService.java | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
|
||||
index f5947ee35ea4..158e6a59ac48 100644
|
||||
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
|
||||
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
|
||||
@@ -239,6 +239,8 @@ public class SliceManagerService extends ISliceManager.Stub {
|
||||
if (autoGrantPermissions != null) {
|
||||
// Need to own the Uri to call in with permissions to grant.
|
||||
enforceOwner(pkg, uri, userId);
|
||||
+ // b/208232850: Needs to verify caller before granting slice access
|
||||
+ verifyCaller(pkg);
|
||||
for (String perm : autoGrantPermissions) {
|
||||
if (mContext.checkPermission(perm, pid, uid) == PERMISSION_GRANTED) {
|
||||
int providerUser = ContentProvider.getUserIdFromUri(uri, userId);
|
88
Patches/LineageOS-16.0/android_frameworks_base/330963.patch
Normal file
88
Patches/LineageOS-16.0/android_frameworks_base/330963.patch
Normal file
|
@ -0,0 +1,88 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Buynytskyy <alexbuy@google.com>
|
||||
Date: Thu, 24 Feb 2022 21:40:13 -0800
|
||||
Subject: [PATCH] Always restart apps if base.apk gets updated.
|
||||
|
||||
Bug: 219044664
|
||||
Fixes: 219044664
|
||||
Test: atest PackageManagerShellCommandTest
|
||||
Change-Id: I27a0c5009b2d5f1ea51618b9acfa1e6ccee71296
|
||||
Merged-In: I27a0c5009b2d5f1ea51618b9acfa1e6ccee71296
|
||||
(cherry picked from commit a5dd59db6d1889ae0aa95ef01bbf8c98e360a2f2)
|
||||
Merged-In: I27a0c5009b2d5f1ea51618b9acfa1e6ccee71296
|
||||
---
|
||||
.../android/content/pm/IPackageInstallerSession.aidl | 2 ++
|
||||
core/java/android/content/pm/PackageInstaller.java | 12 ++++++++++++
|
||||
.../android/server/pm/PackageInstallerSession.java | 11 +++++++++++
|
||||
3 files changed, 25 insertions(+)
|
||||
|
||||
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
|
||||
index 8fddb99b35a8..4d91bdf93f16 100644
|
||||
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
|
||||
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
|
||||
@@ -38,4 +38,6 @@ interface IPackageInstallerSession {
|
||||
void commit(in IntentSender statusReceiver, boolean forTransferred);
|
||||
void transfer(in String packageName);
|
||||
void abandon();
|
||||
+
|
||||
+ int getInstallFlags();
|
||||
}
|
||||
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
|
||||
index b51fa6fc2b29..0d7ca9043ccd 100644
|
||||
--- a/core/java/android/content/pm/PackageInstaller.java
|
||||
+++ b/core/java/android/content/pm/PackageInstaller.java
|
||||
@@ -1059,6 +1059,18 @@ public class PackageInstaller {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * @return Session's {@link SessionParams#installFlags}.
|
||||
+ * @hide
|
||||
+ */
|
||||
+ public int getInstallFlags() {
|
||||
+ try {
|
||||
+ return mSession.getInstallFlags();
|
||||
+ } catch (RemoteException e) {
|
||||
+ throw e.rethrowFromSystemServer();
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
|
||||
index edada326ee12..e6ec80ae1b76 100644
|
||||
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
|
||||
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
|
||||
@@ -83,6 +83,7 @@ import android.system.OsConstants;
|
||||
import android.system.StructStat;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
+import android.util.EventLog;
|
||||
import android.util.ExceptionUtils;
|
||||
import android.util.MathUtils;
|
||||
import android.util.Slog;
|
||||
@@ -1285,6 +1286,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
if (baseDexMetadataFile != null) {
|
||||
mResolvedInheritedFiles.add(baseDexMetadataFile);
|
||||
}
|
||||
+ } else if ((params.installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
|
||||
+ EventLog.writeEvent(0x534e4554, "219044664");
|
||||
+
|
||||
+ // Installing base.apk. Make sure the app is restarted.
|
||||
+ params.setDontKillApp(false);
|
||||
}
|
||||
|
||||
// Inherit splits if not overridden
|
||||
@@ -1589,6 +1595,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public int getInstallFlags() {
|
||||
+ return params.installFlags;
|
||||
+ }
|
||||
+
|
||||
private void dispatchSessionFinished(int returnCode, String msg, Bundle extras) {
|
||||
final IPackageInstallObserver2 observer;
|
||||
final String packageName;
|
174
Patches/LineageOS-16.0/android_frameworks_base/332756.patch
Normal file
174
Patches/LineageOS-16.0/android_frameworks_base/332756.patch
Normal file
|
@ -0,0 +1,174 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jonathan Scott <scottjonathan@google.com>
|
||||
Date: Tue, 5 Apr 2022 18:47:56 +0000
|
||||
Subject: [PATCH] RESTRICT AUTOMERGE Add finalizeWorkProfileProvisioning.
|
||||
|
||||
Test: atest android.devicepolicy.cts.DevicePolicyManagerTest
|
||||
Bug: 210469972
|
||||
Change-Id: I2de99f9ccd8b27ffdc2562fa451f132e73d54317
|
||||
(cherry picked from commit c5037ec63cdc72846082a66e72b34cf5067a6046)
|
||||
Merged-In: I2de99f9ccd8b27ffdc2562fa451f132e73d54317
|
||||
---
|
||||
.../app/admin/DevicePolicyManager.java | 21 ++++++++++++
|
||||
.../app/admin/IDevicePolicyManager.aidl | 3 ++
|
||||
core/res/AndroidManifest.xml | 1 +
|
||||
.../BaseIDevicePolicyManager.java | 6 ++++
|
||||
.../DevicePolicyManagerService.java | 33 +++++++++++++++++++
|
||||
5 files changed, 64 insertions(+)
|
||||
|
||||
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
|
||||
index f298bc6992b0..485ce78c3320 100644
|
||||
--- a/core/java/android/app/admin/DevicePolicyManager.java
|
||||
+++ b/core/java/android/app/admin/DevicePolicyManager.java
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.app.admin;
|
||||
|
||||
+import android.accounts.Account;
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.ColorInt;
|
||||
import android.annotation.IntDef;
|
||||
@@ -136,6 +137,26 @@ public class DevicePolicyManager {
|
||||
this(context, service, false);
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Called when a managed profile has been provisioned.
|
||||
+ *
|
||||
+ * @throws SecurityException if the caller does not hold
|
||||
+ * {@link android.Manifest.permission#MANAGE_PROFILE_AND_DEVICE_OWNERS}.
|
||||
+ * @hide
|
||||
+ */
|
||||
+ @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
|
||||
+ public void finalizeWorkProfileProvisioning(
|
||||
+ @NonNull UserHandle managedProfileUser, @Nullable Account migratedAccount) {
|
||||
+ if (mService == null) {
|
||||
+ throw new IllegalStateException("Could not find DevicePolicyManagerService");
|
||||
+ }
|
||||
+ try {
|
||||
+ mService.finalizeWorkProfileProvisioning(managedProfileUser, migratedAccount);
|
||||
+ } catch (RemoteException e) {
|
||||
+ throw e.rethrowFromSystemServer();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
protected DevicePolicyManager(Context context, IDevicePolicyManager service,
|
||||
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
|
||||
index 096427451662..64b8eaa359aa 100644
|
||||
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
|
||||
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package android.app.admin;
|
||||
|
||||
+import android.accounts.Account;
|
||||
import android.app.admin.NetworkEvent;
|
||||
import android.app.IApplicationThread;
|
||||
import android.app.IServiceConnection;
|
||||
@@ -85,6 +86,8 @@ interface IDevicePolicyManager {
|
||||
int getCurrentFailedPasswordAttempts(int userHandle, boolean parent);
|
||||
int getProfileWithMinimumFailedPasswordsForWipe(int userHandle, boolean parent);
|
||||
|
||||
+ void finalizeWorkProfileProvisioning(in UserHandle managedProfileUser, in Account migratedAccount);
|
||||
+
|
||||
void setMaximumFailedPasswordsForWipe(in ComponentName admin, int num, boolean parent);
|
||||
int getMaximumFailedPasswordsForWipe(in ComponentName admin, int userHandle, boolean parent);
|
||||
|
||||
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
|
||||
index af1a6fa9e3c5..0aafab66dabd 100644
|
||||
--- a/core/res/AndroidManifest.xml
|
||||
+++ b/core/res/AndroidManifest.xml
|
||||
@@ -91,6 +91,7 @@
|
||||
<protected-broadcast android:name="android.intent.action.USER_ACTIVITY_NOTIFICATION" />
|
||||
<protected-broadcast android:name="android.intent.action.MY_PACKAGE_SUSPENDED" />
|
||||
<protected-broadcast android:name="android.intent.action.MY_PACKAGE_UNSUSPENDED" />
|
||||
+ <protected-broadcast android:name="android.app.action.MANAGED_PROFILE_PROVISIONED" />
|
||||
|
||||
<protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" />
|
||||
<protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGING" />
|
||||
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
|
||||
index 1c9782fa5565..af1735f6e26e 100644
|
||||
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
|
||||
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
|
||||
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
package com.android.server.devicepolicy;
|
||||
|
||||
+import android.accounts.Account;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.admin.IDevicePolicyManager;
|
||||
import android.content.ComponentName;
|
||||
import android.os.PersistableBundle;
|
||||
+import android.os.UserHandle;
|
||||
import android.security.keymaster.KeymasterCertificateChain;
|
||||
import android.security.keystore.ParcelableKeyGenParameterSpec;
|
||||
import android.telephony.data.ApnSetting;
|
||||
@@ -159,4 +161,8 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
|
||||
@Override
|
||||
public void setDefaultSmsApplication(ComponentName admin, String packageName) {
|
||||
}
|
||||
+
|
||||
+ public void finalizeWorkProfileProvisioning(
|
||||
+ UserHandle managedProfileUser, Account migratedAccount) {
|
||||
+ }
|
||||
}
|
||||
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
|
||||
index 3a183865ead3..d7539e11bea9 100644
|
||||
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
|
||||
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
|
||||
@@ -20,6 +20,7 @@ import static android.Manifest.permission.BIND_DEVICE_ADMIN;
|
||||
import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
|
||||
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
|
||||
import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
|
||||
+import static android.app.admin.DevicePolicyManager.ACTION_MANAGED_PROFILE_PROVISIONED;
|
||||
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
|
||||
import static android.app.admin.DevicePolicyManager.CODE_ACCOUNTS_NOT_EMPTY;
|
||||
import static android.app.admin.DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED;
|
||||
@@ -45,6 +46,7 @@ import static android.app.admin.DevicePolicyManager.DELEGATION_INSTALL_EXISTING_
|
||||
import static android.app.admin.DevicePolicyManager.DELEGATION_KEEP_UNINSTALLED_PACKAGES;
|
||||
import static android.app.admin.DevicePolicyManager.DELEGATION_PACKAGE_ACCESS;
|
||||
import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT;
|
||||
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE;
|
||||
import static android.app.admin.DevicePolicyManager.ID_TYPE_BASE_INFO;
|
||||
import static android.app.admin.DevicePolicyManager.ID_TYPE_IMEI;
|
||||
import static android.app.admin.DevicePolicyManager.ID_TYPE_MEID;
|
||||
@@ -8878,6 +8880,37 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
}
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public void finalizeWorkProfileProvisioning(UserHandle managedProfileUser,
|
||||
+ Account migratedAccount) {
|
||||
+ if (mContext.checkCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
|
||||
+ != PackageManager.PERMISSION_GRANTED) {
|
||||
+ throw new SecurityException("Calling identity is not authorized");
|
||||
+ }
|
||||
+
|
||||
+ if (!isManagedProfile(managedProfileUser.getIdentifier())) {
|
||||
+ throw new IllegalStateException("Given user is not a managed profile");
|
||||
+ }
|
||||
+ ComponentName profileOwnerComponent =
|
||||
+ mOwners.getProfileOwnerComponent(managedProfileUser.getIdentifier());
|
||||
+ if (profileOwnerComponent == null) {
|
||||
+ throw new IllegalStateException("There is no profile owner on the given profile");
|
||||
+ }
|
||||
+ Intent primaryProfileSuccessIntent = new Intent(ACTION_MANAGED_PROFILE_PROVISIONED);
|
||||
+ primaryProfileSuccessIntent.setPackage(profileOwnerComponent.getPackageName());
|
||||
+ primaryProfileSuccessIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES
|
||||
+ | Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
+ primaryProfileSuccessIntent.putExtra(Intent.EXTRA_USER, managedProfileUser);
|
||||
+
|
||||
+ if (migratedAccount != null) {
|
||||
+ primaryProfileSuccessIntent.putExtra(EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE,
|
||||
+ migratedAccount);
|
||||
+ }
|
||||
+
|
||||
+ mContext.sendBroadcastAsUser(primaryProfileSuccessIntent,
|
||||
+ UserHandle.of(getProfileParentId(managedProfileUser.getIdentifier())));
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public UserHandle createAndManageUser(ComponentName admin, String name,
|
||||
ComponentName profileOwner, PersistableBundle adminExtras, int flags) {
|
36
Patches/LineageOS-16.0/android_frameworks_base/332757.patch
Normal file
36
Patches/LineageOS-16.0/android_frameworks_base/332757.patch
Normal file
|
@ -0,0 +1,36 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Stuart <tjstuart@google.com>
|
||||
Date: Mon, 31 Jan 2022 20:31:42 +0000
|
||||
Subject: [PATCH] limit TelecomManager#registerPhoneAccount to 10; api doc
|
||||
update
|
||||
|
||||
bug: 209814693
|
||||
Bug: 217934478
|
||||
Test: CTS
|
||||
Change-Id: I8e4425a4e7de716f86b1f1f56ea605d93f357a57
|
||||
Merged-In: I8e4425a4e7de716f86b1f1f56ea605d93f357a57
|
||||
(cherry picked from commit f0f67b5a319efedbf8693b436a641fa65bc2d8be)
|
||||
Merged-In: I8e4425a4e7de716f86b1f1f56ea605d93f357a57
|
||||
---
|
||||
telecomm/java/android/telecom/TelecomManager.java | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
|
||||
index 18c170a2e330..6b00a495668c 100644
|
||||
--- a/telecomm/java/android/telecom/TelecomManager.java
|
||||
+++ b/telecomm/java/android/telecom/TelecomManager.java
|
||||
@@ -1000,9 +1000,14 @@ public class TelecomManager {
|
||||
* when placing calls. The user may still need to enable the {@link PhoneAccount} within
|
||||
* the phone app settings before the account is usable.
|
||||
* <p>
|
||||
+ * Note: Each package is limited to 10 {@link PhoneAccount} registrations.
|
||||
+ * <p>
|
||||
* A {@link SecurityException} will be thrown if an app tries to register a
|
||||
* {@link PhoneAccountHandle} where the package name specified within
|
||||
* {@link PhoneAccountHandle#getComponentName()} does not match the package name of the app.
|
||||
+ * <p>
|
||||
+ * A {@link IllegalArgumentException} will be thrown if an app tries to register a
|
||||
+ * {@link PhoneAccount} when the upper bound limit, 10, has already been reached.
|
||||
*
|
||||
* @param account The complete {@link PhoneAccount}.
|
||||
*/
|
45
Patches/LineageOS-16.0/android_frameworks_base/332776.patch
Normal file
45
Patches/LineageOS-16.0/android_frameworks_base/332776.patch
Normal file
|
@ -0,0 +1,45 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Christie <dnchrist@google.com>
|
||||
Date: Fri, 11 Mar 2022 01:13:31 +0000
|
||||
Subject: [PATCH] Update GeofenceHardwareRequestParcelable to match
|
||||
parcel/unparcel format.
|
||||
|
||||
Test: manual
|
||||
Bug: 216631962
|
||||
|
||||
Change-Id: I3d6d1be9d6c312fe0bf98f600ff8fc9c617f8ec3
|
||||
(cherry picked from commit 3e1ffdb29417f4fb994587a013fa56c83e157f6f)
|
||||
Merged-In: I3d6d1be9d6c312fe0bf98f600ff8fc9c617f8ec3
|
||||
---
|
||||
.../location/GeofenceHardwareRequestParcelable.java | 9 +++------
|
||||
1 file changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java b/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java
|
||||
index d3311f5c8c5e..fc27d1de6372 100644
|
||||
--- a/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java
|
||||
+++ b/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package android.hardware.location;
|
||||
|
||||
+import android.os.BadParcelableException;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
-import android.util.Log;
|
||||
|
||||
/**
|
||||
* Geofence Hardware Request used for internal location services communication.
|
||||
@@ -139,11 +139,8 @@ public final class GeofenceHardwareRequestParcelable implements Parcelable {
|
||||
@Override
|
||||
public GeofenceHardwareRequestParcelable createFromParcel(Parcel parcel) {
|
||||
int geofenceType = parcel.readInt();
|
||||
- if(geofenceType != GeofenceHardwareRequest.GEOFENCE_TYPE_CIRCLE) {
|
||||
- Log.e(
|
||||
- "GeofenceHardwareRequest",
|
||||
- String.format("Invalid Geofence type: %d", geofenceType));
|
||||
- return null;
|
||||
+ if (geofenceType != GeofenceHardwareRequest.GEOFENCE_TYPE_CIRCLE) {
|
||||
+ throw new BadParcelableException("Invalid Geofence type: " + geofenceType);
|
||||
}
|
||||
|
||||
GeofenceHardwareRequest request = GeofenceHardwareRequest.createCircularGeofence(
|
151
Patches/LineageOS-16.0/android_frameworks_base/332777.patch
Normal file
151
Patches/LineageOS-16.0/android_frameworks_base/332777.patch
Normal file
|
@ -0,0 +1,151 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Reynolds <juliacr@google.com>
|
||||
Date: Tue, 1 Mar 2022 10:30:27 -0500
|
||||
Subject: [PATCH] DO NOT MERGE Add an OEM configurable limit for zen rules
|
||||
|
||||
Test: ZenModeHelperTest
|
||||
Bug: 220735360
|
||||
Change-Id: I3da105951af90007bf48dc6cf00aed3e28778b36
|
||||
Merged-In: I3da105951af90007bf48dc6cf00aed3e28778b36
|
||||
(cherry picked from commit 3072d98c2dc2b709bd8ffc343c101557a53dd188)
|
||||
Merged-In: I3da105951af90007bf48dc6cf00aed3e28778b36
|
||||
---
|
||||
.../server/notification/ZenModeHelper.java | 6 ++-
|
||||
.../notification/ZenModeHelperTest.java | 52 ++++++++++++++++++-
|
||||
2 files changed, 55 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
|
||||
index 0c42f8ab8345..90c7a874c2f4 100644
|
||||
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
|
||||
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
|
||||
@@ -91,6 +91,7 @@ public class ZenModeHelper {
|
||||
|
||||
// The amount of time rules instances can exist without their owning app being installed.
|
||||
private static final int RULE_INSTANCE_GRACE_PERIOD = 1000 * 60 * 60 * 72;
|
||||
+ static final int RULE_LIMIT_PER_PACKAGE = 100;
|
||||
|
||||
private final Context mContext;
|
||||
private final H mHandler;
|
||||
@@ -294,8 +295,9 @@ public class ZenModeHelper {
|
||||
ruleInstanceLimit = owner.metaData.getInt(
|
||||
ConditionProviderService.META_DATA_RULE_INSTANCE_LIMIT, -1);
|
||||
}
|
||||
- if (ruleInstanceLimit > 0 && ruleInstanceLimit
|
||||
- < (getCurrentInstanceCount(automaticZenRule.getOwner()) + 1)) {
|
||||
+ int newRuleInstanceCount = getCurrentInstanceCount(automaticZenRule.getOwner()) + 1;
|
||||
+ if (newRuleInstanceCount > RULE_LIMIT_PER_PACKAGE
|
||||
+ || (ruleInstanceLimit > 0 && ruleInstanceLimit < newRuleInstanceCount)) {
|
||||
throw new IllegalArgumentException("Rule instance limit exceeded");
|
||||
}
|
||||
}
|
||||
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
|
||||
index 8222c386c0d9..1d97b09853c3 100644
|
||||
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
|
||||
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
|
||||
@@ -20,10 +20,13 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
|
||||
+import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE;
|
||||
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
+import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
+import static junit.framework.TestCase.fail;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
@@ -44,6 +47,9 @@ import android.app.NotificationManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
+import android.content.pm.ActivityInfo;
|
||||
+import android.content.pm.PackageManager;
|
||||
+import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioManager;
|
||||
@@ -69,6 +75,8 @@ import com.android.internal.util.FastXmlSerializer;
|
||||
import com.android.server.UiServiceTestCase;
|
||||
import android.util.Slog;
|
||||
|
||||
+import com.google.common.collect.ImmutableList;
|
||||
+
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -87,8 +95,12 @@ import java.io.ByteArrayOutputStream;
|
||||
@TestableLooper.RunWithLooper
|
||||
public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
|
||||
+ private static final String CUSTOM_PKG_NAME = "not.android";
|
||||
+ private static final int CUSTOM_PKG_UID = 1;
|
||||
+
|
||||
ConditionProviders mConditionProviders;
|
||||
@Mock NotificationManager mNotificationManager;
|
||||
+ @Mock PackageManager mPackageManager;
|
||||
@Mock private Resources mResources;
|
||||
private TestableLooper mTestableLooper;
|
||||
private ZenModeHelper mZenModeHelperSpy;
|
||||
@@ -96,7 +108,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
private ContentResolver mContentResolver;
|
||||
|
||||
@Before
|
||||
- public void setUp() {
|
||||
+ public void setUp() throws PackageManager.NameNotFoundException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mTestableLooper = TestableLooper.get(this);
|
||||
@@ -112,6 +124,16 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
mConditionProviders.addSystemProvider(new CountdownConditionProvider());
|
||||
mZenModeHelperSpy = spy(new ZenModeHelper(mContext, mTestableLooper.getLooper(),
|
||||
mConditionProviders));
|
||||
+
|
||||
+ ResolveInfo ri = new ResolveInfo();
|
||||
+ ri.activityInfo = new ActivityInfo();
|
||||
+ when(mPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), anyInt())).thenReturn(
|
||||
+ ImmutableList.of(ri));
|
||||
+ when(mPackageManager.getPackageUidAsUser(eq(CUSTOM_PKG_NAME), anyInt()))
|
||||
+ .thenReturn(CUSTOM_PKG_UID);
|
||||
+ when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(
|
||||
+ new String[] {getContext().getPackageName()});
|
||||
+ mZenModeHelperSpy.mPm = mPackageManager;
|
||||
}
|
||||
|
||||
private ByteArrayOutputStream writeXmlAndPurge(boolean forBackup, Integer version)
|
||||
@@ -844,6 +866,34 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
assertEquals(1, mZenModeHelperSpy.mConditions.mSubscriptions.size());
|
||||
}
|
||||
|
||||
+ @Test
|
||||
+ public void testAddAutomaticZenRule_beyondSystemLimit() {
|
||||
+ for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) {
|
||||
+ ScheduleInfo si = new ScheduleInfo();
|
||||
+ si.startHour = i;
|
||||
+ AutomaticZenRule zenRule = new AutomaticZenRule("name" + i,
|
||||
+ null,
|
||||
+ new ComponentName("android", "ScheduleConditionProvider"),
|
||||
+ ZenModeConfig.toScheduleConditionId(si),
|
||||
+ new ZenPolicy.Builder().build(),
|
||||
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
|
||||
+ String id = mZenModeHelperSpy.addAutomaticZenRule(zenRule, "test");
|
||||
+ assertNotNull(id);
|
||||
+ }
|
||||
+ try {
|
||||
+ AutomaticZenRule zenRule = new AutomaticZenRule("name",
|
||||
+ null,
|
||||
+ new ComponentName("android", "ScheduleConditionProvider"),
|
||||
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
|
||||
+ new ZenPolicy.Builder().build(),
|
||||
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
|
||||
+ String id = mZenModeHelperSpy.addAutomaticZenRule(zenRule, "test");
|
||||
+ fail("allowed too many rules to be created");
|
||||
+ } catch (IllegalArgumentException e) {
|
||||
+ // yay
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private void setupZenConfig() {
|
||||
mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
|
||||
mZenModeHelperSpy.mConfig.allowAlarms = false;
|
41
Patches/LineageOS-16.0/android_frameworks_base/332778.patch
Normal file
41
Patches/LineageOS-16.0/android_frameworks_base/332778.patch
Normal file
|
@ -0,0 +1,41 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ayush Sharma <ayushsha@google.com>
|
||||
Date: Wed, 16 Mar 2022 10:32:23 +0000
|
||||
Subject: [PATCH] Fix security hole in GateKeeperResponse
|
||||
|
||||
GateKeeperResponse has inconsistent writeToParcel() and
|
||||
createFromParcel() methods, making it possible for a malicious app to
|
||||
create a Bundle that changes contents after reserialization. Such
|
||||
Bundles can be used to execute Intents with system privileges.
|
||||
|
||||
We fixed related issues previously for GateKeeperResponse class, but
|
||||
one of the case was remaining when payload is byte array of size 0,
|
||||
Fixing this case now.
|
||||
|
||||
Bug: 220303465
|
||||
Test: With the POC provided in the bug.
|
||||
Change-Id: Ida28d611edd674e76ed39dd8037f52abcba82586
|
||||
Merged-In: Ida28d611edd674e76ed39dd8037f52abcba82586
|
||||
|
||||
(cherry picked from commit 46653a91c30245ca29d41d69174813979a910496)
|
||||
|
||||
Change-Id: I486348c7a01c6f59c952b20fb4a36429fff22958
|
||||
(cherry picked from commit 658c53c47c0d1b6a74d3c0a72372aaaba16c2516)
|
||||
Merged-In: I486348c7a01c6f59c952b20fb4a36429fff22958
|
||||
---
|
||||
core/java/android/service/gatekeeper/GateKeeperResponse.java | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/java/android/service/gatekeeper/GateKeeperResponse.java b/core/java/android/service/gatekeeper/GateKeeperResponse.java
|
||||
index 9b529345851b..4502c0ef2898 100644
|
||||
--- a/core/java/android/service/gatekeeper/GateKeeperResponse.java
|
||||
+++ b/core/java/android/service/gatekeeper/GateKeeperResponse.java
|
||||
@@ -103,7 +103,7 @@ public final class GateKeeperResponse implements Parcelable {
|
||||
dest.writeInt(mTimeout);
|
||||
} else if (mResponseCode == RESPONSE_OK) {
|
||||
dest.writeInt(mShouldReEnroll ? 1 : 0);
|
||||
- if (mPayload != null) {
|
||||
+ if (mPayload != null && mPayload.length > 0) {
|
||||
dest.writeInt(mPayload.length);
|
||||
dest.writeByteArray(mPayload);
|
||||
} else {
|
45
Patches/LineageOS-16.0/android_frameworks_base/332779.patch
Normal file
45
Patches/LineageOS-16.0/android_frameworks_base/332779.patch
Normal file
|
@ -0,0 +1,45 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Oli Lan <olilan@google.com>
|
||||
Date: Fri, 25 Mar 2022 10:02:41 +0000
|
||||
Subject: [PATCH] RESTRICT AUTOMERGE Prevent non-admin users from deleting
|
||||
system apps.
|
||||
|
||||
This addresses a security issue where the guest user can remove updates
|
||||
for system apps.
|
||||
|
||||
With this CL, attempts to uninstall/downgrade system apps will fail if
|
||||
attempted by a non-admin user.
|
||||
|
||||
This is a backport of ag/17352264.
|
||||
|
||||
Bug: 170646036
|
||||
Test: manual, try uninstalling system app update as guest
|
||||
Change-Id: I5bbaaf83d035c500bfc02ff4b9b0e7fb1e7c2feb
|
||||
Merged-In: I4e959e296cca9bbdfc8fccc5e5e0e654ca524165
|
||||
(cherry picked from commit a7621e0ce00f1d140b375518e26cf75693314203)
|
||||
Merged-In: I5bbaaf83d035c500bfc02ff4b9b0e7fb1e7c2feb
|
||||
---
|
||||
.../com/android/server/pm/PackageManagerService.java | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
index dc44fe17722d..e8532ce4edd3 100644
|
||||
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
@@ -18476,6 +18476,16 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
+ if (isSystemApp(uninstalledPs)) {
|
||||
+ UserInfo userInfo = sUserManager.getUserInfo(userId);
|
||||
+ if (userInfo == null || !userInfo.isAdmin()) {
|
||||
+ Slog.w(TAG, "Not removing package " + packageName
|
||||
+ + " as only admin user may downgrade system apps");
|
||||
+ EventLog.writeEvent(0x534e4554, "170646036", -1, packageName);
|
||||
+ return PackageManager.DELETE_FAILED_USER_RESTRICTED;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
// Static shared libs can be declared by any package, so let us not
|
||||
// allow removing a package if it provides a lib others depend on.
|
||||
pkg = mPackages.get(packageName);
|
37
Patches/LineageOS-16.0/android_frameworks_base/334256.patch
Normal file
37
Patches/LineageOS-16.0/android_frameworks_base/334256.patch
Normal file
|
@ -0,0 +1,37 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Biggers <ebiggers@google.com>
|
||||
Date: Fri, 13 Aug 2021 13:37:55 -0700
|
||||
Subject: [PATCH] StorageManagerService: don't ignore failures to prepare user
|
||||
storage
|
||||
|
||||
We must never leave directories unencrypted.
|
||||
|
||||
Bug: 164488924
|
||||
Bug: 224585613
|
||||
Change-Id: I9a38ab5cca1ae9c9ebff81fca04615fd83ebe4b2
|
||||
(cherry picked from commit 50946dd15fd14cbf92b5c7e32ac7a0f088b8b302)
|
||||
Merged-In: I9a38ab5cca1ae9c9ebff81fca04615fd83ebe4b2
|
||||
(cherry picked from commit f80dd3ecd46db03005423e7fac28a0def49d0140)
|
||||
Merged-In: I9a38ab5cca1ae9c9ebff81fca04615fd83ebe4b2
|
||||
---
|
||||
.../core/java/com/android/server/StorageManagerService.java | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
|
||||
index 910e3e345f69..f6ca63a48a39 100644
|
||||
--- a/services/core/java/com/android/server/StorageManagerService.java
|
||||
+++ b/services/core/java/com/android/server/StorageManagerService.java
|
||||
@@ -2609,8 +2609,12 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
|
||||
try {
|
||||
mVold.prepareUserStorage(volumeUuid, userId, serialNumber, flags);
|
||||
- } catch (Exception e) {
|
||||
+ } catch (RemoteException e) {
|
||||
Slog.wtf(TAG, e);
|
||||
+ // Make sure to re-throw this exception; we must not ignore failure
|
||||
+ // to prepare the user storage as it could indicate that encryption
|
||||
+ // wasn't successfully set up.
|
||||
+ throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
55
Patches/LineageOS-16.0/android_frameworks_base/334257.patch
Normal file
55
Patches/LineageOS-16.0/android_frameworks_base/334257.patch
Normal file
|
@ -0,0 +1,55 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Biggers <ebiggers@google.com>
|
||||
Date: Mon, 24 Jan 2022 20:33:11 +0000
|
||||
Subject: [PATCH] UserDataPreparer: reboot to recovery if preparing user
|
||||
storage fails
|
||||
|
||||
StorageManager.prepareUserStorage() can throw an exception if a
|
||||
directory cannot be encrypted, for example due to already being
|
||||
nonempty. In this case, usage of the directory must not be allowed to
|
||||
proceed. UserDataPreparer currently handles this by deleting the user's
|
||||
directories, but the error is still ultimately suppressed and starting
|
||||
the user is still allowed to proceed.
|
||||
|
||||
The correct behavior in this case is to reboot into recovery to ask the
|
||||
user to factory reset the device. This is already what happens when
|
||||
'init' fails to encrypt a directory with the system DE policy. However,
|
||||
this was overlooked for the user directories. Start doing this.
|
||||
|
||||
Bug: 164488924
|
||||
Bug: 224585613
|
||||
Change-Id: Ib5e91d2510b25780d7a161b91b5cee2f6f7a2e54
|
||||
(cherry picked from commit 5256365e65882b81509ec2f6b9dfe2dcf0025254)
|
||||
Merged-In: Ib5e91d2510b25780d7a161b91b5cee2f6f7a2e54
|
||||
(cherry picked from commit ea010f3dd213bb6b5f3ed28b89988754ed26aac6)
|
||||
Merged-In: Ib5e91d2510b25780d7a161b91b5cee2f6f7a2e54
|
||||
---
|
||||
.../core/java/com/android/server/pm/UserDataPreparer.java | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
|
||||
index 045a295da965..504769064808 100644
|
||||
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
|
||||
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
|
||||
@@ -22,6 +22,7 @@ import android.content.Context;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.Environment;
|
||||
import android.os.FileUtils;
|
||||
+import android.os.RecoverySystem;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.os.storage.VolumeInfo;
|
||||
import android.os.SystemProperties;
|
||||
@@ -115,6 +116,13 @@ class UserDataPreparer {
|
||||
// Try one last time; if we fail again we're really in trouble
|
||||
prepareUserDataLI(volumeUuid, userId, userSerial,
|
||||
flags | StorageManager.FLAG_STORAGE_DE, false);
|
||||
+ } else {
|
||||
+ try {
|
||||
+ Log.e(TAG, "prepareUserData failed", e);
|
||||
+ RecoverySystem.rebootPromptAndWipeUserData(mContext, "prepareUserData failed");
|
||||
+ } catch (IOException e2) {
|
||||
+ throw new RuntimeException("error rebooting into recovery", e2);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
45
Patches/LineageOS-16.0/android_frameworks_base/334258.patch
Normal file
45
Patches/LineageOS-16.0/android_frameworks_base/334258.patch
Normal file
|
@ -0,0 +1,45 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Biggers <ebiggers@google.com>
|
||||
Date: Fri, 4 Mar 2022 00:07:29 +0000
|
||||
Subject: [PATCH] UserDataPreparer: reboot to recovery for system user only
|
||||
|
||||
With the next CL, old devices might contain a combination of old users
|
||||
with prepareUserStorage error checking disabled and new users with
|
||||
prepareUserStorage error checking enabled. Factory resetting the whole
|
||||
device when any user fails to prepare may be too aggressive. Also,
|
||||
UserDataPreparer already destroys the affected user's storage when it
|
||||
fails to prepare, which seems to be fairly effective at breaking things
|
||||
for that user (absent proper error handling by upper layers).
|
||||
|
||||
Therefore, let's only factory reset the device if the failing user is
|
||||
the system user.
|
||||
|
||||
Bug: 164488924
|
||||
Bug: 224585613
|
||||
Change-Id: Ia1db01ab4ec6b3b17d725f391c3500d92aa00f97
|
||||
(cherry picked from commit 4c76da76c9831266e4e63c0618150bed10a929a7)
|
||||
Merged-In: Ia1db01ab4ec6b3b17d725f391c3500d92aa00f97
|
||||
(cherry picked from commit a296a2b724f3b7233952740231a49d432949276b)
|
||||
Merged-In: Ia1db01ab4ec6b3b17d725f391c3500d92aa00f97
|
||||
---
|
||||
.../core/java/com/android/server/pm/UserDataPreparer.java | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
|
||||
index 504769064808..95482d7c7f1a 100644
|
||||
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
|
||||
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
|
||||
@@ -118,8 +118,11 @@ class UserDataPreparer {
|
||||
flags | StorageManager.FLAG_STORAGE_DE, false);
|
||||
} else {
|
||||
try {
|
||||
- Log.e(TAG, "prepareUserData failed", e);
|
||||
- RecoverySystem.rebootPromptAndWipeUserData(mContext, "prepareUserData failed");
|
||||
+ Log.wtf(TAG, "prepareUserData failed for user " + userId, e);
|
||||
+ if (userId == UserHandle.USER_SYSTEM) {
|
||||
+ RecoverySystem.rebootPromptAndWipeUserData(mContext,
|
||||
+ "prepareUserData failed for system user");
|
||||
+ }
|
||||
} catch (IOException e2) {
|
||||
throw new RuntimeException("error rebooting into recovery", e2);
|
||||
}
|
198
Patches/LineageOS-16.0/android_frameworks_base/334259.patch
Normal file
198
Patches/LineageOS-16.0/android_frameworks_base/334259.patch
Normal file
|
@ -0,0 +1,198 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Biggers <ebiggers@google.com>
|
||||
Date: Fri, 4 Mar 2022 00:07:43 +0000
|
||||
Subject: [PATCH] Ignore errors preparing user storage for existing users
|
||||
|
||||
Unfortunately we can't rule out the existence of devices where the user
|
||||
storage wasn't properly prepared, due to StorageManagerService
|
||||
previously ignoring errors from mVold.prepareUserStorage, combined with
|
||||
OEMs potentially creating files in per-user directories too early. And
|
||||
forcing these broken devices to be factory reset upon taking an OTA is
|
||||
not currently considered to be acceptable.
|
||||
|
||||
One option is to only check for prepareUserStorage errors on devices
|
||||
that launched with T or later. However, this is a serious issue and it
|
||||
would be strongly preferable to do more than that.
|
||||
|
||||
Therefore, this CL makes it so that errors are checked for all new
|
||||
users, rather than all new devices. A field ignorePrepareStorageErrors
|
||||
is added to the user record; it is only ever set to true implicitly,
|
||||
when reading a user record from disk that lacks this field. This field
|
||||
is used by StorageManagerService to decide whether to check for errors.
|
||||
|
||||
Bug: 164488924
|
||||
Bug: 224585613
|
||||
Test: Intentionally made a device affected by this issue by reverting
|
||||
the CLs that introduced the error checks, and changing vold to
|
||||
inject an error into prepareUserStorage. Then, flashed a build
|
||||
with this CL without wiping userdata. The device still boots, as
|
||||
expected, and the log shows that the error was intentionally
|
||||
ignored. Tested that if a second user is added, the error is
|
||||
*not* ignored and the second user's storage is destroyed before it
|
||||
can be used. Finally, wiped the device and verified that it won't
|
||||
boot up anymore, as expected since error checking is enabled for
|
||||
the system user in that case.
|
||||
Change-Id: I9bdd1a4bf5b14542adb901f264a91d489115c89b
|
||||
(cherry picked from commit 60d8318c47b7b659716d71243d087b34ab327f64)
|
||||
Merged-In: I9bdd1a4bf5b14542adb901f264a91d489115c89b
|
||||
(cherry picked from commit 493aa93b84b4281378e6b767bf2df6139bd0975d)
|
||||
Merged-In: I9bdd1a4bf5b14542adb901f264a91d489115c89b
|
||||
---
|
||||
core/java/android/os/UserManagerInternal.java | 8 ++++
|
||||
.../android/server/StorageManagerService.java | 12 +++++-
|
||||
.../android/server/pm/UserManagerService.java | 42 +++++++++++++++++++
|
||||
3 files changed, 61 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java
|
||||
index 1f6c3cc76ddd..674dcc024ddc 100644
|
||||
--- a/core/java/android/os/UserManagerInternal.java
|
||||
+++ b/core/java/android/os/UserManagerInternal.java
|
||||
@@ -221,4 +221,12 @@ public abstract class UserManagerInternal {
|
||||
*/
|
||||
public abstract boolean isSettingRestrictedForUser(String setting, int userId, String value,
|
||||
int callingUid);
|
||||
+
|
||||
+ /**
|
||||
+ * Returns {@code true} if the system should ignore errors when preparing
|
||||
+ * the storage directories for the user with ID {@code userId}. This will
|
||||
+ * return {@code false} for all new users; it will only return {@code true}
|
||||
+ * for users that already existed on-disk from an older version of Android.
|
||||
+ */
|
||||
+ public abstract boolean shouldIgnorePrepareStorageErrors(int userId);
|
||||
}
|
||||
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
|
||||
index f6ca63a48a39..dc77f414c9e2 100644
|
||||
--- a/services/core/java/com/android/server/StorageManagerService.java
|
||||
+++ b/services/core/java/com/android/server/StorageManagerService.java
|
||||
@@ -86,6 +86,7 @@ import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
+import android.os.UserManagerInternal;
|
||||
import android.os.storage.DiskInfo;
|
||||
import android.os.storage.IObbActionListener;
|
||||
import android.os.storage.IStorageEventListener;
|
||||
@@ -2609,11 +2610,20 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
|
||||
try {
|
||||
mVold.prepareUserStorage(volumeUuid, userId, serialNumber, flags);
|
||||
- } catch (RemoteException e) {
|
||||
+ } catch (Exception e) {
|
||||
Slog.wtf(TAG, e);
|
||||
// Make sure to re-throw this exception; we must not ignore failure
|
||||
// to prepare the user storage as it could indicate that encryption
|
||||
// wasn't successfully set up.
|
||||
+ //
|
||||
+ // Very unfortunately, these errors need to be ignored for broken
|
||||
+ // users that already existed on-disk from older Android versions.
|
||||
+ UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class);
|
||||
+ if (umInternal.shouldIgnorePrepareStorageErrors(userId)) {
|
||||
+ Slog.wtf(TAG, "ignoring error preparing storage for existing user " + userId
|
||||
+ + "; device may be insecure!");
|
||||
+ return;
|
||||
+ }
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
|
||||
index 1a22a84908f8..56d737d50fbf 100644
|
||||
--- a/services/core/java/com/android/server/pm/UserManagerService.java
|
||||
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
|
||||
@@ -175,6 +175,8 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
private static final String TAG_ENTRY = "entry";
|
||||
private static final String TAG_VALUE = "value";
|
||||
private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions";
|
||||
+ private static final String TAG_IGNORE_PREPARE_STORAGE_ERRORS =
|
||||
+ "ignorePrepareStorageErrors";
|
||||
private static final String ATTR_KEY = "key";
|
||||
private static final String ATTR_VALUE_TYPE = "type";
|
||||
private static final String ATTR_MULTIPLE = "m";
|
||||
@@ -270,6 +272,22 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
/** Elapsed realtime since boot when the user was unlocked. */
|
||||
long unlockRealtime;
|
||||
|
||||
+ /**
|
||||
+ * {@code true} if the system should ignore errors when preparing the
|
||||
+ * storage directories for this user. This is {@code false} for all new
|
||||
+ * users; it will only be {@code true} for users that already existed
|
||||
+ * on-disk from an older version of Android.
|
||||
+ */
|
||||
+ private boolean mIgnorePrepareStorageErrors;
|
||||
+
|
||||
+ boolean getIgnorePrepareStorageErrors() {
|
||||
+ return mIgnorePrepareStorageErrors;
|
||||
+ }
|
||||
+
|
||||
+ void setIgnorePrepareStorageErrors() {
|
||||
+ mIgnorePrepareStorageErrors = true;
|
||||
+ }
|
||||
+
|
||||
void clearSeedAccountData() {
|
||||
seedAccountName = null;
|
||||
seedAccountType = null;
|
||||
@@ -2307,6 +2325,10 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
serializer.endTag(null, TAG_SEED_ACCOUNT_OPTIONS);
|
||||
}
|
||||
|
||||
+ serializer.startTag(/* namespace */ null, TAG_IGNORE_PREPARE_STORAGE_ERRORS);
|
||||
+ serializer.text(String.valueOf(userData.getIgnorePrepareStorageErrors()));
|
||||
+ serializer.endTag(/* namespace */ null, TAG_IGNORE_PREPARE_STORAGE_ERRORS);
|
||||
+
|
||||
serializer.endTag(null, TAG_USER);
|
||||
|
||||
serializer.endDocument();
|
||||
@@ -2413,6 +2435,7 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
Bundle baseRestrictions = null;
|
||||
Bundle localRestrictions = null;
|
||||
Bundle globalRestrictions = null;
|
||||
+ boolean ignorePrepareStorageErrors = true; // default is true for old users
|
||||
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
parser.setInput(is, StandardCharsets.UTF_8.name());
|
||||
@@ -2486,6 +2509,11 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
} else if (TAG_SEED_ACCOUNT_OPTIONS.equals(tag)) {
|
||||
seedAccountOptions = PersistableBundle.restoreFromXml(parser);
|
||||
persistSeedData = true;
|
||||
+ } else if (TAG_IGNORE_PREPARE_STORAGE_ERRORS.equals(tag)) {
|
||||
+ type = parser.next();
|
||||
+ if (type == XmlPullParser.TEXT) {
|
||||
+ ignorePrepareStorageErrors = Boolean.parseBoolean(parser.getText());
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2510,6 +2538,9 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
userData.seedAccountType = seedAccountType;
|
||||
userData.persistSeedData = persistSeedData;
|
||||
userData.seedAccountOptions = seedAccountOptions;
|
||||
+ if (ignorePrepareStorageErrors) {
|
||||
+ userData.setIgnorePrepareStorageErrors();
|
||||
+ }
|
||||
|
||||
synchronized (mRestrictionsLock) {
|
||||
if (baseRestrictions != null) {
|
||||
@@ -3663,6 +3694,9 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
pw.println();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ pw.println(" Ignore errors preparing storage: "
|
||||
+ + userData.getIgnorePrepareStorageErrors());
|
||||
}
|
||||
}
|
||||
pw.println();
|
||||
@@ -4008,6 +4042,14 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
return UserRestrictionsUtils.isSettingRestrictedForUser(mContext, setting, userId,
|
||||
value, callingUid);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean shouldIgnorePrepareStorageErrors(int userId) {
|
||||
+ synchronized (mUsersLock) {
|
||||
+ UserData userData = mUsers.get(userId);
|
||||
+ return userData != null && userData.getIgnorePrepareStorageErrors();
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Remove all the users except of the system one. */
|
35
Patches/LineageOS-16.0/android_frameworks_base/334260.patch
Normal file
35
Patches/LineageOS-16.0/android_frameworks_base/334260.patch
Normal file
|
@ -0,0 +1,35 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Biggers <ebiggers@google.com>
|
||||
Date: Sat, 26 Mar 2022 01:08:07 +0000
|
||||
Subject: [PATCH] Log to EventLog on prepareUserStorage failure
|
||||
|
||||
Bug: 224585613
|
||||
Change-Id: Id6dfb4f4c48d5cf4e71f54bdb6d0d6eea527caf5
|
||||
(cherry picked from commit fbb632ea95ac5b6d9efa89e09d0988a9df4f19e4)
|
||||
Merged-In: Id6dfb4f4c48d5cf4e71f54bdb6d0d6eea527caf5
|
||||
(cherry picked from commit 2f2e7d84f8f856e897056064b64c6b7213ba5d86)
|
||||
Merged-In: Id6dfb4f4c48d5cf4e71f54bdb6d0d6eea527caf5
|
||||
---
|
||||
.../core/java/com/android/server/StorageManagerService.java | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
|
||||
index dc77f414c9e2..dcd1a7b03075 100644
|
||||
--- a/services/core/java/com/android/server/StorageManagerService.java
|
||||
+++ b/services/core/java/com/android/server/StorageManagerService.java
|
||||
@@ -105,6 +105,7 @@ import android.text.format.DateUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.DataUnit;
|
||||
+import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
@@ -2611,6 +2612,7 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
try {
|
||||
mVold.prepareUserStorage(volumeUuid, userId, serialNumber, flags);
|
||||
} catch (Exception e) {
|
||||
+ EventLog.writeEvent(0x534e4554, "224585613", -1, "");
|
||||
Slog.wtf(TAG, e);
|
||||
// Make sure to re-throw this exception; we must not ignore failure
|
||||
// to prepare the user storage as it could indicate that encryption
|
56
Patches/LineageOS-16.0/android_frameworks_base/334262.patch
Normal file
56
Patches/LineageOS-16.0/android_frameworks_base/334262.patch
Normal file
|
@ -0,0 +1,56 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Reynolds <juliacr@google.com>
|
||||
Date: Wed, 7 Jul 2021 16:19:44 -0400
|
||||
Subject: [PATCH] DO NOT MERGE Crash invalid FGS notifications
|
||||
|
||||
Test: CTS, ActivityManagerProcessStateTest
|
||||
Fixes: 191981182
|
||||
Change-Id: I13a0202b25c8118db47edba11a93c1939c94b392
|
||||
Merged-In: I13a0202b25c8118db47edba11a93c1939c94b392
|
||||
(cherry picked from commit 6f657f8f5b7d41af426d6cd8d60bfda6e12057c0)
|
||||
(cherry picked from commit b6b2906ea6472d182e6ae03c581a63802cd84f08)
|
||||
Merged-In: I13a0202b25c8118db47edba11a93c1939c94b392
|
||||
|
||||
Backport to P:
|
||||
Make method Notification.isForegroundService() public, as it is the case
|
||||
in Android 10 and later, see Ia13c1aac0cf91c400594df96ce267e768133f8d1
|
||||
|
||||
Change-Id: I214b6ab4f6ecab332fb8b3293fbc3b2212790b38
|
||||
---
|
||||
core/java/android/app/Notification.java | 3 ++-
|
||||
.../server/notification/NotificationManagerService.java | 7 +++++--
|
||||
2 files changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
|
||||
index 78d23f368900..21bc17172b1f 100644
|
||||
--- a/core/java/android/app/Notification.java
|
||||
+++ b/core/java/android/app/Notification.java
|
||||
@@ -5857,8 +5857,9 @@ public class Notification implements Parcelable
|
||||
|
||||
/**
|
||||
* @return whether this notification is a foreground service notification
|
||||
+ * @hide
|
||||
*/
|
||||
- private boolean isForegroundService() {
|
||||
+ public boolean isForegroundService() {
|
||||
return (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
|
||||
}
|
||||
|
||||
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
index 3e34039548d3..dd202a172d66 100755
|
||||
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
@@ -4161,8 +4161,11 @@ public class NotificationManagerService extends SystemService {
|
||||
notification.flags &= ~Notification.FLAG_CAN_COLORIZE;
|
||||
}
|
||||
|
||||
- } catch (NameNotFoundException e) {
|
||||
- Slog.e(TAG, "Cannot create a context for sending app", e);
|
||||
+ } catch (Exception e) {
|
||||
+ if (notification.isForegroundService()) {
|
||||
+ throw new SecurityException("Invalid FGS notification", e);
|
||||
+ }
|
||||
+ Slog.e(TAG, "Cannot fix notification", e);
|
||||
return;
|
||||
}
|
||||
|
137
Patches/LineageOS-16.0/android_frameworks_base/335117.patch
Normal file
137
Patches/LineageOS-16.0/android_frameworks_base/335117.patch
Normal file
|
@ -0,0 +1,137 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Chang <chengjeff@google.com>
|
||||
Date: Wed, 29 Sep 2021 16:49:00 +0800
|
||||
Subject: [PATCH] Only allow system and same app to apply
|
||||
relinquishTaskIdentity
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Any malicious application could hijack tasks by
|
||||
android:relinquishTaskIdentity. This vulnerability can perform UI
|
||||
spoofing or spy on user’s activities.
|
||||
|
||||
This CL limit the usage which only allow system and same app to apply
|
||||
relinquishTaskIdentity
|
||||
|
||||
Bug: 185810717
|
||||
Test: atest IntentTests
|
||||
atest ActivityStarterTests
|
||||
Change-Id: I55fe8938cd9a0dd7c0268e1cfec89d4e95eee049
|
||||
(cherry picked from commit cd1f9e72cf9752c9a31e990822ab34ae3d475fec)
|
||||
Merged-In: I55fe8938cd9a0dd7c0268e1cfec89d4e95eee049
|
||||
---
|
||||
.../com/android/server/am/TaskRecord.java | 51 ++++++++++++++-----
|
||||
1 file changed, 39 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
|
||||
index 766cee3278ad..6b42918eddb6 100644
|
||||
--- a/services/core/java/com/android/server/am/TaskRecord.java
|
||||
+++ b/services/core/java/com/android/server/am/TaskRecord.java
|
||||
@@ -96,6 +96,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Debug;
|
||||
+import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.Trace;
|
||||
@@ -193,6 +194,11 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
// Do not move the stack as a part of reparenting
|
||||
static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
|
||||
|
||||
+ /**
|
||||
+ * Used to identify if the activity that is installed from device's system image.
|
||||
+ */
|
||||
+ boolean mIsEffectivelySystemApp;
|
||||
+
|
||||
/**
|
||||
* The factory used to create {@link TaskRecord}. This allows OEM subclass {@link TaskRecord}.
|
||||
*/
|
||||
@@ -788,17 +794,25 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
|
||||
/** Sets the original intent, and the calling uid and package. */
|
||||
void setIntent(ActivityRecord r) {
|
||||
- mCallingUid = r.launchedFromUid;
|
||||
- mCallingPackage = r.launchedFromPackage;
|
||||
- setIntent(r.intent, r.info);
|
||||
+ boolean updateIdentity = false;
|
||||
+ if (this.intent == null) {
|
||||
+ updateIdentity = true;
|
||||
+ } else if (!mNeverRelinquishIdentity) {
|
||||
+ updateIdentity = (effectiveUid == Process.SYSTEM_UID || mIsEffectivelySystemApp
|
||||
+ || effectiveUid == r.info.applicationInfo.uid);
|
||||
+ }
|
||||
+ if (updateIdentity) {
|
||||
+ mCallingUid = r.launchedFromUid;
|
||||
+ mCallingPackage = r.launchedFromPackage;
|
||||
+ setIntent(r.intent, r.info);
|
||||
+ }
|
||||
setLockTaskAuth(r);
|
||||
}
|
||||
|
||||
/** Sets the original intent, _without_ updating the calling uid or package. */
|
||||
private void setIntent(Intent _intent, ActivityInfo info) {
|
||||
if (intent == null) {
|
||||
- mNeverRelinquishIdentity =
|
||||
- (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
|
||||
+ mNeverRelinquishIdentity = (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
|
||||
} else if (mNeverRelinquishIdentity) {
|
||||
return;
|
||||
}
|
||||
@@ -811,6 +825,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
rootAffinity = affinity;
|
||||
}
|
||||
effectiveUid = info.applicationInfo.uid;
|
||||
+ mIsEffectivelySystemApp = info.applicationInfo.isSystemApp();
|
||||
stringName = null;
|
||||
|
||||
if (info.targetActivity == null) {
|
||||
@@ -1575,12 +1590,12 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
// utility activities.
|
||||
int activityNdx;
|
||||
final int numActivities = mActivities.size();
|
||||
- final boolean relinquish = numActivities != 0 &&
|
||||
- (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
|
||||
- for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
|
||||
- ++activityNdx) {
|
||||
+ for (activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
|
||||
final ActivityRecord r = mActivities.get(activityNdx);
|
||||
- if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
|
||||
+ if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0
|
||||
+ || (r.info.applicationInfo.uid != Process.SYSTEM_UID
|
||||
+ && !r.info.applicationInfo.isSystemApp()
|
||||
+ && r.info.applicationInfo.uid != effectiveUid)) {
|
||||
// This will be the top activity for determining taskDescription. Pre-inc to
|
||||
// overcome initial decrement below.
|
||||
++activityNdx;
|
||||
@@ -1645,15 +1660,27 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
|
||||
int findEffectiveRootIndex() {
|
||||
int effectiveNdx = 0;
|
||||
final int topActivityNdx = mActivities.size() - 1;
|
||||
+ ActivityRecord root = null;
|
||||
for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
|
||||
final ActivityRecord r = mActivities.get(activityNdx);
|
||||
if (r.finishing) {
|
||||
continue;
|
||||
}
|
||||
- effectiveNdx = activityNdx;
|
||||
- if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
|
||||
+
|
||||
+ if (root == null) {
|
||||
+ // Set this as the candidate root since it isn't finishing.
|
||||
+ root = r;
|
||||
+ effectiveNdx = activityNdx;
|
||||
+ }
|
||||
+ final int uid = root == r ? effectiveUid : r.info.applicationInfo.uid;
|
||||
+ if ((root.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0
|
||||
+ || (root.info.applicationInfo.uid != Process.SYSTEM_UID
|
||||
+ && !root.info.applicationInfo.isSystemApp()
|
||||
+ && root.info.applicationInfo.uid != uid)) {
|
||||
break;
|
||||
}
|
||||
+ effectiveNdx = activityNdx;
|
||||
+ root = r;
|
||||
}
|
||||
return effectiveNdx;
|
||||
}
|
496
Patches/LineageOS-16.0/android_frameworks_base/335118.patch
Normal file
496
Patches/LineageOS-16.0/android_frameworks_base/335118.patch
Normal file
|
@ -0,0 +1,496 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Wenhao Wang <wenhaowang@google.com>
|
||||
Date: Wed, 2 Feb 2022 10:56:44 -0800
|
||||
Subject: [PATCH] DO NOT MERGE Suppress notifications when device enter
|
||||
lockdown
|
||||
|
||||
This CL makes the following modifcations:
|
||||
1. Add LockPatternUtils.StrongAuthTracker to monitor
|
||||
the lockdown mode status of the phone.
|
||||
2. Call mListeners.notifyRemovedLocked with all the
|
||||
notifications in the mNotificationList when entering
|
||||
the lockdown mode.
|
||||
3. Call mListeners.notifyPostedLocked with all the
|
||||
notifications in the mNotificationList when exiting
|
||||
the lockdown mode.
|
||||
4. Dismiss the function calls of notifyPostedLocked,
|
||||
notifyRemovedLocked, and notifyRankingUpdateLocked
|
||||
during the lockdown mode.
|
||||
|
||||
The CL also adds corresponding tests.
|
||||
|
||||
Bug: 173721373
|
||||
Test: atest NotificationManagerServiceTest
|
||||
Test: atest NotificationListenersTest
|
||||
Test: manually verify the paired device cannot receive
|
||||
notifications when the host phone is in lockdown mode.
|
||||
Ignore-AOSP-First: pending fix for a security issue.
|
||||
|
||||
Change-Id: I7e83544863eeadf8272b6ff8a9bb8136d6466203
|
||||
Merged-In: I7e83544863eeadf8272b6ff8a9bb8136d6466203
|
||||
(cherry picked from commit 3cb6842a053e236cc98d7616ba4433c31ffda3ac)
|
||||
(cherry picked from commit 85c00b98a6cac8d7286a70300ceff509693818f2)
|
||||
Merged-In: I7e83544863eeadf8272b6ff8a9bb8136d6466203
|
||||
---
|
||||
.../NotificationManagerService.java | 109 +++++++++++++-
|
||||
.../tests/uiservicestests/AndroidManifest.xml | 1 +
|
||||
.../NotificationListenersTest.java | 135 ++++++++++++++++++
|
||||
.../NotificationManagerServiceTest.java | 66 +++++++++
|
||||
4 files changed, 305 insertions(+), 6 deletions(-)
|
||||
create mode 100644 services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
|
||||
|
||||
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
index dd202a172d66..0dfc0ab0c3e0 100755
|
||||
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
@@ -181,6 +181,7 @@ import android.util.AtomicFile;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
+import android.util.SparseBooleanArray;
|
||||
import android.util.TimeUtils;
|
||||
import android.util.Xml;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
@@ -202,6 +203,7 @@ import com.android.internal.util.DumpUtils;
|
||||
import com.android.internal.util.FastXmlSerializer;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.internal.util.XmlUtils;
|
||||
+import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.server.DeviceIdleController;
|
||||
import com.android.server.EventLogTags;
|
||||
import com.android.server.LocalServices;
|
||||
@@ -1272,6 +1274,54 @@ public class NotificationManagerService extends SystemService {
|
||||
return out;
|
||||
}
|
||||
|
||||
+ protected class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
|
||||
+
|
||||
+ SparseBooleanArray mUserInLockDownMode = new SparseBooleanArray();
|
||||
+ boolean mIsInLockDownMode = false;
|
||||
+
|
||||
+ StrongAuthTracker(Context context) {
|
||||
+ super(context);
|
||||
+ }
|
||||
+
|
||||
+ private boolean containsFlag(int haystack, int needle) {
|
||||
+ return (haystack & needle) != 0;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isInLockDownMode() {
|
||||
+ return mIsInLockDownMode;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public synchronized void onStrongAuthRequiredChanged(int userId) {
|
||||
+ boolean userInLockDownModeNext = containsFlag(getStrongAuthForUser(userId),
|
||||
+ STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
||||
+ mUserInLockDownMode.put(userId, userInLockDownModeNext);
|
||||
+ boolean isInLockDownModeNext = mUserInLockDownMode.indexOfValue(true) != -1;
|
||||
+
|
||||
+ if (mIsInLockDownMode == isInLockDownModeNext) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (isInLockDownModeNext) {
|
||||
+ cancelNotificationsWhenEnterLockDownMode();
|
||||
+ }
|
||||
+
|
||||
+ // When the mIsInLockDownMode is true, both notifyPostedLocked and
|
||||
+ // notifyRemovedLocked will be dismissed. So we shall call
|
||||
+ // cancelNotificationsWhenEnterLockDownMode before we set mIsInLockDownMode
|
||||
+ // as true and call postNotificationsWhenExitLockDownMode after we set
|
||||
+ // mIsInLockDownMode as false.
|
||||
+ mIsInLockDownMode = isInLockDownModeNext;
|
||||
+
|
||||
+ if (!isInLockDownModeNext) {
|
||||
+ postNotificationsWhenExitLockDownMode();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private LockPatternUtils mLockPatternUtils;
|
||||
+ private StrongAuthTracker mStrongAuthTracker;
|
||||
+
|
||||
public NotificationManagerService(Context context) {
|
||||
super(context);
|
||||
Notification.processWhitelistToken = WHITELIST_TOKEN;
|
||||
@@ -1283,6 +1333,11 @@ public class NotificationManagerService extends SystemService {
|
||||
mAudioManager = audioMananger;
|
||||
}
|
||||
|
||||
+ @VisibleForTesting
|
||||
+ void setStrongAuthTracker(StrongAuthTracker strongAuthTracker) {
|
||||
+ mStrongAuthTracker = strongAuthTracker;
|
||||
+ }
|
||||
+
|
||||
@VisibleForTesting
|
||||
void setHints(int hints) {
|
||||
mListenerHints = hints;
|
||||
@@ -1435,6 +1490,8 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
mHandler = new WorkerHandler(looper);
|
||||
mRankingThread.start();
|
||||
+ mLockPatternUtils = new LockPatternUtils(getContext());
|
||||
+ mStrongAuthTracker = new StrongAuthTracker(getContext());
|
||||
String[] extractorNames;
|
||||
try {
|
||||
extractorNames = resources.getStringArray(R.array.config_notificationSignalExtractors);
|
||||
@@ -1563,7 +1620,8 @@ public class NotificationManagerService extends SystemService {
|
||||
init(Looper.myLooper(),
|
||||
AppGlobals.getPackageManager(), getContext().getPackageManager(),
|
||||
getLocalService(LightsManager.class),
|
||||
- new NotificationListeners(AppGlobals.getPackageManager()),
|
||||
+ new NotificationListeners(getContext(), mNotificationLock, mUserProfiles,
|
||||
+ AppGlobals.getPackageManager()),
|
||||
new NotificationAssistants(getContext(), mNotificationLock, mUserProfiles,
|
||||
AppGlobals.getPackageManager()),
|
||||
new ConditionProviders(getContext(), mUserProfiles, AppGlobals.getPackageManager()),
|
||||
@@ -1679,6 +1737,7 @@ public class NotificationManagerService extends SystemService {
|
||||
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
|
||||
mKeyguardManager = getContext().getSystemService(KeyguardManager.class);
|
||||
mZenModeHelper.onSystemReady();
|
||||
+ mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
|
||||
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
|
||||
// This observer will force an update when observe is called, causing us to
|
||||
// bind to listener services.
|
||||
@@ -6342,6 +6401,29 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
+ private void cancelNotificationsWhenEnterLockDownMode() {
|
||||
+ synchronized (mNotificationLock) {
|
||||
+ int numNotifications = mNotificationList.size();
|
||||
+ for (int i = 0; i < numNotifications; i++) {
|
||||
+ NotificationRecord rec = mNotificationList.get(i);
|
||||
+ mListeners.notifyRemovedLocked(rec, REASON_CANCEL_ALL,
|
||||
+ rec.getStats());
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private void postNotificationsWhenExitLockDownMode() {
|
||||
+ synchronized (mNotificationLock) {
|
||||
+ int numNotifications = mNotificationList.size();
|
||||
+ for (int i = 0; i < numNotifications; i++) {
|
||||
+ NotificationRecord rec = mNotificationList.get(i);
|
||||
+ mListeners.notifyPostedLocked(rec, rec);
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private void updateNotificationPulse() {
|
||||
synchronized (mNotificationLock) {
|
||||
updateLightsLocked();
|
||||
@@ -6502,6 +6584,10 @@ public class NotificationManagerService extends SystemService {
|
||||
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, hidden);
|
||||
}
|
||||
|
||||
+ boolean isInLockDownMode() {
|
||||
+ return mStrongAuthTracker.isInLockDownMode();
|
||||
+ }
|
||||
+
|
||||
boolean hasCompanionDevice(ManagedServiceInfo info) {
|
||||
if (mCompanionManager == null) {
|
||||
mCompanionManager = getCompanionManager();
|
||||
@@ -6730,9 +6816,9 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
private final ArraySet<ManagedServiceInfo> mLightTrimListeners = new ArraySet<>();
|
||||
|
||||
- public NotificationListeners(IPackageManager pm) {
|
||||
- super(getContext(), mNotificationLock, mUserProfiles, pm);
|
||||
-
|
||||
+ public NotificationListeners(Context context, Object lock, UserProfiles userProfiles,
|
||||
+ IPackageManager pm) {
|
||||
+ super(context, lock, userProfiles, pm);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -6822,8 +6908,12 @@ public class NotificationManagerService extends SystemService {
|
||||
* targetting <= O_MR1
|
||||
*/
|
||||
@GuardedBy("mNotificationLock")
|
||||
- private void notifyPostedLocked(NotificationRecord r, NotificationRecord old,
|
||||
+ void notifyPostedLocked(NotificationRecord r, NotificationRecord old,
|
||||
boolean notifyAllListeners) {
|
||||
+ if (isInLockDownMode()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
// Lazily initialized snapshots of the notification.
|
||||
StatusBarNotification sbn = r.sbn;
|
||||
StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
|
||||
@@ -6886,8 +6976,11 @@ public class NotificationManagerService extends SystemService {
|
||||
@GuardedBy("mNotificationLock")
|
||||
public void notifyRemovedLocked(NotificationRecord r, int reason,
|
||||
NotificationStats notificationStats) {
|
||||
- final StatusBarNotification sbn = r.sbn;
|
||||
+ if (isInLockDownMode()) {
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
+ final StatusBarNotification sbn = r.sbn;
|
||||
// make a copy in case changes are made to the underlying Notification object
|
||||
// NOTE: this copy is lightweight: it doesn't include heavyweight parts of the
|
||||
// notification
|
||||
@@ -6938,6 +7031,10 @@ public class NotificationManagerService extends SystemService {
|
||||
*/
|
||||
@GuardedBy("mNotificationLock")
|
||||
public void notifyRankingUpdateLocked(List<NotificationRecord> changedHiddenNotifications) {
|
||||
+ if (isInLockDownMode()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
boolean isHiddenRankingUpdate = changedHiddenNotifications != null
|
||||
&& changedHiddenNotifications.size() > 0;
|
||||
|
||||
diff --git a/services/tests/uiservicestests/AndroidManifest.xml b/services/tests/uiservicestests/AndroidManifest.xml
|
||||
index aa3135ff18da..4f81bfae9a7c 100644
|
||||
--- a/services/tests/uiservicestests/AndroidManifest.xml
|
||||
+++ b/services/tests/uiservicestests/AndroidManifest.xml
|
||||
@@ -29,6 +29,7 @@
|
||||
<uses-permission android:name="android.permission.DEVICE_POWER" />
|
||||
<uses-permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
+ <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
|
||||
|
||||
<application android:debuggable="true">
|
||||
<uses-library android:name="android.test.runner" />
|
||||
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
|
||||
new file mode 100644
|
||||
index 000000000000..793739bfe8f5
|
||||
--- /dev/null
|
||||
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
|
||||
@@ -0,0 +1,135 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2022 The Android Open Source Project
|
||||
+ *
|
||||
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
+ * you may not use this file except in compliance with the License.
|
||||
+ * You may obtain a copy of the License at
|
||||
+ *
|
||||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||||
+ *
|
||||
+ * Unless required by applicable law or agreed to in writing, software
|
||||
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+ * See the License for the specific language governing permissions and
|
||||
+ * limitations under the License.
|
||||
+ */
|
||||
+package com.android.server.notification;
|
||||
+
|
||||
+import static org.mockito.ArgumentMatchers.any;
|
||||
+import static org.mockito.Mockito.doNothing;
|
||||
+import static org.mockito.Mockito.mock;
|
||||
+import static org.mockito.Mockito.never;
|
||||
+import static org.mockito.Mockito.reset;
|
||||
+import static org.mockito.Mockito.spy;
|
||||
+import static org.mockito.Mockito.times;
|
||||
+import static org.mockito.Mockito.verify;
|
||||
+import static org.mockito.Mockito.when;
|
||||
+
|
||||
+import android.app.INotificationManager;
|
||||
+import android.content.pm.IPackageManager;
|
||||
+import android.content.pm.PackageManager;
|
||||
+import android.service.notification.NotificationStats;
|
||||
+import android.service.notification.StatusBarNotification;
|
||||
+import android.testing.TestableContext;
|
||||
+
|
||||
+import com.android.server.UiServiceTestCase;
|
||||
+
|
||||
+import org.junit.Before;
|
||||
+import org.junit.Test;
|
||||
+import org.mockito.Mock;
|
||||
+import org.mockito.MockitoAnnotations;
|
||||
+import org.mockito.internal.util.reflection.FieldSetter;
|
||||
+
|
||||
+import java.util.List;
|
||||
+
|
||||
+public class NotificationListenersTest extends UiServiceTestCase {
|
||||
+
|
||||
+ @Mock
|
||||
+ private PackageManager mPm;
|
||||
+ @Mock
|
||||
+ private IPackageManager miPm;
|
||||
+
|
||||
+ @Mock
|
||||
+ NotificationManagerService mNm;
|
||||
+ @Mock
|
||||
+ private INotificationManager mINm;
|
||||
+ private TestableContext mContext = spy(getContext());
|
||||
+
|
||||
+ NotificationManagerService.NotificationListeners mListeners;
|
||||
+
|
||||
+ @Before
|
||||
+ public void setUp() throws Exception {
|
||||
+ MockitoAnnotations.initMocks(this);
|
||||
+ getContext().setMockPackageManager(mPm);
|
||||
+ doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
|
||||
+
|
||||
+ mListeners = spy(mNm.new NotificationListeners(
|
||||
+ mContext, new Object(), mock(ManagedServices.UserProfiles.class), miPm));
|
||||
+ when(mNm.getBinderService()).thenReturn(mINm);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testNotifyPostedLockedInLockdownMode() {
|
||||
+ NotificationRecord r = mock(NotificationRecord.class);
|
||||
+ NotificationRecord old = mock(NotificationRecord.class);
|
||||
+
|
||||
+ // before the lockdown mode
|
||||
+ when(mNm.isInLockDownMode()).thenReturn(false);
|
||||
+ mListeners.notifyPostedLocked(r, old, true);
|
||||
+ mListeners.notifyPostedLocked(r, old, false);
|
||||
+ verify(mListeners, times(2)).getServices();
|
||||
+
|
||||
+ // in the lockdown mode
|
||||
+ reset(r);
|
||||
+ reset(old);
|
||||
+ reset(mListeners);
|
||||
+ when(mNm.isInLockDownMode()).thenReturn(true);
|
||||
+ mListeners.notifyPostedLocked(r, old, true);
|
||||
+ mListeners.notifyPostedLocked(r, old, false);
|
||||
+ verify(mListeners, never()).getServices();
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testnotifyRankingUpdateLockedInLockdownMode() {
|
||||
+ List chn = mock(List.class);
|
||||
+
|
||||
+ // before the lockdown mode
|
||||
+ when(mNm.isInLockDownMode()).thenReturn(false);
|
||||
+ mListeners.notifyRankingUpdateLocked(chn);
|
||||
+ verify(chn, times(1)).size();
|
||||
+
|
||||
+ // in the lockdown mode
|
||||
+ reset(chn);
|
||||
+ when(mNm.isInLockDownMode()).thenReturn(true);
|
||||
+ mListeners.notifyRankingUpdateLocked(chn);
|
||||
+ verify(chn, never()).size();
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testNotifyRemovedLockedInLockdownMode() throws NoSuchFieldException {
|
||||
+ StatusBarNotification sbn = mock(StatusBarNotification.class);
|
||||
+ NotificationRecord r = mock(NotificationRecord.class);
|
||||
+ NotificationStats rs = mock(NotificationStats.class);
|
||||
+ FieldSetter.setField(r,
|
||||
+ NotificationRecord.class.getDeclaredField("sbn"),
|
||||
+ sbn);
|
||||
+ FieldSetter.setField(mNm,
|
||||
+ NotificationManagerService.class.getDeclaredField("mHandler"),
|
||||
+ mock(NotificationManagerService.WorkerHandler.class));
|
||||
+
|
||||
+ // before the lockdown mode
|
||||
+ when(mNm.isInLockDownMode()).thenReturn(false);
|
||||
+ mListeners.notifyRemovedLocked(r, 0, rs);
|
||||
+ mListeners.notifyRemovedLocked(r, 0, rs);
|
||||
+ verify(sbn, times(2)).cloneLight();
|
||||
+
|
||||
+ // in the lockdown mode
|
||||
+ reset(sbn);
|
||||
+ reset(r);
|
||||
+ reset(rs);
|
||||
+ when(mNm.isInLockDownMode()).thenReturn(true);
|
||||
+ mListeners.notifyRemovedLocked(r, 0, rs);
|
||||
+ mListeners.notifyRemovedLocked(r, 0, rs);
|
||||
+ verify(sbn, never()).cloneLight();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
|
||||
index 420bfbc042ff..ed3406fc95b4 100644
|
||||
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
|
||||
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
|
||||
@@ -37,6 +37,9 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.os.Build.VERSION_CODES.O_MR1;
|
||||
import static android.os.Build.VERSION_CODES.P;
|
||||
+import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
|
||||
+
|
||||
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
@@ -233,6 +236,26 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
protected void reportUserInteraction(NotificationRecord r) {
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ class StrongAuthTrackerFake extends NotificationManagerService.StrongAuthTracker {
|
||||
+ private int mGetStrongAuthForUserReturnValue = 0;
|
||||
+ StrongAuthTrackerFake(Context context) {
|
||||
+ super(context);
|
||||
+ }
|
||||
+
|
||||
+ public void setGetStrongAuthForUserReturnValue(int val) {
|
||||
+ mGetStrongAuthForUserReturnValue = val;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getStrongAuthForUser(int userId) {
|
||||
+ return mGetStrongAuthForUserReturnValue;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ TestableNotificationManagerService.StrongAuthTrackerFake mStrongAuthTracker;
|
||||
+
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -304,6 +327,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
}
|
||||
mService.setAudioManager(mAudioManager);
|
||||
|
||||
+ mStrongAuthTracker = mService.new StrongAuthTrackerFake(mContext);
|
||||
+ mService.setStrongAuthTracker(mStrongAuthTracker);
|
||||
+
|
||||
// Tests call directly into the Binder.
|
||||
mBinderService = mService.getBinderService();
|
||||
mInternalService = mService.getInternalService();
|
||||
@@ -3261,4 +3287,44 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
|
||||
mUid + UserHandle.PER_USER_RANGE);
|
||||
}
|
||||
+
|
||||
+ @Test
|
||||
+ public void testStrongAuthTracker_isInLockDownMode() {
|
||||
+ mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
|
||||
+ STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
||||
+ mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
|
||||
+ assertTrue(mStrongAuthTracker.isInLockDownMode());
|
||||
+ mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0);
|
||||
+ mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
|
||||
+ assertFalse(mStrongAuthTracker.isInLockDownMode());
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testCancelAndPostNotificationsWhenEnterAndExitLockDownMode() {
|
||||
+ // post 2 notifications from 2 packages
|
||||
+ NotificationRecord pkgA = new NotificationRecord(mContext,
|
||||
+ generateSbn("a", 1000, 9, 0), mTestNotificationChannel);
|
||||
+ mService.addNotification(pkgA);
|
||||
+ NotificationRecord pkgB = new NotificationRecord(mContext,
|
||||
+ generateSbn("b", 1001, 9, 0), mTestNotificationChannel);
|
||||
+ mService.addNotification(pkgB);
|
||||
+
|
||||
+ // when entering the lockdown mode, cancel the 2 notifications.
|
||||
+ mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
|
||||
+ STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
||||
+ mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
|
||||
+ assertTrue(mStrongAuthTracker.isInLockDownMode());
|
||||
+
|
||||
+ // the notifyRemovedLocked function is called twice due to REASON_LOCKDOWN.
|
||||
+ ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class);
|
||||
+ verify(mListeners, times(2)).notifyRemovedLocked(any(), captor.capture(), any());
|
||||
+ assertEquals(REASON_CANCEL_ALL, captor.getValue().intValue());
|
||||
+
|
||||
+ // exit lockdown mode.
|
||||
+ mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0);
|
||||
+ mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
|
||||
+
|
||||
+ // the notifyPostedLocked function is called twice.
|
||||
+ verify(mListeners, times(2)).notifyPostedLocked(any(), any());
|
||||
+ }
|
||||
}
|
72
Patches/LineageOS-16.0/android_frameworks_base/335119.patch
Normal file
72
Patches/LineageOS-16.0/android_frameworks_base/335119.patch
Normal file
|
@ -0,0 +1,72 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Raphael Kim <raphk@google.com>
|
||||
Date: Fri, 22 Apr 2022 00:32:08 +0000
|
||||
Subject: [PATCH] Remove package title from notification access confirmation
|
||||
intent
|
||||
|
||||
Bug: 228178437
|
||||
Test: Manually confirmed on an application
|
||||
Change-Id: Idad6dc0c71d7b39de0bd9e4ad922b5e6020a6184
|
||||
Merged-In: Idad6dc0c71d7b39de0bd9e4ad922b5e6020a6184
|
||||
(cherry picked from commit 51d47ec7c875cf964f46965a27a5d36343ea999d)
|
||||
Merged-In: Idad6dc0c71d7b39de0bd9e4ad922b5e6020a6184
|
||||
---
|
||||
...NotificationAccessConfirmationActivityContract.java | 10 ++++++----
|
||||
.../companion/CompanionDeviceManagerService.java | 9 ++-------
|
||||
2 files changed, 8 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java b/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java
|
||||
index 4ce6f609ef73..fdf0e9046eef 100644
|
||||
--- a/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java
|
||||
+++ b/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.internal.notification;
|
||||
|
||||
import android.content.ComponentName;
|
||||
+import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public final class NotificationAccessConfirmationActivityContract {
|
||||
@@ -25,13 +26,14 @@ public final class NotificationAccessConfirmationActivityContract {
|
||||
"com.android.settings.notification.NotificationAccessConfirmationActivity");
|
||||
public static final String EXTRA_USER_ID = "user_id";
|
||||
public static final String EXTRA_COMPONENT_NAME = "component_name";
|
||||
- public static final String EXTRA_PACKAGE_TITLE = "package_title";
|
||||
|
||||
- public static Intent launcherIntent(int userId, ComponentName component, String packageTitle) {
|
||||
+ /**
|
||||
+ * Creates a launcher intent for NotificationAccessConfirmationActivity.
|
||||
+ */
|
||||
+ public static Intent launcherIntent(Context context, int userId, ComponentName component) {
|
||||
return new Intent()
|
||||
.setComponent(COMPONENT_NAME)
|
||||
.putExtra(EXTRA_USER_ID, userId)
|
||||
- .putExtra(EXTRA_COMPONENT_NAME, component)
|
||||
- .putExtra(EXTRA_PACKAGE_TITLE, packageTitle);
|
||||
+ .putExtra(EXTRA_COMPONENT_NAME, component);
|
||||
}
|
||||
}
|
||||
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
|
||||
index 0e77715e1563..e39652d77b7a 100644
|
||||
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
|
||||
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
|
||||
@@ -290,17 +290,12 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
|
||||
String callingPackage = component.getPackageName();
|
||||
checkCanCallNotificationApi(callingPackage);
|
||||
int userId = getCallingUserId();
|
||||
- String packageTitle = BidiFormatter.getInstance().unicodeWrap(
|
||||
- getPackageInfo(callingPackage, userId)
|
||||
- .applicationInfo
|
||||
- .loadSafeLabel(getContext().getPackageManager())
|
||||
- .toString());
|
||||
- long identity = Binder.clearCallingIdentity();
|
||||
+ final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return PendingIntent.getActivity(getContext(),
|
||||
0 /* request code */,
|
||||
NotificationAccessConfirmationActivityContract.launcherIntent(
|
||||
- userId, component, packageTitle),
|
||||
+ getContext(), userId, component),
|
||||
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT
|
||||
| PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
} finally {
|
70
Patches/LineageOS-16.0/android_frameworks_base/335120.patch
Normal file
70
Patches/LineageOS-16.0/android_frameworks_base/335120.patch
Normal file
|
@ -0,0 +1,70 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: chiachangwang <chiachangwang@google.com>
|
||||
Date: Thu, 2 Jun 2022 10:22:20 +0000
|
||||
Subject: [PATCH] Stop using invalid URL to prevent unexpected crash
|
||||
|
||||
Verify the input PAC Uri before performing follow-up actions.
|
||||
|
||||
Check if the URL is a valid URL to filter some invalid URLs since
|
||||
these invalid URLs could not fall into any subclass of existing
|
||||
URLConnections. When the PAC Uri is other invalid URL scheme, it
|
||||
will cause an UnsupportedOperationException if there is no proper
|
||||
subclass that implements the openConnection() method.
|
||||
A malformed URL may crash the system.
|
||||
|
||||
Even it's a valid URL, some subclasses(e.g. JarURLConnection)
|
||||
may not have openConnection() implemented. It will also hit the
|
||||
problem, so convert the possbile exception from openConnection()
|
||||
to re-throw it to IOException which is handled in the existing
|
||||
code.
|
||||
|
||||
Bug: 219498290
|
||||
Test: atest FrameworksNetTests CtsNetTestCases
|
||||
Test: Test with malformed URL
|
||||
Merged-In: I22903414380b62051f514e43b93af992f45740b4
|
||||
Merged-In: I2abff75ec59a17628ef006aad348c53fadbed076
|
||||
Change-Id: I4d6cec1da9cf3f70dec0dcf4223254d3da4f30a3
|
||||
(cherry picked from commit 6390b37a3b32fc7583154d53fda3af8fbd95f59f)
|
||||
(cherry picked from commit 6d6f4106948bbad67b9845603392d084078997c4)
|
||||
Merged-In: I4d6cec1da9cf3f70dec0dcf4223254d3da4f30a3
|
||||
---
|
||||
.../server/connectivity/PacManager.java | 19 +++++++++++++++++--
|
||||
1 file changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java
|
||||
index 3a27fcb352aa..f597c8135701 100644
|
||||
--- a/services/core/java/com/android/server/connectivity/PacManager.java
|
||||
+++ b/services/core/java/com/android/server/connectivity/PacManager.java
|
||||
@@ -37,6 +37,7 @@ import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
+import android.webkit.URLUtil;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.net.IProxyCallback;
|
||||
@@ -211,8 +212,22 @@ public class PacManager {
|
||||
* @throws IOException
|
||||
*/
|
||||
private static String get(Uri pacUri) throws IOException {
|
||||
- URL url = new URL(pacUri.toString());
|
||||
- URLConnection urlConnection = url.openConnection(java.net.Proxy.NO_PROXY);
|
||||
+ if (!URLUtil.isValidUrl(pacUri.toString())) {
|
||||
+ throw new IOException("Malformed URL:" + pacUri);
|
||||
+ }
|
||||
+
|
||||
+ final URL url = new URL(pacUri.toString());
|
||||
+ URLConnection urlConnection;
|
||||
+ try {
|
||||
+ urlConnection = url.openConnection(java.net.Proxy.NO_PROXY);
|
||||
+ // Catch the possible exceptions and rethrow as IOException to not to crash the system
|
||||
+ // for illegal input.
|
||||
+ } catch (IllegalArgumentException e) {
|
||||
+ throw new IOException("Incorrect proxy type for " + pacUri);
|
||||
+ } catch (UnsupportedOperationException e) {
|
||||
+ throw new IOException("Unsupported URL connection type for " + pacUri);
|
||||
+ }
|
||||
+
|
||||
long contentLength = -1;
|
||||
try {
|
||||
contentLength = Long.parseLong(urlConnection.getHeaderField("Content-Length"));
|
75
Patches/LineageOS-16.0/android_frameworks_base/335121.patch
Normal file
75
Patches/LineageOS-16.0/android_frameworks_base/335121.patch
Normal file
|
@ -0,0 +1,75 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Makoto Onuki <omakoto@google.com>
|
||||
Date: Tue, 19 Apr 2022 10:54:18 -0700
|
||||
Subject: [PATCH] Only allow the system server to connect to sync adapters
|
||||
|
||||
Bug: 203229608
|
||||
Test: Manual test with changing the check logic + debug log
|
||||
Change-Id: If18009f61360564d02dcda9b1e5fa15685e3250f
|
||||
(cherry picked from commit 58270527d11ac7e5f07d337a402d8edf046a63ee)
|
||||
(cherry picked from commit 7d1397a54475ed7fee632339ef7c60b432f0fbff)
|
||||
Merged-In: If18009f61360564d02dcda9b1e5fa15685e3250f
|
||||
---
|
||||
.../content/AbstractThreadedSyncAdapter.java | 20 +++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
|
||||
index a086a308d0d9..da4ecdd8c1f2 100644
|
||||
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
|
||||
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
|
||||
@@ -21,6 +21,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa
|
||||
import android.accounts.Account;
|
||||
import android.annotation.MainThread;
|
||||
import android.annotation.NonNull;
|
||||
+import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@@ -171,8 +172,20 @@ public abstract class AbstractThreadedSyncAdapter {
|
||||
}
|
||||
|
||||
private class ISyncAdapterImpl extends ISyncAdapter.Stub {
|
||||
+ private boolean isCallerSystem() {
|
||||
+ final long callingUid = Binder.getCallingUid();
|
||||
+ if (callingUid != Process.SYSTEM_UID) {
|
||||
+ android.util.EventLog.writeEvent(0x534e4554, "203229608", -1, "");
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public void onUnsyncableAccount(ISyncAdapterUnsyncableAccountCallback cb) {
|
||||
+ if (!isCallerSystem()) {
|
||||
+ return;
|
||||
+ }
|
||||
Handler.getMain().sendMessage(obtainMessage(
|
||||
AbstractThreadedSyncAdapter::handleOnUnsyncableAccount,
|
||||
AbstractThreadedSyncAdapter.this, cb));
|
||||
@@ -181,12 +194,16 @@ public abstract class AbstractThreadedSyncAdapter {
|
||||
@Override
|
||||
public void startSync(ISyncContext syncContext, String authority, Account account,
|
||||
Bundle extras) {
|
||||
+ if (!isCallerSystem()) {
|
||||
+ return;
|
||||
+ }
|
||||
if (ENABLE_LOG) {
|
||||
if (extras != null) {
|
||||
extras.size(); // Unparcel so its toString() will show the contents.
|
||||
}
|
||||
Log.d(TAG, "startSync() start " + authority + " " + account + " " + extras);
|
||||
}
|
||||
+
|
||||
try {
|
||||
final SyncContext syncContextClient = new SyncContext(syncContext);
|
||||
|
||||
@@ -242,6 +259,9 @@ public abstract class AbstractThreadedSyncAdapter {
|
||||
|
||||
@Override
|
||||
public void cancelSync(ISyncContext syncContext) {
|
||||
+ if (!isCallerSystem()) {
|
||||
+ return;
|
||||
+ }
|
||||
try {
|
||||
// synchronize to make sure that mSyncThreads doesn't change between when we
|
||||
// check it and when we use it
|
113
Patches/LineageOS-16.0/android_frameworks_base/338346.patch
Normal file
113
Patches/LineageOS-16.0/android_frameworks_base/338346.patch
Normal file
|
@ -0,0 +1,113 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Manjeet Rulhania <mrulhania@google.com>
|
||||
Date: Thu, 28 Apr 2022 20:23:58 +0000
|
||||
Subject: [PATCH] Fix duplicate permission privilege escalation
|
||||
|
||||
Duplicate permissions definition with different group allows
|
||||
privilege permission escalation to a different permission group.
|
||||
|
||||
Android studio and gradle plugin does not allow duplicate
|
||||
permissions with different attributes, these tools only allow
|
||||
if duplicate permissions are exact copies.
|
||||
|
||||
Also platform stores permissions in map at multiple places with
|
||||
permission name as key. This suggests that we can disallow
|
||||
duplicate permissions during package install/update.
|
||||
|
||||
Bug: 213323615
|
||||
Test: manual
|
||||
Change-Id: I6f44e740897305e7a0553c1cf6c3af37faf02a2e
|
||||
Merged-In: I1910dca44104e35a57eba4acfa8188cd9b8626ac
|
||||
Merged-In: I34120fff2ec2a158dfa55779d2afd4bbd49487ff
|
||||
Merged-In: I9bc839836786a0876e67fd73c05f8944bb532249
|
||||
(cherry picked from commit 31bd425bb66b108cdec357a00f4a586379bcd33a)
|
||||
Merged-In: I6f44e740897305e7a0553c1cf6c3af37faf02a2e
|
||||
---
|
||||
.../android/content/pm/PackageParser.java | 53 +++++++++++++++++++
|
||||
1 file changed, 53 insertions(+)
|
||||
|
||||
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
|
||||
index e0c2d2dc6dde..c56dfbe97895 100644
|
||||
--- a/core/java/android/content/pm/PackageParser.java
|
||||
+++ b/core/java/android/content/pm/PackageParser.java
|
||||
@@ -81,6 +81,7 @@ import android.util.AttributeSet;
|
||||
import android.util.Base64;
|
||||
import android.util.ByteStringUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
+import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
import android.util.PackageUtils;
|
||||
import android.util.Pair;
|
||||
@@ -125,6 +126,7 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
+import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@@ -2469,6 +2471,12 @@ public class PackageParser {
|
||||
}
|
||||
}
|
||||
|
||||
+ if (declareDuplicatePermission(pkg)) {
|
||||
+ outError[0] = "Found duplicate permission with a different attribute value.";
|
||||
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
if (supportsSmallScreens < 0 || (supportsSmallScreens > 0
|
||||
&& pkg.applicationInfo.targetSdkVersion
|
||||
>= android.os.Build.VERSION_CODES.DONUT)) {
|
||||
@@ -2507,6 +2515,51 @@ public class PackageParser {
|
||||
return pkg;
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * @return {@code true} if the package declares malformed duplicate permissions.
|
||||
+ */
|
||||
+ public static boolean declareDuplicatePermission(@NonNull Package pkg) {
|
||||
+ final List<Permission> permissions = pkg.permissions;
|
||||
+ final int size = permissions.size();
|
||||
+ if (size > 0) {
|
||||
+ final ArrayMap<String, Permission> checkDuplicatePerm = new ArrayMap<>(size);
|
||||
+ for (int i = 0; i < size; i++) {
|
||||
+ final Permission permissionDefinition = permissions.get(i);
|
||||
+ final String name = permissionDefinition.info.name;
|
||||
+ final Permission perm = checkDuplicatePerm.get(name);
|
||||
+ if (isMalformedDuplicate(permissionDefinition, perm)) {
|
||||
+ // Fix for b/213323615
|
||||
+ EventLog.writeEvent(0x534e4554, "213323615",
|
||||
+ "The package " + pkg.packageName + " seems malicious");
|
||||
+ return true;
|
||||
+ }
|
||||
+ checkDuplicatePerm.put(name, permissionDefinition);
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Determines if a duplicate permission is malformed .i.e. defines different protection level
|
||||
+ * or group.
|
||||
+ */
|
||||
+ private static boolean isMalformedDuplicate(Permission p1, Permission p2) {
|
||||
+ // Since a permission tree is also added as a permission with normal protection
|
||||
+ // level, we need to skip if the parsedPermission is a permission tree.
|
||||
+ if (p1 == null || p2 == null || p1.tree || p2.tree) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (p1.info.getProtection() != p2.info.getProtection()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ if (!Objects.equals(p1.info.group, p2.info.group)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
private boolean checkOverlayRequiredSystemProperty(String propName, String propValue) {
|
||||
|
||||
if (TextUtils.isEmpty(propName) || TextUtils.isEmpty(propValue)) {
|
35
Patches/LineageOS-16.0/android_frameworks_base/338347.patch
Normal file
35
Patches/LineageOS-16.0/android_frameworks_base/338347.patch
Normal file
|
@ -0,0 +1,35 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Steven Moreland <smoreland@google.com>
|
||||
Date: Wed, 30 Mar 2022 21:46:29 +0000
|
||||
Subject: [PATCH] Parcel: recycle recycles
|
||||
|
||||
Before, it was like getting a used pan with food stuck on it. We run
|
||||
a clean ship here. You want a Parcel? You get a fresh Parcel. When
|
||||
we recycle a Parcel, we do a real clean-up job. Air freshener. All
|
||||
bits brushed over. These Parcel objects are clean as heck now!
|
||||
|
||||
(specifically cleans mClassCookies)
|
||||
|
||||
Bug: 208279300
|
||||
Test: build
|
||||
Merged-In: I250872f5c6796bb64e2dc68008154c0e90feb218
|
||||
Change-Id: I250872f5c6796bb64e2dc68008154c0e90feb218
|
||||
(cherry picked from commit 46770fa49c9a5e51a5ea5a3afc7aab0dba2e59bd)
|
||||
(cherry picked from commit b5c79e141a81fa86fc834980d46886ac3c86ab11)
|
||||
Merged-In: I250872f5c6796bb64e2dc68008154c0e90feb218
|
||||
---
|
||||
core/java/android/os/Parcel.java | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
|
||||
index 460f12510d45..8d44ba1ad625 100644
|
||||
--- a/core/java/android/os/Parcel.java
|
||||
+++ b/core/java/android/os/Parcel.java
|
||||
@@ -406,6 +406,7 @@ public final class Parcel {
|
||||
*/
|
||||
public final void recycle() {
|
||||
if (DEBUG_RECYCLE) mStack = null;
|
||||
+ mClassCookies = null;
|
||||
freeBuffer();
|
||||
|
||||
final Parcel[] pool;
|
41
Patches/LineageOS-16.0/android_frameworks_base/338348.patch
Normal file
41
Patches/LineageOS-16.0/android_frameworks_base/338348.patch
Normal file
|
@ -0,0 +1,41 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Adrian Roos <roosa@google.com>
|
||||
Date: Thu, 24 Sep 2020 15:30:46 +0200
|
||||
Subject: [PATCH] IMMS: Make IMMS PendingIntents immutable
|
||||
|
||||
Fixes: 154913391
|
||||
Test: n/a
|
||||
Change-Id: I34a95732ef3e7c20d6549b57230c11f0c3db04d6
|
||||
Merged-In: I34a95732ef3e7c20d6549b57230c11f0c3db04d6
|
||||
(cherry picked from commit d4b625994f7664666ac7b53bf6a7d79a6459b3f1)
|
||||
(cherry picked from commit 6842f03c9d2f128785df5ce2bd02c61f35226554)
|
||||
(cherry picked from commit 2b859826165bddb11f17b217d097253c442f6045)
|
||||
Merged-In: I34a95732ef3e7c20d6549b57230c11f0c3db04d6
|
||||
---
|
||||
.../java/com/android/server/InputMethodManagerService.java | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
|
||||
index 412b314aefbf..e728b0aa92e8 100644
|
||||
--- a/services/core/java/com/android/server/InputMethodManagerService.java
|
||||
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
|
||||
@@ -1402,7 +1402,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
|
||||
Intent intent = new Intent(ACTION_SHOW_INPUT_METHOD_PICKER)
|
||||
.setPackage(mContext.getPackageName());
|
||||
- mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
|
||||
+ mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent,
|
||||
+ PendingIntent.FLAG_IMMUTABLE);
|
||||
|
||||
mShowOngoingImeSwitcherForPhones = false;
|
||||
|
||||
@@ -2003,7 +2004,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
mCurIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
|
||||
com.android.internal.R.string.input_method_binding_label);
|
||||
mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
|
||||
- mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
|
||||
+ mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS),
|
||||
+ PendingIntent.FLAG_IMMUTABLE));
|
||||
if (bindCurrentInputMethodServiceLocked(mCurIntent, this, IME_CONNECTION_BIND_FLAGS)) {
|
||||
mLastBindTime = SystemClock.uptimeMillis();
|
||||
mHaveConnection = true;
|
31
Patches/LineageOS-16.0/android_frameworks_base/338349.patch
Normal file
31
Patches/LineageOS-16.0/android_frameworks_base/338349.patch
Normal file
|
@ -0,0 +1,31 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Manjeet Rulhania <mrulhania@google.com>
|
||||
Date: Thu, 30 Jun 2022 18:52:50 +0000
|
||||
Subject: [PATCH] Remove package name from SafetyNet logs
|
||||
|
||||
Bug: 213323615
|
||||
Test: AppSecurityTests
|
||||
Change-Id: Ia2be2b1e32dc0b75c352bc15219f4c4de9abb45a
|
||||
Merged-In: I993832e148636f1795ffe393c6dc74a08b9442f8
|
||||
Merged-In: I8f823487ca16861a35135cfc3383fa2ce8258017
|
||||
Merged-In: I4b61d13256ce0bfb8fc9d21db52ee78ce2097f14
|
||||
(cherry picked from commit 50d343c656921ba9c730c68b7a41de6b15f57f03)
|
||||
Merged-In: Ia2be2b1e32dc0b75c352bc15219f4c4de9abb45a
|
||||
---
|
||||
core/java/android/content/pm/PackageParser.java | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
|
||||
index c56dfbe97895..d99302d6696f 100644
|
||||
--- a/core/java/android/content/pm/PackageParser.java
|
||||
+++ b/core/java/android/content/pm/PackageParser.java
|
||||
@@ -2529,8 +2529,7 @@ public class PackageParser {
|
||||
final Permission perm = checkDuplicatePerm.get(name);
|
||||
if (isMalformedDuplicate(permissionDefinition, perm)) {
|
||||
// Fix for b/213323615
|
||||
- EventLog.writeEvent(0x534e4554, "213323615",
|
||||
- "The package " + pkg.packageName + " seems malicious");
|
||||
+ EventLog.writeEvent(0x534e4554, "213323615");
|
||||
return true;
|
||||
}
|
||||
checkDuplicatePerm.put(name, permissionDefinition);
|
251
Patches/LineageOS-16.0/android_frameworks_base/342100.patch
Normal file
251
Patches/LineageOS-16.0/android_frameworks_base/342100.patch
Normal file
|
@ -0,0 +1,251 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Reynolds <juliacr@google.com>
|
||||
Date: Fri, 1 Jul 2022 09:49:12 -0400
|
||||
Subject: [PATCH] DO NOT MERGE Limit the number of concurrently snoozed
|
||||
notifications
|
||||
|
||||
Test: atest FrameworksUiServicesTests
|
||||
Bug: 234441463
|
||||
Change-Id: I005b43979d1c708fd505c8b33ae0c8cb03ddbb35
|
||||
Merged-In: I005b43979d1c708fd505c8b33ae0c8cb03ddbb35
|
||||
(cherry picked from commit 7c38394ae9c69620499a87e629edae4fe0ac4edc)
|
||||
(cherry picked from commit c38cc3e355718577192da8f544d21fd0be5f6be2)
|
||||
Merged-In: I005b43979d1c708fd505c8b33ae0c8cb03ddbb35
|
||||
---
|
||||
.../NotificationManagerService.java | 25 +++++--
|
||||
.../server/notification/SnoozeHelper.java | 9 +++
|
||||
.../NotificationManagerServiceTest.java | 68 +++++++++++++++++++
|
||||
.../server/notification/SnoozeHelperTest.java | 18 +++++
|
||||
4 files changed, 116 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
index 0dfc0ab0c3e0..acef7148cd2f 100755
|
||||
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
@@ -4487,13 +4487,17 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
@GuardedBy("mNotificationLock")
|
||||
void snoozeLocked(NotificationRecord r) {
|
||||
+ final List<NotificationRecord> recordsToSnooze = new ArrayList<>();
|
||||
if (r.sbn.isGroup()) {
|
||||
- final List<NotificationRecord> groupNotifications = findGroupNotificationsLocked(
|
||||
- r.sbn.getPackageName(), r.sbn.getGroupKey(), r.sbn.getUserId());
|
||||
+ final List<NotificationRecord> groupNotifications =
|
||||
+ findGroupNotificationsLocked(r.sbn.getPackageName(),
|
||||
+ r.sbn.getGroupKey(), r.sbn.getUserId());
|
||||
if (r.getNotification().isGroupSummary()) {
|
||||
// snooze summary and all children
|
||||
for (int i = 0; i < groupNotifications.size(); i++) {
|
||||
- snoozeNotificationLocked(groupNotifications.get(i));
|
||||
+ if (!mKey.equals(groupNotifications.get(i).getKey())) {
|
||||
+ recordsToSnooze.add(groupNotifications.get(i));
|
||||
+ }
|
||||
}
|
||||
} else {
|
||||
// if there is a valid summary for this group, and we are snoozing the only
|
||||
@@ -4504,7 +4508,9 @@ public class NotificationManagerService extends SystemService {
|
||||
} else {
|
||||
// snooze summary and the one child
|
||||
for (int i = 0; i < groupNotifications.size(); i++) {
|
||||
- snoozeNotificationLocked(groupNotifications.get(i));
|
||||
+ if (!mKey.equals(groupNotifications.get(i).getKey())) {
|
||||
+ recordsToSnooze.add(groupNotifications.get(i));
|
||||
+ }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -4515,6 +4521,17 @@ public class NotificationManagerService extends SystemService {
|
||||
// just snooze the one notification
|
||||
snoozeNotificationLocked(r);
|
||||
}
|
||||
+
|
||||
+ // snooze the notification
|
||||
+ recordsToSnooze.add(r);
|
||||
+
|
||||
+ if (mSnoozeHelper.canSnooze(recordsToSnooze.size())) {
|
||||
+ for (int i = 0; i < recordsToSnooze.size(); i++) {
|
||||
+ snoozeNotificationLocked(recordsToSnooze.get(i));
|
||||
+ }
|
||||
+ } else {
|
||||
+ Log.w(TAG, "Cannot snooze " + r.getKey() + ": too many snoozed notifications");
|
||||
+ }
|
||||
}
|
||||
|
||||
@GuardedBy("mNotificationLock")
|
||||
diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java
|
||||
index 732a58774b78..fc0962d9ea36 100644
|
||||
--- a/services/core/java/com/android/server/notification/SnoozeHelper.java
|
||||
+++ b/services/core/java/com/android/server/notification/SnoozeHelper.java
|
||||
@@ -55,6 +55,8 @@ import java.util.Set;
|
||||
* NotificationManagerService helper for handling snoozed notifications.
|
||||
*/
|
||||
public class SnoozeHelper {
|
||||
+ static final int CONCURRENT_SNOOZE_LIMIT = 500;
|
||||
+
|
||||
private static final String TAG = "SnoozeHelper";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
private static final String INDENT = " ";
|
||||
@@ -89,6 +91,13 @@ public class SnoozeHelper {
|
||||
mUserProfiles = userProfiles;
|
||||
}
|
||||
|
||||
+ protected boolean canSnooze(int numberToSnooze) {
|
||||
+ if ((mPackages.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
protected boolean isSnoozed(int userId, String pkg, String key) {
|
||||
return mSnoozedNotifications.containsKey(userId)
|
||||
&& mSnoozedNotifications.get(userId).containsKey(pkg)
|
||||
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
|
||||
index ed3406fc95b4..9592e1905b54 100644
|
||||
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
|
||||
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
|
||||
@@ -1799,6 +1799,69 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertFalse(mService.hasCompanionDevice(mListener));
|
||||
}
|
||||
|
||||
+ @Test
|
||||
+ public void testSnoozeRunnable_tooManySnoozed_singleNotification() {
|
||||
+ final NotificationRecord notification = generateNotificationRecord(
|
||||
+ mTestNotificationChannel, 1, null, true);
|
||||
+ mService.addNotification(notification);
|
||||
+
|
||||
+ when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||
+ when(mSnoozeHelper.canSnooze(1)).thenReturn(false);
|
||||
+
|
||||
+ NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||
+ mService.new SnoozeNotificationRunnable(
|
||||
+ notification.getKey(), 100, null);
|
||||
+ snoozeNotificationRunnable.run();
|
||||
+
|
||||
+ verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong());
|
||||
+ assertEquals(1, mService.getNotificationRecordCount());
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testSnoozeRunnable_tooManySnoozed_singleGroupChildNotification() {
|
||||
+ final NotificationRecord notification = generateNotificationRecord(
|
||||
+ mTestNotificationChannel, 1, "group", true);
|
||||
+ final NotificationRecord notificationChild = generateNotificationRecord(
|
||||
+ mTestNotificationChannel, 1, "group", false);
|
||||
+ mService.addNotification(notification);
|
||||
+ mService.addNotification(notificationChild);
|
||||
+
|
||||
+ when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||
+ when(mSnoozeHelper.canSnooze(2)).thenReturn(false);
|
||||
+
|
||||
+ NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||
+ mService.new SnoozeNotificationRunnable(
|
||||
+ notificationChild.getKey(), 100, null);
|
||||
+ snoozeNotificationRunnable.run();
|
||||
+
|
||||
+ verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong());
|
||||
+ assertEquals(2, mService.getNotificationRecordCount());
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testSnoozeRunnable_tooManySnoozed_summaryNotification() {
|
||||
+ final NotificationRecord notification = generateNotificationRecord(
|
||||
+ mTestNotificationChannel, 1, "group", true);
|
||||
+ final NotificationRecord notificationChild = generateNotificationRecord(
|
||||
+ mTestNotificationChannel, 12, "group", false);
|
||||
+ final NotificationRecord notificationChild2 = generateNotificationRecord(
|
||||
+ mTestNotificationChannel, 13, "group", false);
|
||||
+ mService.addNotification(notification);
|
||||
+ mService.addNotification(notificationChild);
|
||||
+ mService.addNotification(notificationChild2);
|
||||
+
|
||||
+ when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||
+ when(mSnoozeHelper.canSnooze(3)).thenReturn(false);
|
||||
+
|
||||
+ NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||
+ mService.new SnoozeNotificationRunnable(
|
||||
+ notification.getKey(), 100, null);
|
||||
+ snoozeNotificationRunnable.run();
|
||||
+
|
||||
+ verify(mSnoozeHelper, never()).snooze(any(NotificationRecord.class), anyLong());
|
||||
+ assertEquals(3, mService.getNotificationRecordCount());
|
||||
+ }
|
||||
+
|
||||
@Test
|
||||
public void testSnoozeRunnable_snoozeNonGrouped() throws Exception {
|
||||
final NotificationRecord nonGrouped = generateNotificationRecord(
|
||||
@@ -1807,6 +1870,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
mTestNotificationChannel, 2, "group", false);
|
||||
mService.addNotification(grouped);
|
||||
mService.addNotification(nonGrouped);
|
||||
+ when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||
|
||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||
mService.new SnoozeNotificationRunnable(
|
||||
@@ -1829,6 +1893,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
mService.addNotification(parent);
|
||||
mService.addNotification(child);
|
||||
mService.addNotification(child2);
|
||||
+ when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||
|
||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||
mService.new SnoozeNotificationRunnable(
|
||||
@@ -1850,6 +1915,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
mService.addNotification(parent);
|
||||
mService.addNotification(child);
|
||||
mService.addNotification(child2);
|
||||
+ when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||
|
||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||
mService.new SnoozeNotificationRunnable(
|
||||
@@ -1869,6 +1935,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
mTestNotificationChannel, 2, "group", false);
|
||||
mService.addNotification(parent);
|
||||
mService.addNotification(child);
|
||||
+ when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||
|
||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||
mService.new SnoozeNotificationRunnable(
|
||||
@@ -1884,6 +1951,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
final NotificationRecord child = generateNotificationRecord(
|
||||
mTestNotificationChannel, 2, "group", false);
|
||||
mService.addNotification(child);
|
||||
+ when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
|
||||
|
||||
NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
|
||||
mService.new SnoozeNotificationRunnable(
|
||||
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
|
||||
index 7adfbd3cb777..30ec5589d594 100644
|
||||
--- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
|
||||
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
|
||||
@@ -22,6 +22,8 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
+import static com.android.server.notification.SnoozeHelper.CONCURRENT_SNOOZE_LIMIT;
|
||||
+
|
||||
import android.app.AlarmManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
@@ -101,6 +103,22 @@ public class SnoozeHelperTest extends UiServiceTestCase {
|
||||
UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
|
||||
}
|
||||
|
||||
+ @Test
|
||||
+ public void testSnoozeLimit() {
|
||||
+ for (int i = 0; i < CONCURRENT_SNOOZE_LIMIT; i++ ) {
|
||||
+ NotificationRecord r = getNotificationRecord("pkg", i, i+"", UserHandle.SYSTEM);
|
||||
+
|
||||
+ assertTrue("cannot snooze record " + i, mSnoozeHelper.canSnooze(1));
|
||||
+
|
||||
+ if (i % 2 == 0) {
|
||||
+ mSnoozeHelper.snooze(r, 1000);
|
||||
+ } else {
|
||||
+ mSnoozeHelper.snooze(r, 9000);
|
||||
+ }
|
||||
+ }
|
||||
+ assertFalse(mSnoozeHelper.canSnooze(1));
|
||||
+ }
|
||||
+
|
||||
@Test
|
||||
public void testCancelByApp() throws Exception {
|
||||
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
|
102
Patches/LineageOS-16.0/android_frameworks_base/344168.patch
Normal file
102
Patches/LineageOS-16.0/android_frameworks_base/344168.patch
Normal file
|
@ -0,0 +1,102 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aseem Kumar <aseemk@google.com>
|
||||
Date: Mon, 21 Mar 2022 20:35:20 -0700
|
||||
Subject: [PATCH] DO NOT MERGE Move accountname and typeName length check from
|
||||
Account.java to AccountManagerService.
|
||||
|
||||
Bug: 169762606
|
||||
Test: atest AccountManagerServiceTest
|
||||
Change-Id: I80fabf3a64c55837db98ff316e7e5420129c001b
|
||||
(cherry picked from commit 3f218c9a5e1f7c3213ceb84c15afca0d3041057b)
|
||||
Merged-In: I80fabf3a64c55837db98ff316e7e5420129c001b
|
||||
---
|
||||
core/java/android/accounts/Account.java | 7 -------
|
||||
.../accounts/AccountManagerService.java | 12 ++++++++++++
|
||||
.../accounts/AccountManagerServiceTest.java | 19 +++++++++++++++++++
|
||||
3 files changed, 31 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java
|
||||
index 1546ae14862d..3f90f36fb2a1 100644
|
||||
--- a/core/java/android/accounts/Account.java
|
||||
+++ b/core/java/android/accounts/Account.java
|
||||
@@ -28,7 +28,6 @@ import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
-import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -81,12 +80,6 @@ public class Account implements Parcelable {
|
||||
if (TextUtils.isEmpty(type)) {
|
||||
throw new IllegalArgumentException("the type must not be empty: " + type);
|
||||
}
|
||||
- if (name.length() > 200) {
|
||||
- throw new IllegalArgumentException("account name is longer than 200 characters");
|
||||
- }
|
||||
- if (type.length() > 200) {
|
||||
- throw new IllegalArgumentException("account type is longer than 200 characters");
|
||||
- }
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.accessId = accessId;
|
||||
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
index 9e8464728b9b..4c8acc5ffb63 100644
|
||||
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
@@ -1777,6 +1777,14 @@ public class AccountManagerService
|
||||
if (account == null) {
|
||||
return false;
|
||||
}
|
||||
+ if (account.name != null && account.name.length() > 200) {
|
||||
+ Log.w(TAG, "Account cannot be added - Name longer than 200 chars");
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (account.type != null && account.type.length() > 200) {
|
||||
+ Log.w(TAG, "Account cannot be added - Name longer than 200 chars");
|
||||
+ return false;
|
||||
+ }
|
||||
if (!isLocalUnlockedUser(accounts.userId)) {
|
||||
Log.w(TAG, "Account " + account + " cannot be added - user " + accounts.userId
|
||||
+ " is locked. callingUid=" + callingUid);
|
||||
@@ -1969,6 +1977,10 @@ public class AccountManagerService
|
||||
+ ", pid " + Binder.getCallingPid());
|
||||
}
|
||||
if (accountToRename == null) throw new IllegalArgumentException("account is null");
|
||||
+ if (newName != null && newName.length() > 200) {
|
||||
+ Log.e(TAG, "renameAccount failed - account name longer than 200");
|
||||
+ throw new IllegalArgumentException("account name longer than 200");
|
||||
+ }
|
||||
int userId = UserHandle.getCallingUserId();
|
||||
if (!isAccountManagedByCaller(accountToRename.type, callingUid, userId)) {
|
||||
String msg = String.format(
|
||||
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
|
||||
index 149ef156a9fa..73267e4868a6 100644
|
||||
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
|
||||
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
|
||||
@@ -237,6 +237,25 @@ public class AccountManagerServiceTest extends AndroidTestCase {
|
||||
assertEquals(a31, accounts[1]);
|
||||
}
|
||||
|
||||
+ @SmallTest
|
||||
+ public void testCheckAddAccountLongName() throws Exception {
|
||||
+ unlockSystemUser();
|
||||
+ String longString = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
+ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
+ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
+ + "aaaaa";
|
||||
+ Account a11 = new Account(longString, AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
|
||||
+
|
||||
+ mAms.addAccountExplicitly(a11, /* password= */ "p11", /* extras= */ null);
|
||||
+
|
||||
+ String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
|
||||
+ when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
|
||||
+ Account[] accounts = mAms.getAccountsAsUser(null,
|
||||
+ UserHandle.getCallingUserId(), mContext.getOpPackageName());
|
||||
+ assertEquals(0, accounts.length);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
@SmallTest
|
||||
public void testPasswords() throws Exception {
|
||||
unlockSystemUser();
|
141
Patches/LineageOS-16.0/android_frameworks_base/344169.patch
Normal file
141
Patches/LineageOS-16.0/android_frameworks_base/344169.patch
Normal file
|
@ -0,0 +1,141 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Stuart <tjstuart@google.com>
|
||||
Date: Thu, 23 Jun 2022 14:27:43 -0700
|
||||
Subject: [PATCH] switch TelecomManager List getters to ParceledListSlice
|
||||
|
||||
It was shown that given a large phoneAccountHandles that are
|
||||
over 1 mb, a TransactionTooLarge exception can be silently thrown
|
||||
causing an empty list to be returned.
|
||||
|
||||
In order to prevent this behavior, all Lists that return a
|
||||
PhoneAccountHandle or PhoneAccount have been switched to
|
||||
ParceledListSlice.
|
||||
|
||||
bug: 236263294
|
||||
Test: atest android.telecom.cts.PhoneAccountRegistrarTest
|
||||
#testRegisterPhoneAccountHandleWithFieldOverLimit
|
||||
Change-Id: I025245b2a6f8cfaca86f268851a9d8f0817e07dd
|
||||
Merged-In: I025245b2a6f8cfaca86f268851a9d8f0817e07dd
|
||||
(cherry picked from commit 773cddde3d522606ff032fe8e432321c70edca09)
|
||||
Merged-In: I025245b2a6f8cfaca86f268851a9d8f0817e07dd
|
||||
---
|
||||
telecomm/java/android/telecom/TelecomManager.java | 14 ++++++++------
|
||||
.../android/internal/telecom/ITelecomService.aidl | 13 +++++++------
|
||||
2 files changed, 15 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
|
||||
index 6b00a495668c..ae97db00507d 100644
|
||||
--- a/telecomm/java/android/telecom/TelecomManager.java
|
||||
+++ b/telecomm/java/android/telecom/TelecomManager.java
|
||||
@@ -831,7 +831,7 @@ public class TelecomManager {
|
||||
try {
|
||||
if (isServiceConnected()) {
|
||||
return getTelecomService().getPhoneAccountsSupportingScheme(uriScheme,
|
||||
- mContext.getOpPackageName());
|
||||
+ mContext.getOpPackageName()).getList();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsSupportingScheme", e);
|
||||
@@ -873,7 +873,8 @@ public class TelecomManager {
|
||||
public List<PhoneAccountHandle> getSelfManagedPhoneAccounts() {
|
||||
try {
|
||||
if (isServiceConnected()) {
|
||||
- return getTelecomService().getSelfManagedPhoneAccounts(mContext.getOpPackageName());
|
||||
+ return getTelecomService()
|
||||
+ .getSelfManagedPhoneAccounts(mContext.getOpPackageName()).getList();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error calling ITelecomService#getSelfManagedPhoneAccounts()", e);
|
||||
@@ -892,7 +893,7 @@ public class TelecomManager {
|
||||
try {
|
||||
if (isServiceConnected()) {
|
||||
return getTelecomService().getCallCapablePhoneAccounts(
|
||||
- includeDisabledAccounts, mContext.getOpPackageName());
|
||||
+ includeDisabledAccounts, mContext.getOpPackageName()).getList();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error calling ITelecomService#getCallCapablePhoneAccounts(" +
|
||||
@@ -912,7 +913,8 @@ public class TelecomManager {
|
||||
public List<PhoneAccountHandle> getPhoneAccountsForPackage() {
|
||||
try {
|
||||
if (isServiceConnected()) {
|
||||
- return getTelecomService().getPhoneAccountsForPackage(mContext.getPackageName());
|
||||
+ return getTelecomService()
|
||||
+ .getPhoneAccountsForPackage(mContext.getPackageName()).getList();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsForPackage", e);
|
||||
@@ -966,7 +968,7 @@ public class TelecomManager {
|
||||
public List<PhoneAccount> getAllPhoneAccounts() {
|
||||
try {
|
||||
if (isServiceConnected()) {
|
||||
- return getTelecomService().getAllPhoneAccounts();
|
||||
+ return getTelecomService().getAllPhoneAccounts().getList();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccounts", e);
|
||||
@@ -984,7 +986,7 @@ public class TelecomManager {
|
||||
public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
|
||||
try {
|
||||
if (isServiceConnected()) {
|
||||
- return getTelecomService().getAllPhoneAccountHandles();
|
||||
+ return getTelecomService().getAllPhoneAccountHandles().getList();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccountHandles", e);
|
||||
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
|
||||
index b4e7d56bc642..5169a7d24093 100644
|
||||
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
|
||||
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
|
||||
@@ -23,6 +23,7 @@ import android.telecom.PhoneAccountHandle;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.telecom.PhoneAccount;
|
||||
+import android.content.pm.ParceledListSlice;
|
||||
|
||||
/**
|
||||
* Interface used to interact with Telecom. Mostly this is used by TelephonyManager for passing
|
||||
@@ -55,24 +56,24 @@ interface ITelecomService {
|
||||
/**
|
||||
* @see TelecomServiceImpl#getCallCapablePhoneAccounts
|
||||
*/
|
||||
- List<PhoneAccountHandle> getCallCapablePhoneAccounts(
|
||||
+ ParceledListSlice getCallCapablePhoneAccounts(
|
||||
boolean includeDisabledAccounts, String callingPackage);
|
||||
|
||||
/**
|
||||
* @see TelecomServiceImpl#getSelfManagedPhoneAccounts
|
||||
*/
|
||||
- List<PhoneAccountHandle> getSelfManagedPhoneAccounts(String callingPackage);
|
||||
+ ParceledListSlice getSelfManagedPhoneAccounts(String callingPackage);
|
||||
|
||||
/**
|
||||
* @see TelecomManager#getPhoneAccountsSupportingScheme
|
||||
*/
|
||||
- List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(in String uriScheme,
|
||||
+ ParceledListSlice getPhoneAccountsSupportingScheme(in String uriScheme,
|
||||
String callingPackage);
|
||||
|
||||
/**
|
||||
* @see TelecomManager#getPhoneAccountsForPackage
|
||||
*/
|
||||
- List<PhoneAccountHandle> getPhoneAccountsForPackage(in String packageName);
|
||||
+ ParceledListSlice getPhoneAccountsForPackage(in String packageName);
|
||||
|
||||
/**
|
||||
* @see TelecomManager#getPhoneAccount
|
||||
@@ -87,12 +88,12 @@ interface ITelecomService {
|
||||
/**
|
||||
* @see TelecomManager#getAllPhoneAccounts
|
||||
*/
|
||||
- List<PhoneAccount> getAllPhoneAccounts();
|
||||
+ ParceledListSlice getAllPhoneAccounts();
|
||||
|
||||
/**
|
||||
* @see TelecomManager#getAllPhoneAccountHandles
|
||||
*/
|
||||
- List<PhoneAccountHandle> getAllPhoneAccountHandles();
|
||||
+ ParceledListSlice getAllPhoneAccountHandles();
|
||||
|
||||
/**
|
||||
* @see TelecomServiceImpl#getSimCallManager
|
84
Patches/LineageOS-16.0/android_frameworks_base/344170.patch
Normal file
84
Patches/LineageOS-16.0/android_frameworks_base/344170.patch
Normal file
|
@ -0,0 +1,84 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Louis Chang <louischang@google.com>
|
||||
Date: Tue, 2 Aug 2022 03:33:39 +0000
|
||||
Subject: [PATCH] Do not send new Intent to non-exported activity when
|
||||
navigateUpTo
|
||||
|
||||
The new Intent was delivered to a non-exported activity while
|
||||
'#navigateUpTo was called from an Activity of a different uid.
|
||||
|
||||
Backport to pie:
|
||||
* services/core/java/com/android/server/am directory (not wm)
|
||||
* back port of getPid() method
|
||||
|
||||
Bug: 238605611
|
||||
Test: atest StartActivityTests
|
||||
Change-Id: I854dd825bfd9a2c08851980d480d1f3a177af6cf
|
||||
Merged-In: I854dd825bfd9a2c08851980d480d1f3a177af6cf
|
||||
(cherry picked from commit b9a934064598aa655fab4ce75c8eab6165409670)
|
||||
Merged-In: I854dd825bfd9a2c08851980d480d1f3a177af6cf
|
||||
---
|
||||
.../com/android/server/am/ActivityRecord.java | 4 ++++
|
||||
.../com/android/server/am/ActivityStack.java | 18 +++++++++++++++++-
|
||||
.../com/android/server/am/ProcessRecord.java | 4 ++++
|
||||
3 files changed, 25 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
|
||||
index 2c5b8568515f..089a3984a480 100644
|
||||
--- a/services/core/java/com/android/server/am/ActivityRecord.java
|
||||
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
|
||||
@@ -2922,6 +2922,10 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
|
||||
return info.applicationInfo.uid;
|
||||
}
|
||||
|
||||
+ int getPid() {
|
||||
+ return app != null ? app.getPid() : 0;
|
||||
+ }
|
||||
+
|
||||
void setShowWhenLocked(boolean showWhenLocked) {
|
||||
mShowWhenLocked = showWhenLocked;
|
||||
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0 /* configChanges */,
|
||||
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
|
||||
index dddcc9e466a4..68af5184dec0 100644
|
||||
--- a/services/core/java/com/android/server/am/ActivityStack.java
|
||||
+++ b/services/core/java/com/android/server/am/ActivityStack.java
|
||||
@@ -4008,7 +4008,23 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
|
||||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
|
||||
(destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
|
||||
- parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName);
|
||||
+ boolean abort;
|
||||
+ try {
|
||||
+ final int callingPid = srec.app != null ? srec.app.getPid() : 0;
|
||||
+ abort = !mStackSupervisor.checkStartAnyActivityPermission(destIntent,
|
||||
+ parent.info, null /* resultWho */, -1 /* requestCode */, callingPid,
|
||||
+ callingUid, srec.info.packageName, false /* ignoreTargetSecurity */,
|
||||
+ false /* launchingInTask */, srec.app, null /* resultRecord */,
|
||||
+ null /* resultRootTask */);
|
||||
+ } catch (SecurityException e) {
|
||||
+ abort = true;
|
||||
+ }
|
||||
+ if (abort) {
|
||||
+ android.util.EventLog.writeEvent(0x534e4554, "238605611", callingUid, "");
|
||||
+ foundParentInTask = false;
|
||||
+ } else {
|
||||
+ parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName);
|
||||
+ }
|
||||
} else {
|
||||
try {
|
||||
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
|
||||
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
|
||||
index e3e839f63172..b15cf6a606cc 100644
|
||||
--- a/services/core/java/com/android/server/am/ProcessRecord.java
|
||||
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
|
||||
@@ -520,6 +520,10 @@ final class ProcessRecord {
|
||||
stringName = null;
|
||||
}
|
||||
|
||||
+ public int getPid() {
|
||||
+ return pid;
|
||||
+ }
|
||||
+
|
||||
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
|
||||
if (thread == null) {
|
||||
final ProcessState origBase = baseProcessTracker;
|
57
Patches/LineageOS-16.0/android_frameworks_base/344171.patch
Normal file
57
Patches/LineageOS-16.0/android_frameworks_base/344171.patch
Normal file
|
@ -0,0 +1,57 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Norman <danielnorman@google.com>
|
||||
Date: Fri, 12 Aug 2022 11:40:41 -0700
|
||||
Subject: [PATCH] Do not send AccessibilityEvent if notification is for
|
||||
different user.
|
||||
|
||||
Bug: 237540408
|
||||
Test: BuzzBeepBlinkTest#testA11yCrossUserEventNotSent
|
||||
Change-Id: I62a875e26e214847ec72ce3c41b4f2fa8e597e07
|
||||
Merged-In: I62a875e26e214847ec72ce3c41b4f2fa8e597e07
|
||||
(cherry picked from commit 18f2ec86d680bff26ce9248061878894ad16e05f)
|
||||
Merged-In: I62a875e26e214847ec72ce3c41b4f2fa8e597e07
|
||||
---
|
||||
.../notification/NotificationManagerService.java | 3 ++-
|
||||
.../server/notification/BuzzBeepBlinkTest.java | 15 +++++++++++++++
|
||||
2 files changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
index acef7148cd2f..a53f2aec436c 100755
|
||||
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
@@ -4985,7 +4985,8 @@ public class NotificationManagerService extends SystemService {
|
||||
boolean sentAccessibilityEvent = false;
|
||||
// If the notification will appear in the status bar, it should send an accessibility
|
||||
// event
|
||||
- if (!record.isUpdate && record.getImportance() > IMPORTANCE_MIN) {
|
||||
+ if (!record.isUpdate && record.getImportance() > IMPORTANCE_MIN
|
||||
+ && isNotificationForCurrentUser(record)) {
|
||||
sendAccessibilityEvent(record);
|
||||
sentAccessibilityEvent = true;
|
||||
}
|
||||
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
|
||||
index 3b3f128b6ca5..feae34dcb68c 100644
|
||||
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
|
||||
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
|
||||
@@ -1102,6 +1102,21 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
|
||||
verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
|
||||
}
|
||||
|
||||
+ @Test
|
||||
+ public void testA11yCrossUserEventNotSent() throws Exception {
|
||||
+ final Notification n = new Builder(getContext(), "test")
|
||||
+ .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
|
||||
+ int userId = mUser.getIdentifier() + 1;
|
||||
+ StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
|
||||
+ mPid, n, UserHandle.of(userId), null, System.currentTimeMillis());
|
||||
+ NotificationRecord r = new NotificationRecord(getContext(), sbn,
|
||||
+ new NotificationChannel("test", "test", IMPORTANCE_HIGH));
|
||||
+
|
||||
+ mService.buzzBeepBlinkLocked(r);
|
||||
+
|
||||
+ verify(mAccessibilityService, never()).sendAccessibilityEvent(any(), anyInt());
|
||||
+ }
|
||||
+
|
||||
@Test
|
||||
public void testLightsScreenOn() {
|
||||
mService.mScreenOn = true;
|
126
Patches/LineageOS-16.0/android_frameworks_base/344172.patch
Normal file
126
Patches/LineageOS-16.0/android_frameworks_base/344172.patch
Normal file
|
@ -0,0 +1,126 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yuri Lin <yurilin@google.com>
|
||||
Date: Mon, 29 Aug 2022 17:40:14 -0400
|
||||
Subject: [PATCH] Trim any long string inputs that come in to AutomaticZenRule
|
||||
|
||||
This change both prevents any rules from being unable to be written to
|
||||
disk and also avoids risk of running out of memory while handling all
|
||||
the zen rules.
|
||||
|
||||
Bug: 242703460
|
||||
Bug: 242703505
|
||||
Bug: 242703780
|
||||
Bug: 242704043
|
||||
Bug: 243794204
|
||||
Test: cts AutomaticZenRuleTest; atest android.app.AutomaticZenRuleTest;
|
||||
manually confirmed each exploit example either saves the rule
|
||||
successfully with a truncated string (in the case of name & conditionId)
|
||||
or may fail to save the rule at all (if the owner/configactivity is invalid).
|
||||
Additionally ran the memory-exhausting PoC without device crashes.
|
||||
|
||||
Change-Id: I110172a43f28528dd274b3b346eb29c3796ff2c6
|
||||
Merged-In: I110172a43f28528dd274b3b346eb29c3796ff2c6
|
||||
(cherry picked from commit de172ba0d434c940be9e2aad8685719731ab7da2)
|
||||
(cherry picked from commit c4b2c877ec28e2473104d9fcdcf321bd81da881b)
|
||||
Merged-In: I110172a43f28528dd274b3b346eb29c3796ff2c6
|
||||
---
|
||||
core/java/android/app/AutomaticZenRule.java | 50 ++++++++++++++++++---
|
||||
1 file changed, 43 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java
|
||||
index cd4ace669b6c..29dd91ec1ad6 100644
|
||||
--- a/core/java/android/app/AutomaticZenRule.java
|
||||
+++ b/core/java/android/app/AutomaticZenRule.java
|
||||
@@ -36,6 +36,13 @@ public final class AutomaticZenRule implements Parcelable {
|
||||
private ComponentName owner;
|
||||
private long creationTime;
|
||||
|
||||
+ /**
|
||||
+ * The maximum string length for any string contained in this automatic zen rule. This pertains
|
||||
+ * both to fields in the rule itself (such as its name) and items with sub-fields.
|
||||
+ * @hide
|
||||
+ */
|
||||
+ public static final int MAX_STRING_LENGTH = 1000;
|
||||
+
|
||||
/**
|
||||
* Creates an automatic zen rule.
|
||||
*
|
||||
@@ -50,9 +57,9 @@ public final class AutomaticZenRule implements Parcelable {
|
||||
*/
|
||||
public AutomaticZenRule(String name, ComponentName owner, Uri conditionId,
|
||||
int interruptionFilter, boolean enabled) {
|
||||
- this.name = name;
|
||||
- this.owner = owner;
|
||||
- this.conditionId = conditionId;
|
||||
+ this.name = getTrimmedString(name);
|
||||
+ this.owner = getTrimmedComponentName(owner);
|
||||
+ this.conditionId = getTrimmedUri(conditionId);
|
||||
this.interruptionFilter = interruptionFilter;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
@@ -70,11 +77,11 @@ public final class AutomaticZenRule implements Parcelable {
|
||||
public AutomaticZenRule(Parcel source) {
|
||||
enabled = source.readInt() == 1;
|
||||
if (source.readInt() == 1) {
|
||||
- name = source.readString();
|
||||
+ name = getTrimmedString(source.readString());
|
||||
}
|
||||
interruptionFilter = source.readInt();
|
||||
conditionId = source.readParcelable(null);
|
||||
- owner = source.readParcelable(null);
|
||||
+ owner = getTrimmedComponentName(source.readParcelable(null));
|
||||
creationTime = source.readLong();
|
||||
}
|
||||
|
||||
@@ -124,7 +131,7 @@ public final class AutomaticZenRule implements Parcelable {
|
||||
* Sets the representation of the state that causes this rule to become active.
|
||||
*/
|
||||
public void setConditionId(Uri conditionId) {
|
||||
- this.conditionId = conditionId;
|
||||
+ this.conditionId = getTrimmedUri(conditionId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +146,7 @@ public final class AutomaticZenRule implements Parcelable {
|
||||
* Sets the name of this rule.
|
||||
*/
|
||||
public void setName(String name) {
|
||||
- this.name = name;
|
||||
+ this.name = getTrimmedString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,4 +217,33 @@ public final class AutomaticZenRule implements Parcelable {
|
||||
return new AutomaticZenRule[size];
|
||||
}
|
||||
};
|
||||
+
|
||||
+ /**
|
||||
+ * If the package or class name of the provided ComponentName are longer than MAX_STRING_LENGTH,
|
||||
+ * return a trimmed version that truncates each of the package and class name at the max length.
|
||||
+ */
|
||||
+ private static ComponentName getTrimmedComponentName(ComponentName cn) {
|
||||
+ if (cn == null) return null;
|
||||
+ return new ComponentName(getTrimmedString(cn.getPackageName()),
|
||||
+ getTrimmedString(cn.getClassName()));
|
||||
+ }
|
||||
+ /**
|
||||
+ * Returns a truncated copy of the string if the string is longer than MAX_STRING_LENGTH.
|
||||
+ */
|
||||
+ private static String getTrimmedString(String input) {
|
||||
+ if (input != null && input.length() > MAX_STRING_LENGTH) {
|
||||
+ return input.substring(0, MAX_STRING_LENGTH);
|
||||
+ }
|
||||
+ return input;
|
||||
+ }
|
||||
+ /**
|
||||
+ * Returns a truncated copy of the Uri by trimming the string representation to the maximum
|
||||
+ * string length.
|
||||
+ */
|
||||
+ private static Uri getTrimmedUri(Uri input) {
|
||||
+ if (input != null && input.toString().length() > MAX_STRING_LENGTH) {
|
||||
+ return Uri.parse(getTrimmedString(input.toString()));
|
||||
+ }
|
||||
+ return input;
|
||||
+ }
|
||||
}
|
202
Patches/LineageOS-16.0/android_frameworks_base/344173.patch
Normal file
202
Patches/LineageOS-16.0/android_frameworks_base/344173.patch
Normal file
|
@ -0,0 +1,202 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ivan Chiang <chiangi@google.com>
|
||||
Date: Mon, 15 Aug 2022 15:09:33 +0800
|
||||
Subject: [PATCH] Check permission for VoiceInteraction
|
||||
|
||||
The service must have the CAPTURE_AUDIO_HOTWORD permission to access
|
||||
AlwaysOnHotwordDetector. If it doesn't have the permission, return
|
||||
STATE_HARDWARE_UNAVAILABLE state. If it is not granted the
|
||||
RECORD_AUDIO permisison, it also can't start to recognize the audio.
|
||||
|
||||
Test: manual
|
||||
Test: atest CtsVoiceInteractionTestCases
|
||||
Test: atest CtsAssistTestCases
|
||||
Bug: 229793943
|
||||
Change-Id: I7d0f8d2f6af4bc4210060f0a44469db2afc7a1bb
|
||||
Merged-In: I7d0f8d2f6af4bc4210060f0a44469db2afc7a1bb
|
||||
(cherry picked from commit e4e77f45700bcbc56aa6d6ffc094e0e0ae78190a)
|
||||
Merged-In: I7d0f8d2f6af4bc4210060f0a44469db2afc7a1bb
|
||||
---
|
||||
.../voice/AlwaysOnHotwordDetector.java | 40 ++++++++++++++++++-
|
||||
.../voice/VoiceInteractionService.java | 2 +-
|
||||
.../VoiceInteractionManagerService.java | 14 +++++++
|
||||
3 files changed, 53 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
|
||||
index 76d89ef039c8..350a4169287f 100644
|
||||
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
|
||||
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
|
||||
@@ -16,11 +16,14 @@
|
||||
|
||||
package android.service.voice;
|
||||
|
||||
+import android.Manifest;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
+import android.content.Context;
|
||||
import android.content.Intent;
|
||||
+import android.content.pm.PackageManager;
|
||||
import android.hardware.soundtrigger.IRecognitionStatusCallback;
|
||||
import android.hardware.soundtrigger.KeyphraseEnrollmentInfo;
|
||||
import android.hardware.soundtrigger.KeyphraseMetadata;
|
||||
@@ -194,8 +197,10 @@ public class AlwaysOnHotwordDetector {
|
||||
private final Callback mExternalCallback;
|
||||
private final Object mLock = new Object();
|
||||
private final Handler mHandler;
|
||||
+ private final Context mContext;
|
||||
|
||||
private int mAvailability = STATE_NOT_READY;
|
||||
+ private boolean mIsGrantedHotwordPermission;
|
||||
|
||||
/**
|
||||
* Additional payload for {@link Callback#onDetected}.
|
||||
@@ -322,19 +327,32 @@ public class AlwaysOnHotwordDetector {
|
||||
public abstract void onRecognitionResumed();
|
||||
}
|
||||
|
||||
+ private static boolean hasHotwordPermission(Context context) {
|
||||
+ return context.checkSelfPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD)
|
||||
+ == PackageManager.PERMISSION_GRANTED;
|
||||
+ }
|
||||
+
|
||||
+ private static boolean hasRecordAudioPermission(Context context) {
|
||||
+ return context.checkSelfPermission(Manifest.permission.RECORD_AUDIO)
|
||||
+ == PackageManager.PERMISSION_GRANTED;
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
+ * @param context The context to check permission
|
||||
* @param text The keyphrase text to get the detector for.
|
||||
* @param locale The java locale for the detector.
|
||||
* @param callback A non-null Callback for receiving the recognition events.
|
||||
+ * @param keyphraseEnrollmentInfo The Enrollment info of key phrase
|
||||
* @param voiceInteractionService The current voice interaction service.
|
||||
* @param modelManagementService A service that allows management of sound models.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
- public AlwaysOnHotwordDetector(String text, Locale locale, Callback callback,
|
||||
+ public AlwaysOnHotwordDetector(Context context, String text, Locale locale, Callback callback,
|
||||
KeyphraseEnrollmentInfo keyphraseEnrollmentInfo,
|
||||
IVoiceInteractionService voiceInteractionService,
|
||||
IVoiceInteractionManagerService modelManagementService) {
|
||||
+ mContext = context;
|
||||
mText = text;
|
||||
mLocale = locale;
|
||||
mKeyphraseEnrollmentInfo = keyphraseEnrollmentInfo;
|
||||
@@ -344,6 +362,7 @@ public class AlwaysOnHotwordDetector {
|
||||
mInternalCallback = new SoundTriggerListener(mHandler);
|
||||
mVoiceInteractionService = voiceInteractionService;
|
||||
mModelManagementService = modelManagementService;
|
||||
+ mIsGrantedHotwordPermission = hasHotwordPermission(mContext);
|
||||
new RefreshAvailabiltyTask().execute();
|
||||
}
|
||||
|
||||
@@ -400,6 +419,12 @@ public class AlwaysOnHotwordDetector {
|
||||
*/
|
||||
public boolean startRecognition(@RecognitionFlags int recognitionFlags) {
|
||||
if (DBG) Slog.d(TAG, "startRecognition(" + recognitionFlags + ")");
|
||||
+
|
||||
+ if (!mIsGrantedHotwordPermission || !hasRecordAudioPermission(mContext)) {
|
||||
+ throw new IllegalStateException("Must have the RECORD_AUDIO and CAPTURE_AUDIO_HOTWORD "
|
||||
+ + "permissions to access the detector.");
|
||||
+ }
|
||||
+
|
||||
synchronized (mLock) {
|
||||
if (mAvailability == STATE_INVALID) {
|
||||
throw new IllegalStateException("startRecognition called on an invalid detector");
|
||||
@@ -428,6 +453,12 @@ public class AlwaysOnHotwordDetector {
|
||||
*/
|
||||
public boolean stopRecognition() {
|
||||
if (DBG) Slog.d(TAG, "stopRecognition()");
|
||||
+
|
||||
+ if (!mIsGrantedHotwordPermission || !hasRecordAudioPermission(mContext)) {
|
||||
+ throw new IllegalStateException("Must have the RECORD_AUDIO and CAPTURE_AUDIO_HOTWORD "
|
||||
+ + "permissions to access the detector.");
|
||||
+ }
|
||||
+
|
||||
synchronized (mLock) {
|
||||
if (mAvailability == STATE_INVALID) {
|
||||
throw new IllegalStateException("stopRecognition called on an invalid detector");
|
||||
@@ -544,7 +575,8 @@ public class AlwaysOnHotwordDetector {
|
||||
synchronized (mLock) {
|
||||
if (mAvailability == STATE_INVALID
|
||||
|| mAvailability == STATE_HARDWARE_UNAVAILABLE
|
||||
- || mAvailability == STATE_KEYPHRASE_UNSUPPORTED) {
|
||||
+ || mAvailability == STATE_KEYPHRASE_UNSUPPORTED
|
||||
+ || !hasRecordAudioPermission(mContext)) {
|
||||
Slog.w(TAG, "Received onSoundModelsChanged for an unsupported keyphrase/config");
|
||||
return;
|
||||
}
|
||||
@@ -715,6 +747,10 @@ public class AlwaysOnHotwordDetector {
|
||||
* @return The initial availability without checking the enrollment status.
|
||||
*/
|
||||
private int internalGetInitialAvailability() {
|
||||
+ if (!mIsGrantedHotwordPermission) {
|
||||
+ return STATE_HARDWARE_UNAVAILABLE;
|
||||
+ }
|
||||
+
|
||||
synchronized (mLock) {
|
||||
// This detector has already been invalidated.
|
||||
if (mAvailability == STATE_INVALID) {
|
||||
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
|
||||
index 8f79bcffa776..409d8ddddc2d 100644
|
||||
--- a/core/java/android/service/voice/VoiceInteractionService.java
|
||||
+++ b/core/java/android/service/voice/VoiceInteractionService.java
|
||||
@@ -272,7 +272,7 @@ public class VoiceInteractionService extends Service {
|
||||
synchronized (mLock) {
|
||||
// Allow only one concurrent recognition via the APIs.
|
||||
safelyShutdownHotwordDetector();
|
||||
- mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback,
|
||||
+ mHotwordDetector = new AlwaysOnHotwordDetector(this, keyphrase, locale, callback,
|
||||
mKeyphraseEnrollmentInfo, mInterface, mSystemService);
|
||||
}
|
||||
return mHotwordDetector;
|
||||
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
|
||||
index 44f55511f940..e6e3ef372e28 100644
|
||||
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
|
||||
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
|
||||
@@ -902,6 +902,9 @@ public class VoiceInteractionManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public ModuleProperties getDspModuleProperties(IVoiceInteractionService service) {
|
||||
+ // Allow the call if it is granted CAPTURE_AUDIO_HOTWORD.
|
||||
+ enforceCallingPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD);
|
||||
+
|
||||
// Allow the call if this is the current voice interaction service.
|
||||
synchronized (this) {
|
||||
if (mImpl == null || mImpl.mService == null
|
||||
@@ -923,6 +926,9 @@ public class VoiceInteractionManagerService extends SystemService {
|
||||
public int startRecognition(IVoiceInteractionService service, int keyphraseId,
|
||||
String bcp47Locale, IRecognitionStatusCallback callback,
|
||||
RecognitionConfig recognitionConfig) {
|
||||
+ // Allow the call if it is granted RECORD_AUDIO and CAPTURE_AUDIO_HOTWORD.
|
||||
+ enforceAlwaysOnHotwordPermissions();
|
||||
+
|
||||
// Allow the call if this is the current voice interaction service.
|
||||
synchronized (this) {
|
||||
if (mImpl == null || mImpl.mService == null
|
||||
@@ -963,6 +969,9 @@ public class VoiceInteractionManagerService extends SystemService {
|
||||
@Override
|
||||
public int stopRecognition(IVoiceInteractionService service, int keyphraseId,
|
||||
IRecognitionStatusCallback callback) {
|
||||
+ // Allow the call if it is granted RECORD_AUDIO and CAPTURE_AUDIO_HOTWORD.
|
||||
+ enforceAlwaysOnHotwordPermissions();
|
||||
+
|
||||
// Allow the call if this is the current voice interaction service.
|
||||
synchronized (this) {
|
||||
if (mImpl == null || mImpl.mService == null
|
||||
@@ -1172,6 +1181,11 @@ public class VoiceInteractionManagerService extends SystemService {
|
||||
mSoundTriggerInternal.dump(fd, pw, args);
|
||||
}
|
||||
|
||||
+ private void enforceAlwaysOnHotwordPermissions() {
|
||||
+ enforceCallingPermission(Manifest.permission.RECORD_AUDIO);
|
||||
+ enforceCallingPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD);
|
||||
+ }
|
||||
+
|
||||
private void enforceCallingPermission(String permission) {
|
||||
if (mContext.checkCallingOrSelfPermission(permission)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
353
Patches/LineageOS-16.0/android_frameworks_base/344174.patch
Normal file
353
Patches/LineageOS-16.0/android_frameworks_base/344174.patch
Normal file
|
@ -0,0 +1,353 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Pietal <mpietal@google.com>
|
||||
Date: Thu, 18 Aug 2022 12:04:43 +0000
|
||||
Subject: [PATCH] Do not dismiss keyguard after SIM PUK unlock
|
||||
|
||||
After PUK unlock, multiple calls to
|
||||
KeyguardSecurityContainerController#dismiss() were being called from
|
||||
the KeyguardSimPukViewController, which begins the transition to the
|
||||
next security screen, if any. At the same time, other parts of the
|
||||
system, also listening to SIM events, recognize the PUK unlock and
|
||||
call KeyguardSecurityContainer#showSecurityScreen, which updates which
|
||||
security method comes next. After boot, this should be one of PIN,
|
||||
Password, Pattern, assuming they have a security method. If one of the
|
||||
first dismiss() calls comes AFTER the security method changes, this is
|
||||
incorrectly recognized by the code as a successful
|
||||
PIN/pattern/password unlock. This causes the keyguard to be marked as
|
||||
done, causing screen flickers and incorrect system state.
|
||||
|
||||
The solution: every call to dismiss() should include a new parameter
|
||||
for the security method used. If there is a difference between this
|
||||
parameter and the current value in KeyguardSecurityContainerCallback,
|
||||
ignore the request, as the system state has changed.
|
||||
|
||||
Bug: 218500036
|
||||
Test: atest KeyguardSecurityContainerTest
|
||||
|
||||
Merged-In: I7c8714a177bc85fbce92f6e8fe911f74ca2ac243
|
||||
Change-Id: I30226bc7b5eda9480d471b35fe81e106b0491ff8
|
||||
(cherry picked from commit a30148b8a40a36cababba1ff434d053cfd7dd6e3)
|
||||
Merged-In: I30226bc7b5eda9480d471b35fe81e106b0491ff8
|
||||
---
|
||||
.../keyguard/KeyguardAbsKeyInputView.java | 4 ++-
|
||||
.../android/keyguard/KeyguardHostView.java | 13 +++++---
|
||||
.../com/android/keyguard/KeyguardPINView.java | 6 ++++
|
||||
.../keyguard/KeyguardPasswordView.java | 6 ++++
|
||||
.../android/keyguard/KeyguardPatternView.java | 3 +-
|
||||
.../keyguard/KeyguardSecurityCallback.java | 5 ++-
|
||||
.../keyguard/KeyguardSecurityContainer.java | 32 +++++++++++++++----
|
||||
.../android/keyguard/KeyguardSimPinView.java | 10 +++++-
|
||||
.../android/keyguard/KeyguardSimPukView.java | 12 +++++--
|
||||
9 files changed, 73 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
|
||||
index c3119793eaf5..959da444cee7 100644
|
||||
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
|
||||
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
|
||||
@@ -29,6 +29,7 @@ import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
import com.android.internal.util.LatencyTracker;
|
||||
import com.android.internal.widget.LockPatternChecker;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
@@ -92,6 +93,7 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
|
||||
|
||||
protected abstract int getPasswordTextViewId();
|
||||
protected abstract void resetState();
|
||||
+ protected abstract SecurityMode getSecurityMode();
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
@@ -191,7 +193,7 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
|
||||
mCallback.reportUnlockAttempt(userId, true, 0);
|
||||
if (dismissKeyguard) {
|
||||
mDismissing = true;
|
||||
- mCallback.dismiss(true, userId);
|
||||
+ mCallback.dismiss(true, userId, getSecurityMode());
|
||||
}
|
||||
} else {
|
||||
if (isValidPassword) {
|
||||
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
|
||||
index aa0bcc5cf2b8..27e7d79bd6f5 100644
|
||||
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
|
||||
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
|
||||
@@ -89,7 +89,7 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback {
|
||||
// the user proved presence via some other way to the trust agent.
|
||||
Log.i(TAG, "TrustAgent dismissed Keyguard.");
|
||||
}
|
||||
- dismiss(false /* authenticated */, userId);
|
||||
+ dismiss(false /* authenticated */, userId, SecurityMode.Invalid);
|
||||
} else {
|
||||
mViewMediatorCallback.playTrustedSound();
|
||||
}
|
||||
@@ -189,12 +189,13 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback {
|
||||
* @return True if the keyguard is done.
|
||||
*/
|
||||
public boolean dismiss(int targetUserId) {
|
||||
- return dismiss(false, targetUserId);
|
||||
+ return dismiss(false, targetUserId, getCurrentSecurityMode());
|
||||
}
|
||||
|
||||
public boolean handleBackKey() {
|
||||
if (mSecurityContainer.getCurrentSecuritySelection() != SecurityMode.None) {
|
||||
- mSecurityContainer.dismiss(false, KeyguardUpdateMonitor.getCurrentUser());
|
||||
+ mSecurityContainer.dismiss(false, KeyguardUpdateMonitor.getCurrentUser(),
|
||||
+ getCurrentSecurityMode());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -205,8 +206,10 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean dismiss(boolean authenticated, int targetUserId) {
|
||||
- return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated, targetUserId);
|
||||
+ public boolean dismiss(boolean authenticated, int targetUserId,
|
||||
+ SecurityMode expectedSecurityMode) {
|
||||
+ return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated, targetUserId,
|
||||
+ expectedSecurityMode);
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
|
||||
index 4058d3e0f6c0..c75997a89c2e 100644
|
||||
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
|
||||
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
|
||||
@@ -23,6 +23,7 @@ import android.view.ViewGroup;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
import com.android.settingslib.animation.AppearAnimationUtils;
|
||||
import com.android.settingslib.animation.DisappearAnimationUtils;
|
||||
|
||||
@@ -212,4 +213,9 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public SecurityMode getSecurityMode() {
|
||||
+ return SecurityMode.PIN;
|
||||
+ }
|
||||
}
|
||||
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
|
||||
index 5dd2655a8f16..16cb7796d13f 100644
|
||||
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
|
||||
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
|
||||
@@ -36,6 +36,7 @@ import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
|
||||
import com.android.internal.widget.TextViewInputDisabler;
|
||||
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
|
||||
import java.util.List;
|
||||
/**
|
||||
@@ -368,4 +369,9 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
|
||||
return getContext().getString(
|
||||
com.android.internal.R.string.keyguard_accessibility_password_unlock);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public SecurityMode getSecurityMode() {
|
||||
+ return SecurityMode.Password;
|
||||
+ }
|
||||
}
|
||||
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
|
||||
index 69e3b0d50020..ef2ef4febcac 100644
|
||||
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
|
||||
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
|
||||
@@ -37,6 +37,7 @@ import com.android.internal.util.LatencyTracker;
|
||||
import com.android.internal.widget.LockPatternChecker;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.LockPatternView;
|
||||
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
import com.android.settingslib.animation.AppearAnimationCreator;
|
||||
import com.android.settingslib.animation.AppearAnimationUtils;
|
||||
import com.android.settingslib.animation.DisappearAnimationUtils;
|
||||
@@ -321,7 +322,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
|
||||
mCallback.reportUnlockAttempt(userId, true, 0);
|
||||
if (dismissKeyguard) {
|
||||
mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
|
||||
- mCallback.dismiss(true, userId);
|
||||
+ mCallback.dismiss(true, userId, SecurityMode.Pattern);
|
||||
}
|
||||
} else {
|
||||
mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
|
||||
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
|
||||
index 5b743c1a20c5..c8eec6b80897 100644
|
||||
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
|
||||
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
|
||||
@@ -15,14 +15,17 @@
|
||||
*/
|
||||
package com.android.keyguard;
|
||||
|
||||
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
+
|
||||
public interface KeyguardSecurityCallback {
|
||||
|
||||
/**
|
||||
* Dismiss the given security screen.
|
||||
* @param securityVerified true if the user correctly entered credentials for the given screen.
|
||||
* @param targetUserId a user that needs to be the foreground user at the dismissal completion.
|
||||
+ * @param expectedSecurityMode The security mode that is invoking this dismiss.
|
||||
*/
|
||||
- void dismiss(boolean securityVerified, int targetUserId);
|
||||
+ void dismiss(boolean securityVerified, int targetUserId, SecurityMode expectedSecurityMode);
|
||||
|
||||
/**
|
||||
* Manually report user activity to keep the device awake.
|
||||
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
|
||||
index 9c69432d3178..6a71cf84759c 100644
|
||||
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
|
||||
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
|
||||
@@ -54,7 +54,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
|
||||
|
||||
// Used to notify the container when something interesting happens.
|
||||
public interface SecurityCallback {
|
||||
- public boolean dismiss(boolean authenticated, int targetUserId);
|
||||
+ public boolean dismiss(boolean authenticated, int targetUserId,
|
||||
+ SecurityMode expectedSecurityMode);
|
||||
public void userActivity();
|
||||
public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput);
|
||||
|
||||
@@ -312,10 +313,20 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
|
||||
* @param authenticated true if the user entered the correct authentication
|
||||
* @param targetUserId a user that needs to be the foreground user at the finish (if called)
|
||||
* completion.
|
||||
+ * @param expectedSecurityMode SecurityMode that is invoking this request. SecurityMode.Invalid
|
||||
+ * indicates that no check should be done
|
||||
* @return true if keyguard is done
|
||||
*/
|
||||
- boolean showNextSecurityScreenOrFinish(boolean authenticated, int targetUserId) {
|
||||
+ boolean showNextSecurityScreenOrFinish(boolean authenticated, int targetUserId,
|
||||
+ SecurityMode expectedSecurityMode) {
|
||||
if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
|
||||
+ if (expectedSecurityMode != SecurityMode.Invalid
|
||||
+ && expectedSecurityMode != getCurrentSecurityMode()) {
|
||||
+ Log.w(TAG, "Attempted to invoke showNextSecurityScreenOrFinish with securityMode "
|
||||
+ + expectedSecurityMode + ", but current mode is " + getCurrentSecurityMode());
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
boolean finish = false;
|
||||
boolean strongAuth = false;
|
||||
if (mUpdateMonitor.getUserCanSkipBouncer(targetUserId)) {
|
||||
@@ -417,8 +428,13 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
|
||||
}
|
||||
}
|
||||
|
||||
- public void dismiss(boolean authenticated, int targetId) {
|
||||
- mSecurityCallback.dismiss(authenticated, targetId);
|
||||
+ /**
|
||||
+ * Potentially dismiss the current security screen, after validating that all device
|
||||
+ * security has been unlocked. Otherwise show the next screen.
|
||||
+ */
|
||||
+ public void dismiss(boolean authenticated, int targetId,
|
||||
+ SecurityMode expectedSecurityMode) {
|
||||
+ mSecurityCallback.dismiss(authenticated, targetId, expectedSecurityMode);
|
||||
}
|
||||
|
||||
public boolean isVerifyUnlockOnly() {
|
||||
@@ -454,7 +470,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
|
||||
@Override
|
||||
public boolean isVerifyUnlockOnly() { return false; }
|
||||
@Override
|
||||
- public void dismiss(boolean securityVerified, int targetUserId) { }
|
||||
+ public void dismiss(boolean securityVerified, int targetUserId,
|
||||
+ SecurityMode expectedSecurityMode) { }
|
||||
@Override
|
||||
public void reset() {}
|
||||
};
|
||||
@@ -500,8 +517,9 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
|
||||
return mCurrentSecuritySelection;
|
||||
}
|
||||
|
||||
- public void dismiss(boolean authenticated, int targetUserId) {
|
||||
- mCallback.dismiss(authenticated, targetUserId);
|
||||
+ public void dismiss(boolean authenticated, int targetUserId,
|
||||
+ SecurityMode expectedSecurityMode) {
|
||||
+ mCallback.dismiss(authenticated, targetUserId, expectedSecurityMode);
|
||||
}
|
||||
|
||||
public boolean needsInput() {
|
||||
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
|
||||
index df9fb355ce2f..f2cfdd2f4c86 100644
|
||||
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
|
||||
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
|
||||
@@ -42,6 +42,8 @@ import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
|
||||
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
+
|
||||
/**
|
||||
* Displays a PIN pad for unlocking.
|
||||
*/
|
||||
@@ -342,7 +344,8 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView {
|
||||
mRemainingAttempts = -1;
|
||||
mShowDefaultMessage = true;
|
||||
if (mCallback != null) {
|
||||
- mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
|
||||
+ mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser(),
|
||||
+ SecurityMode.SimPin);
|
||||
}
|
||||
} else {
|
||||
mShowDefaultMessage = false;
|
||||
@@ -390,5 +393,10 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView {
|
||||
return getContext().getString(
|
||||
com.android.internal.R.string.keyguard_accessibility_sim_pin_unlock);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public SecurityMode getSecurityMode() {
|
||||
+ return SecurityMode.SimPin;
|
||||
+ }
|
||||
}
|
||||
|
||||
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
|
||||
index 5da764d90f73..08ba8d4ef6e8 100644
|
||||
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
|
||||
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
|
||||
@@ -40,6 +40,7 @@ import com.android.internal.telephony.ITelephony;
|
||||
import com.android.internal.telephony.IccCardConstants;
|
||||
import com.android.internal.telephony.PhoneConstants;
|
||||
import com.android.internal.telephony.IccCardConstants.State;
|
||||
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
|
||||
|
||||
/**
|
||||
@@ -78,7 +79,8 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
|
||||
// mCallback can be null if onSimStateChanged callback is called when keyguard
|
||||
// isn't active.
|
||||
if (mCallback != null) {
|
||||
- mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
|
||||
+ mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser(),
|
||||
+ SecurityMode.SimPuk);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -408,7 +410,8 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
|
||||
mRemainingAttempts = -1;
|
||||
mShowDefaultMessage = true;
|
||||
if (mCallback != null) {
|
||||
- mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
|
||||
+ mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser(),
|
||||
+ SecurityMode.SimPuk);
|
||||
}
|
||||
} else {
|
||||
mShowDefaultMessage = false;
|
||||
@@ -463,6 +466,11 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
|
||||
return getContext().getString(
|
||||
com.android.internal.R.string.keyguard_accessibility_sim_puk_unlock);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public SecurityMode getSecurityMode() {
|
||||
+ return SecurityMode.SimPuk;
|
||||
+ }
|
||||
}
|
||||
|
||||
|
38
Patches/LineageOS-16.0/android_frameworks_base/345892.patch
Normal file
38
Patches/LineageOS-16.0/android_frameworks_base/345892.patch
Normal file
|
@ -0,0 +1,38 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Oli Lan <olilan@google.com>
|
||||
Date: Tue, 19 Jul 2022 10:45:22 +0000
|
||||
Subject: [PATCH] Revert "RESTRICT AUTOMERGE Prevent non-admin users from
|
||||
deleting system apps."
|
||||
|
||||
This reverts commit 4005549db2fa7e1524fc0dbbe22c774fb00b6cb3.
|
||||
|
||||
Reason for revert: Regression, DELETE_SYSTEM_APP flag no longer works
|
||||
|
||||
Change-Id: I7386d1ba3d61b95836b85c52214c83b216c478e8
|
||||
(cherry picked from commit 49d8f9325a8d103497632097010899f87f403faa)
|
||||
Merged-In: I7386d1ba3d61b95836b85c52214c83b216c478e8
|
||||
---
|
||||
.../com/android/server/pm/PackageManagerService.java | 10 ----------
|
||||
1 file changed, 10 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
index e8532ce4edd3..dc44fe17722d 100644
|
||||
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
@@ -18476,16 +18476,6 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
- if (isSystemApp(uninstalledPs)) {
|
||||
- UserInfo userInfo = sUserManager.getUserInfo(userId);
|
||||
- if (userInfo == null || !userInfo.isAdmin()) {
|
||||
- Slog.w(TAG, "Not removing package " + packageName
|
||||
- + " as only admin user may downgrade system apps");
|
||||
- EventLog.writeEvent(0x534e4554, "170646036", -1, packageName);
|
||||
- return PackageManager.DELETE_FAILED_USER_RESTRICTED;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
// Static shared libs can be declared by any package, so let us not
|
||||
// allow removing a package if it provides a lib others depend on.
|
||||
pkg = mPackages.get(packageName);
|
325
Patches/LineageOS-16.0/android_frameworks_base/345893.patch
Normal file
325
Patches/LineageOS-16.0/android_frameworks_base/345893.patch
Normal file
|
@ -0,0 +1,325 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Reynolds <juliacr@google.com>
|
||||
Date: Fri, 19 Aug 2022 09:54:23 -0400
|
||||
Subject: [PATCH] Limit the size of NotificationChannel and
|
||||
NotificationChannelGroup
|
||||
|
||||
Test: android.app.NotificationChannelGroupTest
|
||||
Test: android.app.NotificationChannelTest
|
||||
Test: cts NotificationChannelTest
|
||||
Test: cts NotificationChannelGroupTest
|
||||
Bug: 241764350
|
||||
Bug: 241764340
|
||||
Bug: 241764135
|
||||
Bug: 242702935
|
||||
Bug: 242703118
|
||||
Bug: 242703202
|
||||
Bug: 242702851
|
||||
Bug: 242703217
|
||||
Bug: 242703556
|
||||
Change-Id: I0925583ab54d6c81c415859618f6b907ab7baada
|
||||
Merged-In: I0925583ab54d6c81c415859618f6b907ab7baada
|
||||
(cherry picked from commit 3850857cb0e7f26702d5bd601731d7290390fa3b)
|
||||
(cherry picked from commit c2d264989a2c18af9e3f210f62eba8d987fefb5b)
|
||||
Merged-In: I0925583ab54d6c81c415859618f6b907ab7baada
|
||||
---
|
||||
.../java/android/app/NotificationChannel.java | 19 +++-
|
||||
.../android/app/NotificationChannelGroup.java | 10 +-
|
||||
.../app/NotificationChannelGroupTest.java | 73 +++++++++++++
|
||||
.../android/app/NotificationChannelTest.java | 102 ++++++++++++++++++
|
||||
4 files changed, 195 insertions(+), 9 deletions(-)
|
||||
create mode 100644 core/tests/coretests/src/android/app/NotificationChannelGroupTest.java
|
||||
create mode 100644 core/tests/coretests/src/android/app/NotificationChannelTest.java
|
||||
|
||||
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
|
||||
index ba355f9f9c1d..5c5801d0019b 100644
|
||||
--- a/core/java/android/app/NotificationChannel.java
|
||||
+++ b/core/java/android/app/NotificationChannel.java
|
||||
@@ -55,8 +55,13 @@ public final class NotificationChannel implements Parcelable {
|
||||
/**
|
||||
* The maximum length for text fields in a NotificationChannel. Fields will be truncated at this
|
||||
* limit.
|
||||
+ * @hide
|
||||
*/
|
||||
- private static final int MAX_TEXT_LENGTH = 1000;
|
||||
+ public static final int MAX_TEXT_LENGTH = 1000;
|
||||
+ /**
|
||||
+ * @hide
|
||||
+ */
|
||||
+ public static final int MAX_VIBRATION_LENGTH = 1000;
|
||||
|
||||
private static final String TAG_CHANNEL = "channel";
|
||||
private static final String ATT_NAME = "name";
|
||||
@@ -177,17 +182,17 @@ public final class NotificationChannel implements Parcelable {
|
||||
*/
|
||||
protected NotificationChannel(Parcel in) {
|
||||
if (in.readByte() != 0) {
|
||||
- mId = in.readString();
|
||||
+ mId = getTrimmedString(in.readString());
|
||||
} else {
|
||||
mId = null;
|
||||
}
|
||||
if (in.readByte() != 0) {
|
||||
- mName = in.readString();
|
||||
+ mName = getTrimmedString(in.readString());
|
||||
} else {
|
||||
mName = null;
|
||||
}
|
||||
if (in.readByte() != 0) {
|
||||
- mDesc = in.readString();
|
||||
+ mDesc = getTrimmedString(in.readString());
|
||||
} else {
|
||||
mDesc = null;
|
||||
}
|
||||
@@ -196,18 +201,22 @@ public final class NotificationChannel implements Parcelable {
|
||||
mLockscreenVisibility = in.readInt();
|
||||
if (in.readByte() != 0) {
|
||||
mSound = Uri.CREATOR.createFromParcel(in);
|
||||
+ mSound = Uri.parse(getTrimmedString(mSound.toString()));
|
||||
} else {
|
||||
mSound = null;
|
||||
}
|
||||
mLights = in.readByte() != 0;
|
||||
mVibration = in.createLongArray();
|
||||
+ if (mVibration != null && mVibration.length > MAX_VIBRATION_LENGTH) {
|
||||
+ mVibration = Arrays.copyOf(mVibration, MAX_VIBRATION_LENGTH);
|
||||
+ }
|
||||
mUserLockedFields = in.readInt();
|
||||
mFgServiceShown = in.readByte() != 0;
|
||||
mVibrationEnabled = in.readByte() != 0;
|
||||
mShowBadge = in.readByte() != 0;
|
||||
mDeleted = in.readByte() != 0;
|
||||
if (in.readByte() != 0) {
|
||||
- mGroup = in.readString();
|
||||
+ mGroup = getTrimmedString(in.readString());
|
||||
} else {
|
||||
mGroup = null;
|
||||
}
|
||||
diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java
|
||||
index 0fa3c7fa6492..14c8be38b8a4 100644
|
||||
--- a/core/java/android/app/NotificationChannelGroup.java
|
||||
+++ b/core/java/android/app/NotificationChannelGroup.java
|
||||
@@ -40,8 +40,9 @@ public final class NotificationChannelGroup implements Parcelable {
|
||||
/**
|
||||
* The maximum length for text fields in a NotificationChannelGroup. Fields will be truncated at
|
||||
* this limit.
|
||||
+ * @hide
|
||||
*/
|
||||
- private static final int MAX_TEXT_LENGTH = 1000;
|
||||
+ public static final int MAX_TEXT_LENGTH = 1000;
|
||||
|
||||
private static final String TAG_GROUP = "channelGroup";
|
||||
private static final String ATT_NAME = "name";
|
||||
@@ -75,13 +76,14 @@ public final class NotificationChannelGroup implements Parcelable {
|
||||
*/
|
||||
protected NotificationChannelGroup(Parcel in) {
|
||||
if (in.readByte() != 0) {
|
||||
- mId = in.readString();
|
||||
+ mId = getTrimmedString(in.readString());
|
||||
} else {
|
||||
mId = null;
|
||||
}
|
||||
mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
+ mName = getTrimmedString(mName.toString());
|
||||
if (in.readByte() != 0) {
|
||||
- mDescription = in.readString();
|
||||
+ mDescription = getTrimmedString(in.readString());
|
||||
} else {
|
||||
mDescription = null;
|
||||
}
|
||||
@@ -104,7 +106,7 @@ public final class NotificationChannelGroup implements Parcelable {
|
||||
} else {
|
||||
dest.writeByte((byte) 0);
|
||||
}
|
||||
- TextUtils.writeToParcel(mName, dest, flags);
|
||||
+ TextUtils.writeToParcel(mName.toString(), dest, flags);
|
||||
if (mDescription != null) {
|
||||
dest.writeByte((byte) 1);
|
||||
dest.writeString(mDescription);
|
||||
diff --git a/core/tests/coretests/src/android/app/NotificationChannelGroupTest.java b/core/tests/coretests/src/android/app/NotificationChannelGroupTest.java
|
||||
new file mode 100644
|
||||
index 000000000000..2a3da05eabb3
|
||||
--- /dev/null
|
||||
+++ b/core/tests/coretests/src/android/app/NotificationChannelGroupTest.java
|
||||
@@ -0,0 +1,73 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2022 The Android Open Source Project
|
||||
+ *
|
||||
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
+ * you may not use this file except in compliance with the License.
|
||||
+ * You may obtain a copy of the License at
|
||||
+ *
|
||||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||||
+ *
|
||||
+ * Unless required by applicable law or agreed to in writing, software
|
||||
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+ * See the License for the specific language governing permissions and
|
||||
+ * limitations under the License.
|
||||
+ */
|
||||
+
|
||||
+package android.app;
|
||||
+
|
||||
+import static junit.framework.TestCase.assertEquals;
|
||||
+
|
||||
+import android.os.Parcel;
|
||||
+import android.test.AndroidTestCase;
|
||||
+
|
||||
+import androidx.test.filters.SmallTest;
|
||||
+import androidx.test.runner.AndroidJUnit4;
|
||||
+
|
||||
+import com.google.common.base.Strings;
|
||||
+
|
||||
+import org.junit.Test;
|
||||
+import org.junit.runner.RunWith;
|
||||
+
|
||||
+import java.lang.reflect.Field;
|
||||
+
|
||||
+@RunWith(AndroidJUnit4.class)
|
||||
+@SmallTest
|
||||
+public class NotificationChannelGroupTest {
|
||||
+ private final String CLASS = "android.app.NotificationChannelGroup";
|
||||
+
|
||||
+ @Test
|
||||
+ public void testLongStringFields() {
|
||||
+ NotificationChannelGroup group = new NotificationChannelGroup("my_group_01", "groupName");
|
||||
+
|
||||
+ try {
|
||||
+ String longString = Strings.repeat("A", 65536);
|
||||
+ Field mName = Class.forName(CLASS).getDeclaredField("mName");
|
||||
+ mName.setAccessible(true);
|
||||
+ mName.set(group, longString);
|
||||
+ Field mId = Class.forName(CLASS).getDeclaredField("mId");
|
||||
+ mId.setAccessible(true);
|
||||
+ mId.set(group, longString);
|
||||
+ Field mDescription = Class.forName(CLASS).getDeclaredField("mDescription");
|
||||
+ mDescription.setAccessible(true);
|
||||
+ mDescription.set(group, longString);
|
||||
+ } catch (NoSuchFieldException e) {
|
||||
+ e.printStackTrace();
|
||||
+ } catch (ClassNotFoundException e) {
|
||||
+ e.printStackTrace();
|
||||
+ } catch (IllegalAccessException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+
|
||||
+ Parcel parcel = Parcel.obtain();
|
||||
+ group.writeToParcel(parcel, 0);
|
||||
+ parcel.setDataPosition(0);
|
||||
+
|
||||
+ NotificationChannelGroup fromParcel =
|
||||
+ NotificationChannelGroup.CREATOR.createFromParcel(parcel);
|
||||
+ assertEquals(NotificationChannelGroup.MAX_TEXT_LENGTH, fromParcel.getId().length());
|
||||
+ assertEquals(NotificationChannelGroup.MAX_TEXT_LENGTH, fromParcel.getName().length());
|
||||
+ assertEquals(NotificationChannelGroup.MAX_TEXT_LENGTH,
|
||||
+ fromParcel.getDescription().length());
|
||||
+ }
|
||||
+}
|
||||
diff --git a/core/tests/coretests/src/android/app/NotificationChannelTest.java b/core/tests/coretests/src/android/app/NotificationChannelTest.java
|
||||
new file mode 100644
|
||||
index 000000000000..d8be502e6db6
|
||||
--- /dev/null
|
||||
+++ b/core/tests/coretests/src/android/app/NotificationChannelTest.java
|
||||
@@ -0,0 +1,102 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2022 The Android Open Source Project
|
||||
+ *
|
||||
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
+ * you may not use this file except in compliance with the License.
|
||||
+ * You may obtain a copy of the License at
|
||||
+ *
|
||||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||||
+ *
|
||||
+ * Unless required by applicable law or agreed to in writing, software
|
||||
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+ * See the License for the specific language governing permissions and
|
||||
+ * limitations under the License.
|
||||
+ */
|
||||
+
|
||||
+package android.app;
|
||||
+
|
||||
+import static junit.framework.TestCase.assertEquals;
|
||||
+
|
||||
+import android.net.Uri;
|
||||
+import android.os.Parcel;
|
||||
+
|
||||
+import androidx.test.filters.SmallTest;
|
||||
+import androidx.test.runner.AndroidJUnit4;
|
||||
+
|
||||
+import com.google.common.base.Strings;
|
||||
+
|
||||
+import org.junit.Test;
|
||||
+import org.junit.runner.RunWith;
|
||||
+
|
||||
+import java.lang.reflect.Field;
|
||||
+
|
||||
+@RunWith(AndroidJUnit4.class)
|
||||
+@SmallTest
|
||||
+public class NotificationChannelTest {
|
||||
+ private final String CLASS = "android.app.NotificationChannel";
|
||||
+
|
||||
+ @Test
|
||||
+ public void testLongStringFields() {
|
||||
+ NotificationChannel channel = new NotificationChannel("id", "name", 3);
|
||||
+
|
||||
+ try {
|
||||
+ String longString = Strings.repeat("A", 65536);
|
||||
+ Field mName = Class.forName(CLASS).getDeclaredField("mName");
|
||||
+ mName.setAccessible(true);
|
||||
+ mName.set(channel, longString);
|
||||
+ Field mId = Class.forName(CLASS).getDeclaredField("mId");
|
||||
+ mId.setAccessible(true);
|
||||
+ mId.set(channel, longString);
|
||||
+ Field mDesc = Class.forName(CLASS).getDeclaredField("mDesc");
|
||||
+ mDesc.setAccessible(true);
|
||||
+ mDesc.set(channel, longString);
|
||||
+ Field mParentId = Class.forName(CLASS).getDeclaredField("mParentId");
|
||||
+ mParentId.setAccessible(true);
|
||||
+ mParentId.set(channel, longString);
|
||||
+ Field mGroup = Class.forName(CLASS).getDeclaredField("mGroup");
|
||||
+ mGroup.setAccessible(true);
|
||||
+ mGroup.set(channel, longString);
|
||||
+ Field mConversationId = Class.forName(CLASS).getDeclaredField("mConversationId");
|
||||
+ mConversationId.setAccessible(true);
|
||||
+ mConversationId.set(channel, longString);
|
||||
+ } catch (NoSuchFieldException e) {
|
||||
+ e.printStackTrace();
|
||||
+ } catch (ClassNotFoundException e) {
|
||||
+ e.printStackTrace();
|
||||
+ } catch (IllegalAccessException e) {
|
||||
+ e.printStackTrace();
|
||||
+ }
|
||||
+
|
||||
+ Parcel parcel = Parcel.obtain();
|
||||
+ channel.writeToParcel(parcel, 0);
|
||||
+ parcel.setDataPosition(0);
|
||||
+
|
||||
+ NotificationChannel fromParcel = NotificationChannel.CREATOR.createFromParcel(parcel);
|
||||
+ assertEquals(NotificationChannel.MAX_TEXT_LENGTH, fromParcel.getId().length());
|
||||
+ assertEquals(NotificationChannel.MAX_TEXT_LENGTH, fromParcel.getName().length());
|
||||
+ assertEquals(NotificationChannel.MAX_TEXT_LENGTH,
|
||||
+ fromParcel.getDescription().length());
|
||||
+ assertEquals(NotificationChannel.MAX_TEXT_LENGTH,
|
||||
+ fromParcel.getGroup().length());
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testLongAlertFields() {
|
||||
+ NotificationChannel channel = new NotificationChannel("id", "name", 3);
|
||||
+
|
||||
+ channel.setSound(Uri.parse("content://" + Strings.repeat("A",65536)),
|
||||
+ Notification.AUDIO_ATTRIBUTES_DEFAULT);
|
||||
+ channel.setVibrationPattern(new long[65550/2]);
|
||||
+
|
||||
+ Parcel parcel = Parcel.obtain();
|
||||
+ channel.writeToParcel(parcel, 0);
|
||||
+ parcel.setDataPosition(0);
|
||||
+
|
||||
+ NotificationChannel fromParcel = NotificationChannel.CREATOR.createFromParcel(parcel);
|
||||
+ assertEquals(NotificationChannel.MAX_VIBRATION_LENGTH,
|
||||
+ fromParcel.getVibrationPattern().length);
|
||||
+ assertEquals(NotificationChannel.MAX_TEXT_LENGTH,
|
||||
+ fromParcel.getSound().toString().length());
|
||||
+ }
|
||||
+}
|
46
Patches/LineageOS-16.0/android_frameworks_base/345894.patch
Normal file
46
Patches/LineageOS-16.0/android_frameworks_base/345894.patch
Normal file
|
@ -0,0 +1,46 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Oli Lan <olilan@google.com>
|
||||
Date: Mon, 8 Aug 2022 13:31:36 +0100
|
||||
Subject: [PATCH] RESTRICT AUTOMERGE Prevent non-admin users from deleting
|
||||
system apps.
|
||||
|
||||
This addresses a security issue where the guest user can remove updates
|
||||
for system apps.
|
||||
|
||||
With this CL, attempts to uninstall/downgrade system apps will fail if
|
||||
attempted by a non-admin user, unless the DELETE_SYSTEM_APP flag is
|
||||
specified.
|
||||
|
||||
This is a fixed version of ag/17400663, to address b/236578018.
|
||||
|
||||
Bug: 170646036
|
||||
Test: manual, try uninstalling system app update as guest
|
||||
Change-Id: I5eab215cba6528aa4316ed7b20bee544915c1486
|
||||
(cherry picked from commit 7fdc96aef4e098d2271ac3a8557bd8e1ad6827f3)
|
||||
Merged-In: I5eab215cba6528aa4316ed7b20bee544915c1486
|
||||
---
|
||||
.../com/android/server/pm/PackageManagerService.java | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
index dc44fe17722d..c873f82d740c 100644
|
||||
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
@@ -18476,6 +18476,17 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
+ if (isSystemApp(uninstalledPs)
|
||||
+ && (deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0) {
|
||||
+ UserInfo userInfo = sUserManager.getUserInfo(userId);
|
||||
+ if (userInfo == null || !userInfo.isAdmin()) {
|
||||
+ Slog.w(TAG, "Not removing package " + packageName
|
||||
+ + " as only admin user may downgrade system apps");
|
||||
+ EventLog.writeEvent(0x534e4554, "170646036", -1, packageName);
|
||||
+ return PackageManager.DELETE_FAILED_USER_RESTRICTED;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
// Static shared libs can be declared by any package, so let us not
|
||||
// allow removing a package if it provides a lib others depend on.
|
||||
pkg = mPackages.get(packageName);
|
106
Patches/LineageOS-16.0/android_frameworks_base/345895.patch
Normal file
106
Patches/LineageOS-16.0/android_frameworks_base/345895.patch
Normal file
|
@ -0,0 +1,106 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Oli Lan <olilan@google.com>
|
||||
Date: Fri, 19 Aug 2022 17:08:13 +0100
|
||||
Subject: [PATCH] Validate package name passed to setApplicationRestrictions.
|
||||
|
||||
This adds validation that the package name passed to
|
||||
setApplicationRestrictions is in the correct format. This will avoid
|
||||
an issue where a path could be entered resulting in a file being
|
||||
written to an unexpected place.
|
||||
|
||||
Bug: 239701237
|
||||
Test: atest UserManagerServiceTest
|
||||
Change-Id: I1ab2b7228470f10ec26fe3a608ae540cfc9e9a96
|
||||
(cherry picked from commit 31a582490d6e8952d24f267df47d669e3861cf67)
|
||||
Merged-In: I1ab2b7228470f10ec26fe3a608ae540cfc9e9a96
|
||||
(cherry picked from commit cfcfe6ca8c545f78603c05e23687f8638fd4b51d)
|
||||
Merged-In: I1ab2b7228470f10ec26fe3a608ae540cfc9e9a96
|
||||
---
|
||||
.../android/server/pm/UserManagerService.java | 41 +++++++++++++++++++
|
||||
.../server/pm/UserManagerServiceTest.java | 7 ++++
|
||||
2 files changed, 48 insertions(+)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
|
||||
index 56d737d50fbf..423b88388809 100644
|
||||
--- a/services/core/java/com/android/server/pm/UserManagerService.java
|
||||
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
|
||||
@@ -76,6 +76,7 @@ import android.provider.Settings;
|
||||
import android.security.GateKeeper;
|
||||
import android.service.gatekeeper.IGateKeeperService;
|
||||
import android.util.AtomicFile;
|
||||
+import android.util.EventLog;
|
||||
import android.util.IntArray;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
@@ -3104,6 +3105,13 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
public void setApplicationRestrictions(String packageName, Bundle restrictions,
|
||||
int userId) {
|
||||
checkSystemOrRoot("set application restrictions");
|
||||
+ String validationResult = validateName(packageName);
|
||||
+ if (validationResult != null) {
|
||||
+ if (packageName.contains("../")) {
|
||||
+ EventLog.writeEvent(0x534e4554, "239701237", -1, "");
|
||||
+ }
|
||||
+ throw new IllegalArgumentException("Invalid package name: " + validationResult);
|
||||
+ }
|
||||
if (restrictions != null) {
|
||||
restrictions.setDefusable(true);
|
||||
}
|
||||
@@ -3123,6 +3131,39 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(userId));
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Check if the given name is valid.
|
||||
+ *
|
||||
+ * Note: the logic is taken from FrameworkParsingPackageUtils in master, edited to remove
|
||||
+ * unnecessary parts. Copied here for a security fix.
|
||||
+ *
|
||||
+ * @param name The name to check.
|
||||
+ * @return null if it's valid, error message if not
|
||||
+ */
|
||||
+ @VisibleForTesting
|
||||
+ static String validateName(String name) {
|
||||
+ final int n = name.length();
|
||||
+ boolean front = true;
|
||||
+ for (int i = 0; i < n; i++) {
|
||||
+ final char c = name.charAt(i);
|
||||
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
|
||||
+ front = false;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (!front) {
|
||||
+ if ((c >= '0' && c <= '9') || c == '_') {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (c == '.') {
|
||||
+ front = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ return "bad character '" + c + "'";
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
private int getUidForPackage(String packageName) {
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
|
||||
index d1366144d33b..8da7a76f18ce 100644
|
||||
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
|
||||
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
|
||||
@@ -74,6 +74,13 @@ public class UserManagerServiceTest extends AndroidTestCase {
|
||||
assertEquals(accountName, um.getUserAccount(tempUserId));
|
||||
}
|
||||
|
||||
+ public void testValidateName() {
|
||||
+ assertNull(UserManagerService.validateName("android"));
|
||||
+ assertNull(UserManagerService.validateName("com.company.myapp"));
|
||||
+ assertNotNull(UserManagerService.validateName("/../../data"));
|
||||
+ assertNotNull(UserManagerService.validateName("/dir"));
|
||||
+ }
|
||||
+
|
||||
private Bundle createBundle() {
|
||||
Bundle result = new Bundle();
|
||||
// Tests for 6 allowed types: Integer, Boolean, String, String[], Bundle and Parcelable[]
|
29
Patches/LineageOS-16.0/android_frameworks_base/345896.patch
Normal file
29
Patches/LineageOS-16.0/android_frameworks_base/345896.patch
Normal file
|
@ -0,0 +1,29 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Norman <danielnorman@google.com>
|
||||
Date: Thu, 1 Sep 2022 10:14:24 -0700
|
||||
Subject: [PATCH] Include all enabled services when FEEDBACK_ALL_MASK.
|
||||
|
||||
Bug: 243849844
|
||||
Test: m sts;
|
||||
sts-tradefed run sts-dynamic-develop -m CtsAccessibilityTestCases
|
||||
Change-Id: I4f93e06d1066085bd64e8f09882de2f4a72a0633
|
||||
(cherry picked from commit 2bc4d49c2b0265f5de1c62d1342b1426cc5e1377)
|
||||
Merged-In: I4f93e06d1066085bd64e8f09882de2f4a72a0633
|
||||
---
|
||||
.../server/accessibility/AccessibilityManagerService.java | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
|
||||
index 7798cf7af3cb..58a1beed70c9 100644
|
||||
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
|
||||
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
|
||||
@@ -620,7 +620,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
final List<AccessibilityServiceInfo> result = new ArrayList<>(serviceCount);
|
||||
for (int i = 0; i < serviceCount; ++i) {
|
||||
final AccessibilityServiceConnection service = services.get(i);
|
||||
- if ((service.mFeedbackType & feedbackType) != 0) {
|
||||
+ if ((service.mFeedbackType & feedbackType) != 0
|
||||
+ || feedbackType == AccessibilityServiceInfo.FEEDBACK_ALL_MASK) {
|
||||
result.add(service.getServiceInfo());
|
||||
}
|
||||
}
|
44
Patches/LineageOS-16.0/android_frameworks_base/345897.patch
Normal file
44
Patches/LineageOS-16.0/android_frameworks_base/345897.patch
Normal file
|
@ -0,0 +1,44 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Songchun Fan <schfan@google.com>
|
||||
Date: Fri, 9 Sep 2022 14:50:31 -0700
|
||||
Subject: [PATCH] forbid deletion of protected packages
|
||||
|
||||
BUG: 242996180
|
||||
Test: adb shell pm uninstall --user 0 com.google.android.apps.work.oobconfig
|
||||
Test: Verified with the command above. Before this CL, the package can
|
||||
be deleted. After this CL, the deletion will fail.
|
||||
|
||||
Change-Id: Iba408e536b340ea5d66ab499442c0c4f828fa36f
|
||||
(cherry picked from commit 15f85c7fa97fe9faa540e6ad9e850990f46a5cca)
|
||||
Merged-In: Iba408e536b340ea5d66ab499442c0c4f828fa36f
|
||||
(cherry picked from commit 2e42c393f2d5521d20acd9281d411a0fbc6196c3)
|
||||
Merged-In: Iba408e536b340ea5d66ab499442c0c4f828fa36f
|
||||
---
|
||||
.../android/server/pm/PackageManagerService.java | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
index c873f82d740c..4cd38c15ce52 100644
|
||||
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
@@ -18144,6 +18144,20 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
|
||||
final String packageName = versionedPackage.getPackageName();
|
||||
final long versionCode = versionedPackage.getLongVersionCode();
|
||||
+
|
||||
+ if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
|
||||
+ mHandler.post(() -> {
|
||||
+ try {
|
||||
+ Slog.w(TAG, "Attempted to delete protected package: " + packageName);
|
||||
+ observer.onPackageDeleted(packageName,
|
||||
+ PackageManager.DELETE_FAILED_INTERNAL_ERROR, null);
|
||||
+ } catch (RemoteException re) {
|
||||
+ }
|
||||
+ });
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
final String internalPackageName;
|
||||
synchronized (mPackages) {
|
||||
// Normalize package name to handle renamed packages and static libs
|
93
Patches/LineageOS-16.0/android_frameworks_base/345898.patch
Normal file
93
Patches/LineageOS-16.0/android_frameworks_base/345898.patch
Normal file
|
@ -0,0 +1,93 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Reynolds <juliacr@google.com>
|
||||
Date: Tue, 6 Sep 2022 10:19:06 -0400
|
||||
Subject: [PATCH] Fix NPE
|
||||
|
||||
Test: NotificationChannelGroupTest
|
||||
Test: view notification settings for an app that doesn't use groups
|
||||
Fixes: 244574602
|
||||
Bug: 241764350
|
||||
Bug: 241764340
|
||||
Bug: 241764135
|
||||
Bug: 242702935
|
||||
Bug: 242703118
|
||||
Bug: 242703202
|
||||
Bug: 242702851
|
||||
Bug: 242703217
|
||||
Bug: 242703556
|
||||
Change-Id: I9c681106f6d645e62b0e44903d40aa523fee0e95
|
||||
(cherry picked from commit 6f02c07176d0fa4d6985c8f2200ccf49a1657d1c)
|
||||
(cherry picked from commit a37554289731f0d52923123697d55074b0f41748)
|
||||
Merged-In: I9c681106f6d645e62b0e44903d40aa523fee0e95
|
||||
---
|
||||
.../android/app/NotificationChannelGroup.java | 14 +++++++++++---
|
||||
.../app/NotificationChannelGroupTest.java | 16 ++++++++++++++++
|
||||
2 files changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java
|
||||
index 14c8be38b8a4..87565312448c 100644
|
||||
--- a/core/java/android/app/NotificationChannelGroup.java
|
||||
+++ b/core/java/android/app/NotificationChannelGroup.java
|
||||
@@ -80,8 +80,11 @@ public final class NotificationChannelGroup implements Parcelable {
|
||||
} else {
|
||||
mId = null;
|
||||
}
|
||||
- mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||
- mName = getTrimmedString(mName.toString());
|
||||
+ if (in.readByte() != 0) {
|
||||
+ mName = getTrimmedString(in.readString());
|
||||
+ } else {
|
||||
+ mName = "";
|
||||
+ }
|
||||
if (in.readByte() != 0) {
|
||||
mDescription = getTrimmedString(in.readString());
|
||||
} else {
|
||||
@@ -106,7 +109,12 @@ public final class NotificationChannelGroup implements Parcelable {
|
||||
} else {
|
||||
dest.writeByte((byte) 0);
|
||||
}
|
||||
- TextUtils.writeToParcel(mName.toString(), dest, flags);
|
||||
+ if (mName != null) {
|
||||
+ dest.writeByte((byte) 1);
|
||||
+ dest.writeString(mName.toString());
|
||||
+ } else {
|
||||
+ dest.writeByte((byte) 0);
|
||||
+ }
|
||||
if (mDescription != null) {
|
||||
dest.writeByte((byte) 1);
|
||||
dest.writeString(mDescription);
|
||||
diff --git a/core/tests/coretests/src/android/app/NotificationChannelGroupTest.java b/core/tests/coretests/src/android/app/NotificationChannelGroupTest.java
|
||||
index 2a3da05eabb3..625c66a4c60e 100644
|
||||
--- a/core/tests/coretests/src/android/app/NotificationChannelGroupTest.java
|
||||
+++ b/core/tests/coretests/src/android/app/NotificationChannelGroupTest.java
|
||||
@@ -17,9 +17,11 @@
|
||||
package android.app;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
+import static junit.framework.TestCase.assertTrue;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.test.AndroidTestCase;
|
||||
+import android.text.TextUtils;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
@@ -70,4 +72,18 @@ public class NotificationChannelGroupTest {
|
||||
assertEquals(NotificationChannelGroup.MAX_TEXT_LENGTH,
|
||||
fromParcel.getDescription().length());
|
||||
}
|
||||
+
|
||||
+ @Test
|
||||
+ public void testNullableFields() {
|
||||
+ NotificationChannelGroup group = new NotificationChannelGroup("my_group_01", null);
|
||||
+
|
||||
+ Parcel parcel = Parcel.obtain();
|
||||
+ group.writeToParcel(parcel, 0);
|
||||
+ parcel.setDataPosition(0);
|
||||
+
|
||||
+ NotificationChannelGroup fromParcel =
|
||||
+ NotificationChannelGroup.CREATOR.createFromParcel(parcel);
|
||||
+ assertEquals(group.getId(), fromParcel.getId());
|
||||
+ assertTrue(TextUtils.isEmpty(fromParcel.getName()));
|
||||
+ }
|
||||
}
|
52
Patches/LineageOS-16.0/android_frameworks_base/345899.patch
Normal file
52
Patches/LineageOS-16.0/android_frameworks_base/345899.patch
Normal file
|
@ -0,0 +1,52 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Pinyao Ting <pinyaoting@google.com>
|
||||
Date: Thu, 14 Jul 2022 11:25:54 -0700
|
||||
Subject: [PATCH] Fix a security issue in app widget service.
|
||||
|
||||
Bug: 234013191
|
||||
Test: atest RemoteViewsAdapterTest
|
||||
Change-Id: Icd2eccb7a90124aca18a3dd463c3f79e3a595c20
|
||||
Merged-In: Icd2eccb7a90124aca18a3dd463c3f79e3a595c20
|
||||
(cherry picked from commit 263d7d0ba8818c471a27938c4e002bae33569f01)
|
||||
(cherry picked from commit 0ee21ef3e652c78c934d257632a4951bd6d38011)
|
||||
Merged-In: Icd2eccb7a90124aca18a3dd463c3f79e3a595c20
|
||||
---
|
||||
core/java/android/appwidget/AppWidgetManager.java | 4 +++-
|
||||
.../com/android/server/appwidget/AppWidgetServiceImpl.java | 7 ++++---
|
||||
2 files changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
|
||||
index 20248b90d1e9..b8d33b1c8a17 100644
|
||||
--- a/core/java/android/appwidget/AppWidgetManager.java
|
||||
+++ b/core/java/android/appwidget/AppWidgetManager.java
|
||||
@@ -1089,7 +1089,9 @@ public class AppWidgetManager {
|
||||
* @param intent The intent of the service which will be providing the data to the
|
||||
* RemoteViewsAdapter.
|
||||
* @param connection The callback interface to be notified when a connection is made or lost.
|
||||
- * @param flags Flags used for binding to the service
|
||||
+ * @param flags Flags used for binding to the service. Currently only
|
||||
+ * {@link Context#BIND_AUTO_CREATE} and
|
||||
+ * {@link Context#BIND_FOREGROUND_SERVICE_WHILE_AWAKE} are supported.
|
||||
*
|
||||
* @see Context#getServiceDispatcher(ServiceConnection, Handler, int)
|
||||
* @hide
|
||||
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
|
||||
index da52d408e125..9c18029ec693 100644
|
||||
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
|
||||
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
|
||||
@@ -1299,11 +1299,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
try {
|
||||
// Ask ActivityManager to bind it. Notice that we are binding the service with the
|
||||
// caller app instead of DevicePolicyManagerService.
|
||||
- if(ActivityManager.getService().bindService(
|
||||
+ if (ActivityManager.getService().bindService(
|
||||
caller, activtiyToken, intent,
|
||||
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
|
||||
- connection, flags, mContext.getOpPackageName(),
|
||||
- widget.provider.getUserId()) != 0) {
|
||||
+ connection, flags & (Context.BIND_AUTO_CREATE
|
||||
+ | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE),
|
||||
+ mContext.getOpPackageName(), widget.provider.getUserId()) != 0) {
|
||||
|
||||
// Add it to the mapping of RemoteViewsService to appWidgetIds so that we
|
||||
// can determine when we can call back to the RemoteViewsService later to
|
48
Patches/LineageOS-16.0/android_frameworks_base/345900.patch
Normal file
48
Patches/LineageOS-16.0/android_frameworks_base/345900.patch
Normal file
|
@ -0,0 +1,48 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Pinyao Ting <pinyaoting@google.com>
|
||||
Date: Wed, 21 Sep 2022 23:03:11 +0000
|
||||
Subject: [PATCH] Ignore malformed shortcuts
|
||||
|
||||
After an app publishes a shortcut that contains malformed intent, the
|
||||
system can be stuck in boot-loop due to uncaught exception caused by
|
||||
parsing the malformed intent.
|
||||
|
||||
This CL ignores that particular malformed entry. Since shortcuts are
|
||||
constantly writes back into the xml from system memory, the malformed
|
||||
entry will be removed from the xml the next time system persists
|
||||
shortcuts from memory to file system.
|
||||
|
||||
Bug: 246540168
|
||||
Change-Id: Ie1e39005a5f9d8038bd703a5bc845779c2f46e94
|
||||
Test: manual
|
||||
(cherry picked from commit 9b0dd514d29bbf986f1d1a3c6cebc2ef2bcf782e)
|
||||
Merged-In: Ie1e39005a5f9d8038bd703a5bc845779c2f46e94
|
||||
---
|
||||
.../com/android/server/pm/ShortcutPackage.java | 14 +++++++++-----
|
||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
|
||||
index 92e261a72617..320cd382c2fc 100644
|
||||
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
|
||||
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
|
||||
@@ -1486,11 +1486,15 @@ class ShortcutPackage extends ShortcutPackageItem {
|
||||
|
||||
continue;
|
||||
case TAG_SHORTCUT:
|
||||
- final ShortcutInfo si = parseShortcut(parser, packageName,
|
||||
- shortcutUser.getUserId(), fromBackup);
|
||||
-
|
||||
- // Don't use addShortcut(), we don't need to save the icon.
|
||||
- ret.mShortcuts.put(si.getId(), si);
|
||||
+ try {
|
||||
+ final ShortcutInfo si = parseShortcut(parser, packageName,
|
||||
+ shortcutUser.getUserId(), fromBackup);
|
||||
+ // Don't use addShortcut(), we don't need to save the icon.
|
||||
+ ret.mShortcuts.put(si.getId(), si);
|
||||
+ } catch (Exception e) {
|
||||
+ // b/246540168 malformed shortcuts should be ignored
|
||||
+ Slog.e(TAG, "Failed parsing shortcut.", e);
|
||||
+ }
|
||||
continue;
|
||||
}
|
||||
}
|
32
Patches/LineageOS-16.0/android_frameworks_base/345901.patch
Normal file
32
Patches/LineageOS-16.0/android_frameworks_base/345901.patch
Normal file
|
@ -0,0 +1,32 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Rhed Jao <rhedjao@google.com>
|
||||
Date: Mon, 26 Sep 2022 21:35:26 +0800
|
||||
Subject: [PATCH] Fix permanent denial of service via
|
||||
setComponentEnabledSetting
|
||||
|
||||
Do not update invalid component enabled settings to prevent the
|
||||
malicious apps from exhausting system server memory.
|
||||
|
||||
Bug: 240936919
|
||||
Test: atest android.security.cts.PackageManagerTest
|
||||
Change-Id: I08165337895e89f13a2b9fcce1201cba9ad13d7d
|
||||
(cherry picked from commit 4d13148a3fa5f6bc1b7038fae7d1f1adda163a9f)
|
||||
Merged-In: I08165337895e89f13a2b9fcce1201cba9ad13d7d
|
||||
---
|
||||
.../core/java/com/android/server/pm/PackageManagerService.java | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
index 4cd38c15ce52..5b454f2d8939 100644
|
||||
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
@@ -21244,6 +21244,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
|
||||
} else {
|
||||
Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
|
||||
+ className + " does not exist in " + packageName);
|
||||
+ // Safetynet logging for b/240936919
|
||||
+ EventLog.writeEvent(0x534e4554, "240936919", callingUid);
|
||||
+ return;
|
||||
}
|
||||
}
|
||||
switch (newState) {
|
102
Patches/LineageOS-16.0/android_frameworks_base/345902.patch
Normal file
102
Patches/LineageOS-16.0/android_frameworks_base/345902.patch
Normal file
|
@ -0,0 +1,102 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hao Ke <haok@google.com>
|
||||
Date: Tue, 4 Oct 2022 19:43:58 +0000
|
||||
Subject: [PATCH] Add safety checks on KEY_INTENT mismatch.
|
||||
|
||||
For many years, Parcel mismatch typed exploits has been using the
|
||||
AccoungManagerService's passing of KEY_INTENT workflow, as a foothold of
|
||||
launching arbitrary intents. We are adding an extra check on the service
|
||||
side to simulate the final deserialization of the KEY_INTENT value, to
|
||||
make sure the client side won't get a mismatched KEY_INTENT value.
|
||||
|
||||
Bug: 250588548
|
||||
Bug: 240138294
|
||||
Test: atest CtsAccountManagerTestCases
|
||||
Test: local test, also see b/250588548
|
||||
Change-Id: I433e34f6e21ce15c89825044a15b1dec46bb25cc
|
||||
(cherry picked from commit eb9a0566a583fa13f8aff671c41f78a9e33eab82)
|
||||
Merged-In: I433e34f6e21ce15c89825044a15b1dec46bb25cc
|
||||
---
|
||||
.../accounts/AccountManagerService.java | 34 ++++++++++++++++---
|
||||
1 file changed, 30 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
index 4c8acc5ffb63..c1f401e9a11f 100644
|
||||
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
@@ -87,6 +87,7 @@ import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.TextUtils;
|
||||
+import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
@@ -3001,7 +3002,7 @@ public class AccountManagerService
|
||||
*/
|
||||
if (!checkKeyIntent(
|
||||
Binder.getCallingUid(),
|
||||
- intent)) {
|
||||
+ result)) {
|
||||
onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
|
||||
"invalid intent in bundle returned");
|
||||
return;
|
||||
@@ -3411,7 +3412,7 @@ public class AccountManagerService
|
||||
&& (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
|
||||
if (!checkKeyIntent(
|
||||
Binder.getCallingUid(),
|
||||
- intent)) {
|
||||
+ result)) {
|
||||
onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
|
||||
"invalid intent in bundle returned");
|
||||
return;
|
||||
@@ -4771,7 +4772,13 @@ public class AccountManagerService
|
||||
* into launching arbitrary intents on the device via by tricking to click authenticator
|
||||
* supplied entries in the system Settings app.
|
||||
*/
|
||||
- protected boolean checkKeyIntent(int authUid, Intent intent) {
|
||||
+ protected boolean checkKeyIntent(int authUid, Bundle bundle) {
|
||||
+ if (!checkKeyIntentParceledCorrectly(bundle)) {
|
||||
+ EventLog.writeEvent(0x534e4554, "250588548", authUid, "");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
|
||||
// Explicitly set an empty ClipData to ensure that we don't offer to
|
||||
// promote any Uris contained inside for granting purposes
|
||||
if (intent.getClipData() == null) {
|
||||
@@ -4808,6 +4815,25 @@ public class AccountManagerService
|
||||
}
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Simulate the client side's deserialization of KEY_INTENT value, to make sure they don't
|
||||
+ * violate our security policy.
|
||||
+ *
|
||||
+ * In particular we want to make sure the Authenticator doesn't trick users
|
||||
+ * into launching arbitrary intents on the device via exploiting any other Parcel read/write
|
||||
+ * mismatch problems.
|
||||
+ */
|
||||
+ private boolean checkKeyIntentParceledCorrectly(Bundle bundle) {
|
||||
+ Parcel p = Parcel.obtain();
|
||||
+ p.writeBundle(bundle);
|
||||
+ p.setDataPosition(0);
|
||||
+ Bundle simulateBundle = p.readBundle();
|
||||
+ p.recycle();
|
||||
+ Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
|
||||
+ Intent simulateIntent = simulateBundle.getParcelable(AccountManager.KEY_INTENT);
|
||||
+ return (intent.filterEquals(simulateIntent));
|
||||
+ }
|
||||
+
|
||||
private boolean isExportedSystemActivity(ActivityInfo activityInfo) {
|
||||
String className = activityInfo.name;
|
||||
return "android".equals(activityInfo.packageName) &&
|
||||
@@ -4954,7 +4980,7 @@ public class AccountManagerService
|
||||
&& (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
|
||||
if (!checkKeyIntent(
|
||||
Binder.getCallingUid(),
|
||||
- intent)) {
|
||||
+ result)) {
|
||||
onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
|
||||
"invalid intent in bundle returned");
|
||||
return;
|
86
Patches/LineageOS-16.0/android_frameworks_base/347044.patch
Normal file
86
Patches/LineageOS-16.0/android_frameworks_base/347044.patch
Normal file
|
@ -0,0 +1,86 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yuri Lin <yurilin@google.com>
|
||||
Date: Tue, 13 Sep 2022 12:53:19 -0400
|
||||
Subject: [PATCH] Limit lengths of fields in Condition to a max length.
|
||||
|
||||
This app-generated input needs to not be too long to avoid errors in the process of writing to disk.
|
||||
|
||||
Bug: 242846316
|
||||
Test: cts ConditionTest; atest ConditionTest; manually verified exploit apk is OK
|
||||
|
||||
Change-Id: Ic2fa8f06cc7a4c1f262115764fbd1be2a226b4b9
|
||||
Merged-In: Ic2fa8f06cc7a4c1f262115764fbd1be2a226b4b9
|
||||
(cherry picked from commit 81352c3775949c622441e10b468766441e35edc7)
|
||||
(cherry picked from commit 5cb217fff3bc7184bd776a9dc2991e7fce5e25bd)
|
||||
Merged-In: Ic2fa8f06cc7a4c1f262115764fbd1be2a226b4b9
|
||||
---
|
||||
.../service/notification/Condition.java | 38 +++++++++++++++++--
|
||||
1 file changed, 34 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java
|
||||
index 5a7a83f19b0c..10a7f5afaa50 100644
|
||||
--- a/core/java/android/service/notification/Condition.java
|
||||
+++ b/core/java/android/service/notification/Condition.java
|
||||
@@ -99,6 +99,12 @@ public final class Condition implements Parcelable {
|
||||
@SystemApi
|
||||
public final int icon;
|
||||
|
||||
+ /**
|
||||
+ * The maximum string length for any string contained in this condition.
|
||||
+ * @hide
|
||||
+ */
|
||||
+ public static final int MAX_STRING_LENGTH = 1000;
|
||||
+
|
||||
/**
|
||||
* An object representing the current state of a {@link android.app.AutomaticZenRule}.
|
||||
* @param id the {@link android.app.AutomaticZenRule#getConditionId()} of the zen rule
|
||||
@@ -114,16 +120,19 @@ public final class Condition implements Parcelable {
|
||||
if (id == null) throw new IllegalArgumentException("id is required");
|
||||
if (summary == null) throw new IllegalArgumentException("summary is required");
|
||||
if (!isValidState(state)) throw new IllegalArgumentException("state is invalid: " + state);
|
||||
- this.id = id;
|
||||
- this.summary = summary;
|
||||
- this.line1 = line1;
|
||||
- this.line2 = line2;
|
||||
+ this.id = getTrimmedUri(id);
|
||||
+ this.summary = getTrimmedString(summary);
|
||||
+ this.line1 = getTrimmedString(line1);
|
||||
+ this.line2 = getTrimmedString(line2);
|
||||
this.icon = icon;
|
||||
this.state = state;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public Condition(Parcel source) {
|
||||
+ // This constructor passes all fields directly into the constructor that takes all the
|
||||
+ // fields as arguments; that constructor will trim each of the input strings to
|
||||
+ // max length if necessary.
|
||||
this((Uri)source.readParcelable(Condition.class.getClassLoader()),
|
||||
source.readString(),
|
||||
source.readString(),
|
||||
@@ -255,4 +264,25 @@ public final class Condition implements Parcelable {
|
||||
return new Condition[size];
|
||||
}
|
||||
};
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a truncated copy of the string if the string is longer than MAX_STRING_LENGTH.
|
||||
+ */
|
||||
+ private static String getTrimmedString(String input) {
|
||||
+ if (input != null && input.length() > MAX_STRING_LENGTH) {
|
||||
+ return input.substring(0, MAX_STRING_LENGTH);
|
||||
+ }
|
||||
+ return input;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a truncated copy of the Uri by trimming the string representation to the maximum
|
||||
+ * string length.
|
||||
+ */
|
||||
+ private static Uri getTrimmedUri(Uri input) {
|
||||
+ if (input != null && input.toString().length() > MAX_STRING_LENGTH) {
|
||||
+ return Uri.parse(getTrimmedString(input.toString()));
|
||||
+ }
|
||||
+ return input;
|
||||
+ }
|
||||
}
|
64
Patches/LineageOS-16.0/android_frameworks_base/347045.patch
Normal file
64
Patches/LineageOS-16.0/android_frameworks_base/347045.patch
Normal file
|
@ -0,0 +1,64 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Norman <danielnorman@google.com>
|
||||
Date: Wed, 5 Oct 2022 16:28:20 -0700
|
||||
Subject: [PATCH] RESTRICT AUTOMERGE Disable all A11yServices from an
|
||||
uninstalled package.
|
||||
|
||||
Previous logic would exit the loop after removing the first service
|
||||
matching the uninstalled package.
|
||||
|
||||
Bug: 243378132
|
||||
Test: atest AccessibilityEndToEndTest
|
||||
Test: m sts;
|
||||
sts-tradefed run sts-dynamic-develop -m \
|
||||
CtsAccessibilityServiceTestCases
|
||||
Change-Id: I4ba30345d8600674ee8a9ea3ff411aecbf3655a3
|
||||
(cherry picked from commit 37966299859153377e61a6a97b036388d231c2d0)
|
||||
Merged-In: I4ba30345d8600674ee8a9ea3ff411aecbf3655a3
|
||||
---
|
||||
.../AccessibilityManagerService.java | 24 ++++++++++---------
|
||||
1 file changed, 13 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
|
||||
index 58a1beed70c9..91d1b7576ca7 100644
|
||||
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
|
||||
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
|
||||
@@ -379,25 +379,27 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
}
|
||||
UserState userState = getUserStateLocked(userId);
|
||||
Iterator<ComponentName> it = userState.mEnabledServices.iterator();
|
||||
+ boolean anyServiceRemoved = false;
|
||||
while (it.hasNext()) {
|
||||
ComponentName comp = it.next();
|
||||
String compPkg = comp.getPackageName();
|
||||
if (compPkg.equals(packageName)) {
|
||||
it.remove();
|
||||
- // Update the enabled services setting.
|
||||
- persistComponentNamesToSettingLocked(
|
||||
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
|
||||
- userState.mEnabledServices, userId);
|
||||
- // Update the touch exploration granted services setting.
|
||||
userState.mTouchExplorationGrantedServices.remove(comp);
|
||||
- persistComponentNamesToSettingLocked(
|
||||
- Settings.Secure.
|
||||
- TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
|
||||
- userState.mTouchExplorationGrantedServices, userId);
|
||||
- onUserStateChangedLocked(userState);
|
||||
- return;
|
||||
+ anyServiceRemoved = true;
|
||||
}
|
||||
}
|
||||
+ if (anyServiceRemoved) {
|
||||
+ // Update the enabled services setting.
|
||||
+ persistComponentNamesToSettingLocked(
|
||||
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
|
||||
+ userState.mEnabledServices, userId);
|
||||
+ // Update the touch exploration granted services setting.
|
||||
+ persistComponentNamesToSettingLocked(
|
||||
+ Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
|
||||
+ userState.mTouchExplorationGrantedServices, userId);
|
||||
+ onUserStateChangedLocked(userState);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
35
Patches/LineageOS-16.0/android_frameworks_base/347046.patch
Normal file
35
Patches/LineageOS-16.0/android_frameworks_base/347046.patch
Normal file
|
@ -0,0 +1,35 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yuri Lin <yurilin@google.com>
|
||||
Date: Wed, 12 Oct 2022 14:27:46 +0000
|
||||
Subject: [PATCH] Fix conditionId string trimming in AutomaticZenRule
|
||||
|
||||
This change only applies to S branches and earlier.
|
||||
|
||||
Bug: 253085433
|
||||
Bug: 242703460
|
||||
Bug: 242703505
|
||||
Bug: 242703780
|
||||
Bug: 242704043
|
||||
Bug: 243794204
|
||||
Test: AutomaticZenRuleTest
|
||||
Change-Id: Iae423d93b777df8946ecf1c3baf640fcf74990ec
|
||||
Merged-In: Iae423d93b777df8946ecf1c3baf640fcf74990ec
|
||||
(cherry picked from commit 303f6bde896877793370c1697fa8c8331b808e56)
|
||||
Merged-In: Iae423d93b777df8946ecf1c3baf640fcf74990ec
|
||||
---
|
||||
core/java/android/app/AutomaticZenRule.java | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java
|
||||
index 29dd91ec1ad6..5998ab6fdaf4 100644
|
||||
--- a/core/java/android/app/AutomaticZenRule.java
|
||||
+++ b/core/java/android/app/AutomaticZenRule.java
|
||||
@@ -80,7 +80,7 @@ public final class AutomaticZenRule implements Parcelable {
|
||||
name = getTrimmedString(source.readString());
|
||||
}
|
||||
interruptionFilter = source.readInt();
|
||||
- conditionId = source.readParcelable(null);
|
||||
+ conditionId = getTrimmedUri(source.readParcelable(null));
|
||||
owner = getTrimmedComponentName(source.readParcelable(null));
|
||||
creationTime = source.readLong();
|
||||
}
|
237
Patches/LineageOS-16.0/android_frameworks_base/347047.patch
Normal file
237
Patches/LineageOS-16.0/android_frameworks_base/347047.patch
Normal file
|
@ -0,0 +1,237 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Songchun Fan <schfan@google.com>
|
||||
Date: Wed, 17 Aug 2022 09:37:18 -0700
|
||||
Subject: [PATCH] mem limit should be checked before settings are updated
|
||||
|
||||
Previously, a setting is updated before the memory usage limit
|
||||
check, which can be exploited by malicious apps and cause OoM DoS.
|
||||
|
||||
This CL changes the logic to checkMemLimit -> update -> updateMemUsage.
|
||||
|
||||
BUG: 239415861
|
||||
Test: atest com.android.providers.settings.SettingsStateTest
|
||||
|
||||
(cherry picked from commit 8eeb92950f4a7012d4cf282106a1418fd211f475)
|
||||
Merged-In: I20551a2dba9aa79efa0c064824f349f551c2c2e4
|
||||
Change-Id: I20551a2dba9aa79efa0c064824f349f551c2c2e4
|
||||
(cherry picked from commit d85a42821075ad80b931d904bdc9c1d4c3129456)
|
||||
Merged-In: I20551a2dba9aa79efa0c064824f349f551c2c2e4
|
||||
---
|
||||
.../providers/settings/SettingsState.java | 75 ++++++++++++-------
|
||||
.../providers/settings/SettingsStateTest.java | 43 ++++++++++-
|
||||
2 files changed, 90 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
|
||||
index 449946d7ab15..33b506468e11 100644
|
||||
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
|
||||
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
|
||||
@@ -358,9 +358,11 @@ final class SettingsState {
|
||||
Setting newSetting = new Setting(name, oldSetting.getValue(), null,
|
||||
oldSetting.getPackageName(), oldSetting.getTag(), false,
|
||||
oldSetting.getId());
|
||||
- mSettings.put(name, newSetting);
|
||||
- updateMemoryUsagePerPackageLocked(newSetting.getPackageName(), oldValue,
|
||||
+ int newSize = getNewMemoryUsagePerPackageLocked(newSetting.getPackageName(), oldValue,
|
||||
newSetting.getValue(), oldDefaultValue, newSetting.getDefaultValue());
|
||||
+ checkNewMemoryUsagePerPackageLocked(newSetting.getPackageName(), newSize);
|
||||
+ mSettings.put(name, newSetting);
|
||||
+ updateMemoryUsagePerPackageLocked(newSetting.getPackageName(), newSize);
|
||||
scheduleWriteIfNeededLocked();
|
||||
}
|
||||
}
|
||||
@@ -375,6 +377,12 @@ final class SettingsState {
|
||||
Setting oldState = mSettings.get(name);
|
||||
String oldValue = (oldState != null) ? oldState.value : null;
|
||||
String oldDefaultValue = (oldState != null) ? oldState.defaultValue : null;
|
||||
+ String newDefaultValue = makeDefault ? value : oldDefaultValue;
|
||||
+
|
||||
+ int newSize = getNewMemoryUsagePerPackageLocked(packageName, oldValue, value,
|
||||
+ oldDefaultValue, newDefaultValue);
|
||||
+ checkNewMemoryUsagePerPackageLocked(packageName, newSize);
|
||||
+
|
||||
Setting newState;
|
||||
|
||||
if (oldState != null) {
|
||||
@@ -392,8 +400,7 @@ final class SettingsState {
|
||||
|
||||
addHistoricalOperationLocked(HISTORICAL_OPERATION_UPDATE, newState);
|
||||
|
||||
- updateMemoryUsagePerPackageLocked(packageName, oldValue, value,
|
||||
- oldDefaultValue, newState.getDefaultValue());
|
||||
+ updateMemoryUsagePerPackageLocked(packageName, newSize);
|
||||
|
||||
scheduleWriteIfNeededLocked();
|
||||
|
||||
@@ -413,13 +420,14 @@ final class SettingsState {
|
||||
}
|
||||
|
||||
Setting oldState = mSettings.remove(name);
|
||||
+ int newSize = getNewMemoryUsagePerPackageLocked(oldState.packageName, oldState.value,
|
||||
+ null, oldState.defaultValue, null);
|
||||
|
||||
StatsLog.write(StatsLog.SETTING_CHANGED, name, /* value= */ "", /* newValue= */ "",
|
||||
oldState.value, /* tag */ "", false, getUserIdFromKey(mKey),
|
||||
StatsLog.SETTING_CHANGED__REASON__DELETED);
|
||||
|
||||
- updateMemoryUsagePerPackageLocked(oldState.packageName, oldState.value,
|
||||
- null, oldState.defaultValue, null);
|
||||
+ updateMemoryUsagePerPackageLocked(oldState.packageName, newSize);
|
||||
|
||||
addHistoricalOperationLocked(HISTORICAL_OPERATION_DELETE, oldState);
|
||||
|
||||
@@ -439,16 +447,18 @@ final class SettingsState {
|
||||
Setting oldSetting = new Setting(setting);
|
||||
String oldValue = setting.getValue();
|
||||
String oldDefaultValue = setting.getDefaultValue();
|
||||
+ String newValue = oldDefaultValue;
|
||||
+ String newDefaultValue = oldDefaultValue;
|
||||
+
|
||||
+ int newSize = getNewMemoryUsagePerPackageLocked(setting.packageName, oldValue,
|
||||
+ newValue, oldDefaultValue, newDefaultValue);
|
||||
+ checkNewMemoryUsagePerPackageLocked(setting.packageName, newSize);
|
||||
|
||||
if (!setting.reset()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
- String newValue = setting.getValue();
|
||||
- String newDefaultValue = setting.getDefaultValue();
|
||||
-
|
||||
- updateMemoryUsagePerPackageLocked(setting.packageName, oldValue,
|
||||
- newValue, oldDefaultValue, newDefaultValue);
|
||||
+ updateMemoryUsagePerPackageLocked(setting.packageName, newSize);
|
||||
|
||||
addHistoricalOperationLocked(HISTORICAL_OPERATION_RESET, oldSetting);
|
||||
|
||||
@@ -553,38 +563,49 @@ final class SettingsState {
|
||||
}
|
||||
}
|
||||
|
||||
- private void updateMemoryUsagePerPackageLocked(String packageName, String oldValue,
|
||||
- String newValue, String oldDefaultValue, String newDefaultValue) {
|
||||
- if (mMaxBytesPerAppPackage == MAX_BYTES_PER_APP_PACKAGE_UNLIMITED) {
|
||||
- return;
|
||||
- }
|
||||
+ private boolean isExemptFromMemoryUsageCap(String packageName) {
|
||||
+ return mMaxBytesPerAppPackage == MAX_BYTES_PER_APP_PACKAGE_UNLIMITED
|
||||
+ || SYSTEM_PACKAGE_NAME.equals(packageName);
|
||||
+ }
|
||||
|
||||
- if (SYSTEM_PACKAGE_NAME.equals(packageName)) {
|
||||
+ @GuardedBy("mLock")
|
||||
+ private void checkNewMemoryUsagePerPackageLocked(String packageName, int newSize)
|
||||
+ throws IllegalStateException {
|
||||
+ if (isExemptFromMemoryUsageCap(packageName)) {
|
||||
return;
|
||||
}
|
||||
+ if (newSize > mMaxBytesPerAppPackage) {
|
||||
+ throw new IllegalStateException("You are adding too many system settings. "
|
||||
+ + "You should stop using system settings for app specific data"
|
||||
+ + " package: " + packageName);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ @GuardedBy("mLock")
|
||||
+ private int getNewMemoryUsagePerPackageLocked(String packageName, String oldValue,
|
||||
+ String newValue, String oldDefaultValue, String newDefaultValue) {
|
||||
+ if (isExemptFromMemoryUsageCap(packageName)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ final Integer currentSize = mPackageToMemoryUsage.get(packageName);
|
||||
final int oldValueSize = (oldValue != null) ? oldValue.length() : 0;
|
||||
final int newValueSize = (newValue != null) ? newValue.length() : 0;
|
||||
final int oldDefaultValueSize = (oldDefaultValue != null) ? oldDefaultValue.length() : 0;
|
||||
final int newDefaultValueSize = (newDefaultValue != null) ? newDefaultValue.length() : 0;
|
||||
final int deltaSize = newValueSize + newDefaultValueSize
|
||||
- oldValueSize - oldDefaultValueSize;
|
||||
+ return Math.max((currentSize != null) ? currentSize + deltaSize : deltaSize, 0);
|
||||
+ }
|
||||
|
||||
- Integer currentSize = mPackageToMemoryUsage.get(packageName);
|
||||
- final int newSize = Math.max((currentSize != null)
|
||||
- ? currentSize + deltaSize : deltaSize, 0);
|
||||
-
|
||||
- if (newSize > mMaxBytesPerAppPackage) {
|
||||
- throw new IllegalStateException("You are adding too many system settings. "
|
||||
- + "You should stop using system settings for app specific data"
|
||||
- + " package: " + packageName);
|
||||
+ @GuardedBy("mLock")
|
||||
+ private void updateMemoryUsagePerPackageLocked(String packageName, int newSize) {
|
||||
+ if (isExemptFromMemoryUsageCap(packageName)) {
|
||||
+ return;
|
||||
}
|
||||
-
|
||||
if (DEBUG) {
|
||||
Slog.i(LOG_TAG, "Settings for package: " + packageName
|
||||
+ " size: " + newSize + " bytes.");
|
||||
}
|
||||
-
|
||||
mPackageToMemoryUsage.put(packageName, newSize);
|
||||
}
|
||||
|
||||
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
|
||||
index 3f68554ffe87..6f45adef91f7 100644
|
||||
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
|
||||
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
|
||||
@@ -21,6 +21,8 @@ import android.util.Xml;
|
||||
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
+import com.google.common.base.Strings;
|
||||
+
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -46,7 +48,6 @@ public class SettingsStateTest extends AndroidTestCase {
|
||||
"\uD800ab\uDC00 " + // broken surrogate pairs
|
||||
"日本語";
|
||||
|
||||
-
|
||||
public void testIsBinary() {
|
||||
assertFalse(SettingsState.isBinary(" abc 日本語"));
|
||||
|
||||
@@ -182,4 +183,44 @@ public class SettingsStateTest extends AndroidTestCase {
|
||||
assertEquals("p2", s.getPackageName());
|
||||
}
|
||||
}
|
||||
+
|
||||
+ public void testInsertSetting_memoryUsage() {
|
||||
+ final Object lock = new Object();
|
||||
+ final File file = new File(getContext().getCacheDir(), "setting.xml");
|
||||
+ final String settingName = "test_setting";
|
||||
+
|
||||
+ SettingsState settingsState = new SettingsState(getContext(), lock, file, 1,
|
||||
+ SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
|
||||
+ // No exception should be thrown when there is no cap
|
||||
+ settingsState.insertSettingLocked(settingName, Strings.repeat("A", 20001),
|
||||
+ null, false, "p1");
|
||||
+ settingsState.deleteSettingLocked(settingName);
|
||||
+
|
||||
+ settingsState = new SettingsState(getContext(), lock, file, 1,
|
||||
+ SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED, Looper.getMainLooper());
|
||||
+ // System package doesn't have memory usage limit
|
||||
+ settingsState.insertSettingLocked(settingName, Strings.repeat("A", 20001),
|
||||
+ null, false, "android");
|
||||
+ settingsState.deleteSettingLocked(settingName);
|
||||
+
|
||||
+ // Should not throw if usage is under the cap
|
||||
+ settingsState.insertSettingLocked(settingName, Strings.repeat("A", 19999),
|
||||
+ null, false, "p1");
|
||||
+ settingsState.deleteSettingLocked(settingName);
|
||||
+ try {
|
||||
+ settingsState.insertSettingLocked(settingName, Strings.repeat("A", 20001),
|
||||
+ null, false, "p1");
|
||||
+ fail("Should throw because it exceeded per package memory usage");
|
||||
+ } catch (IllegalStateException ex) {
|
||||
+ assertTrue(ex.getMessage().contains("p1"));
|
||||
+ }
|
||||
+ try {
|
||||
+ settingsState.insertSettingLocked(settingName, Strings.repeat("A", 20001),
|
||||
+ null, false, "p1");
|
||||
+ fail("Should throw because it exceeded per package memory usage");
|
||||
+ } catch (IllegalStateException ex) {
|
||||
+ assertTrue(ex.getMessage().contains("p1"));
|
||||
+ }
|
||||
+ assertTrue(settingsState.getSettingLocked(settingName).isNull());
|
||||
+ }
|
||||
}
|
34
Patches/LineageOS-16.0/android_frameworks_base/347048.patch
Normal file
34
Patches/LineageOS-16.0/android_frameworks_base/347048.patch
Normal file
|
@ -0,0 +1,34 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nate Myren <ntmyren@google.com>
|
||||
Date: Wed, 26 Oct 2022 17:37:26 +0000
|
||||
Subject: [PATCH] RESTRICT AUTOMERGE Revert "Revert "RESTRICT AUTOMERGE
|
||||
Validate permission tree size..."
|
||||
|
||||
Revert submission 20285709-revert-20103164-permTree-qt-dev-QWIEBZIWEA
|
||||
|
||||
Reason for revert: resubmission
|
||||
Reverted Changes:
|
||||
I0a3b68aff:Revert "RESTRICT AUTOMERGE Add PermissionMemoryFoo...
|
||||
I4e8ec8b1a:Revert "RESTRICT AUTOMERGE Validate permission tre...
|
||||
|
||||
Change-Id: I3cd1aa270373bb32f95dfbe8422faa783ee49dca
|
||||
(cherry picked from commit 4e83e59b27f7d6232ee9fe96f789e32debc19772)
|
||||
Merged-In: I3cd1aa270373bb32f95dfbe8422faa783ee49dca
|
||||
---
|
||||
.../android/server/pm/permission/PermissionManagerService.java | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
|
||||
index 79b2636481b3..a61f67d32452 100644
|
||||
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
|
||||
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
|
||||
@@ -688,8 +688,8 @@ public class PermissionManagerService {
|
||||
BasePermission bp = mSettings.getPermissionLocked(info.name);
|
||||
added = bp == null;
|
||||
int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
|
||||
+ enforcePermissionCapLocked(info, tree);
|
||||
if (added) {
|
||||
- enforcePermissionCapLocked(info, tree);
|
||||
bp = new BasePermission(info.name, tree.getSourcePackageName(),
|
||||
BasePermission.TYPE_DYNAMIC);
|
||||
} else if (!bp.isDynamic()) {
|
249
Patches/LineageOS-16.0/android_frameworks_base/347049.patch
Normal file
249
Patches/LineageOS-16.0/android_frameworks_base/347049.patch
Normal file
|
@ -0,0 +1,249 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Songchun Fan <schfan@google.com>
|
||||
Date: Tue, 11 Oct 2022 18:08:11 -0700
|
||||
Subject: [PATCH] key size limit for mutating settings
|
||||
|
||||
Prior to targetSdk 22, apps could add random system settings keys which
|
||||
opens an opportunity for OOM attacks. This CL adds a key size limit.
|
||||
|
||||
BUG: 239415997
|
||||
Test: manual; will add cts test
|
||||
Merged-In: Ic9e88c0cc3d7206c64ba5b5c7d15b50d1ffc9adc
|
||||
Change-Id: Ic9e88c0cc3d7206c64ba5b5c7d15b50d1ffc9adc
|
||||
(cherry picked from commit 783bcba343c480f6ccedaaff41ba7171a1082e0c)
|
||||
(cherry picked from commit f1831c87122e56951c04e1f62f647ab156ca71e3)
|
||||
Merged-In: Ic9e88c0cc3d7206c64ba5b5c7d15b50d1ffc9adc
|
||||
---
|
||||
.../providers/settings/SettingsState.java | 40 ++++---
|
||||
.../providers/settings/SettingsStateTest.java | 102 +++++++++++++++++-
|
||||
2 files changed, 126 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
|
||||
index 33b506468e11..c27c43d0cdc7 100644
|
||||
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
|
||||
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
|
||||
@@ -48,6 +48,7 @@ import android.util.Xml;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
+import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.server.LocalServices;
|
||||
|
||||
@@ -358,8 +359,8 @@ final class SettingsState {
|
||||
Setting newSetting = new Setting(name, oldSetting.getValue(), null,
|
||||
oldSetting.getPackageName(), oldSetting.getTag(), false,
|
||||
oldSetting.getId());
|
||||
- int newSize = getNewMemoryUsagePerPackageLocked(newSetting.getPackageName(), oldValue,
|
||||
- newSetting.getValue(), oldDefaultValue, newSetting.getDefaultValue());
|
||||
+ int newSize = getNewMemoryUsagePerPackageLocked(newSetting.getPackageName(), 0,
|
||||
+ oldValue, newSetting.getValue(), oldDefaultValue, newSetting.getDefaultValue());
|
||||
checkNewMemoryUsagePerPackageLocked(newSetting.getPackageName(), newSize);
|
||||
mSettings.put(name, newSetting);
|
||||
updateMemoryUsagePerPackageLocked(newSetting.getPackageName(), newSize);
|
||||
@@ -379,8 +380,9 @@ final class SettingsState {
|
||||
String oldDefaultValue = (oldState != null) ? oldState.defaultValue : null;
|
||||
String newDefaultValue = makeDefault ? value : oldDefaultValue;
|
||||
|
||||
- int newSize = getNewMemoryUsagePerPackageLocked(packageName, oldValue, value,
|
||||
- oldDefaultValue, newDefaultValue);
|
||||
+ int newSize = getNewMemoryUsagePerPackageLocked(packageName,
|
||||
+ oldValue == null ? name.length() : 0 /* deltaKeySize */,
|
||||
+ oldValue, value, oldDefaultValue, newDefaultValue);
|
||||
checkNewMemoryUsagePerPackageLocked(packageName, newSize);
|
||||
|
||||
Setting newState;
|
||||
@@ -420,8 +422,12 @@ final class SettingsState {
|
||||
}
|
||||
|
||||
Setting oldState = mSettings.remove(name);
|
||||
- int newSize = getNewMemoryUsagePerPackageLocked(oldState.packageName, oldState.value,
|
||||
- null, oldState.defaultValue, null);
|
||||
+ if (oldState == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ int newSize = getNewMemoryUsagePerPackageLocked(oldState.packageName,
|
||||
+ -name.length() /* deltaKeySize */,
|
||||
+ oldState.value, null, oldState.defaultValue, null);
|
||||
|
||||
StatsLog.write(StatsLog.SETTING_CHANGED, name, /* value= */ "", /* newValue= */ "",
|
||||
oldState.value, /* tag */ "", false, getUserIdFromKey(mKey),
|
||||
@@ -443,15 +449,16 @@ final class SettingsState {
|
||||
}
|
||||
|
||||
Setting setting = mSettings.get(name);
|
||||
+ if (setting == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
Setting oldSetting = new Setting(setting);
|
||||
String oldValue = setting.getValue();
|
||||
String oldDefaultValue = setting.getDefaultValue();
|
||||
- String newValue = oldDefaultValue;
|
||||
- String newDefaultValue = oldDefaultValue;
|
||||
|
||||
- int newSize = getNewMemoryUsagePerPackageLocked(setting.packageName, oldValue,
|
||||
- newValue, oldDefaultValue, newDefaultValue);
|
||||
+ int newSize = getNewMemoryUsagePerPackageLocked(setting.packageName, 0, oldValue,
|
||||
+ oldDefaultValue, oldDefaultValue, oldDefaultValue);
|
||||
checkNewMemoryUsagePerPackageLocked(setting.packageName, newSize);
|
||||
|
||||
if (!setting.reset()) {
|
||||
@@ -582,8 +589,8 @@ final class SettingsState {
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
- private int getNewMemoryUsagePerPackageLocked(String packageName, String oldValue,
|
||||
- String newValue, String oldDefaultValue, String newDefaultValue) {
|
||||
+ private int getNewMemoryUsagePerPackageLocked(String packageName, int deltaKeySize,
|
||||
+ String oldValue, String newValue, String oldDefaultValue, String newDefaultValue) {
|
||||
if (isExemptFromMemoryUsageCap(packageName)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -592,7 +599,7 @@ final class SettingsState {
|
||||
final int newValueSize = (newValue != null) ? newValue.length() : 0;
|
||||
final int oldDefaultValueSize = (oldDefaultValue != null) ? oldDefaultValue.length() : 0;
|
||||
final int newDefaultValueSize = (newDefaultValue != null) ? newDefaultValue.length() : 0;
|
||||
- final int deltaSize = newValueSize + newDefaultValueSize
|
||||
+ final int deltaSize = deltaKeySize + newValueSize + newDefaultValueSize
|
||||
- oldValueSize - oldDefaultValueSize;
|
||||
return Math.max((currentSize != null) ? currentSize + deltaSize : deltaSize, 0);
|
||||
}
|
||||
@@ -1216,4 +1223,11 @@ final class SettingsState {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ @VisibleForTesting
|
||||
+ public int getMemoryUsage(String packageName) {
|
||||
+ synchronized (mLock) {
|
||||
+ return mPackageToMemoryUsage.getOrDefault(packageName, 0);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
|
||||
index 6f45adef91f7..adb356726eec 100644
|
||||
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
|
||||
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
|
||||
@@ -186,8 +186,8 @@ public class SettingsStateTest extends AndroidTestCase {
|
||||
|
||||
public void testInsertSetting_memoryUsage() {
|
||||
final Object lock = new Object();
|
||||
- final File file = new File(getContext().getCacheDir(), "setting.xml");
|
||||
- final String settingName = "test_setting";
|
||||
+ final File file = new File(getContext().getCacheDir(), "setting.xml");
|
||||
+ final String settingName = "test_setting";
|
||||
|
||||
SettingsState settingsState = new SettingsState(getContext(), lock, file, 1,
|
||||
SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
|
||||
@@ -204,7 +204,7 @@ public class SettingsStateTest extends AndroidTestCase {
|
||||
settingsState.deleteSettingLocked(settingName);
|
||||
|
||||
// Should not throw if usage is under the cap
|
||||
- settingsState.insertSettingLocked(settingName, Strings.repeat("A", 19999),
|
||||
+ settingsState.insertSettingLocked(settingName, Strings.repeat("A", 19975),
|
||||
null, false, "p1");
|
||||
settingsState.deleteSettingLocked(settingName);
|
||||
try {
|
||||
@@ -222,5 +222,101 @@ public class SettingsStateTest extends AndroidTestCase {
|
||||
assertTrue(ex.getMessage().contains("p1"));
|
||||
}
|
||||
assertTrue(settingsState.getSettingLocked(settingName).isNull());
|
||||
+ try {
|
||||
+ settingsState.insertSettingLocked(Strings.repeat("A", 20001), "",
|
||||
+ null, false, "p1");
|
||||
+ fail("Should throw because it exceeded per package memory usage");
|
||||
+ } catch (IllegalStateException ex) {
|
||||
+ assertTrue(ex.getMessage().contains("You are adding too many system settings"));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void testMemoryUsagePerPackage() {
|
||||
+ final Object lock = new Object();
|
||||
+ final File file = new File(getContext().getCacheDir(), "setting.xml");
|
||||
+ final String testPackage = "package";
|
||||
+ SettingsState settingsState = new SettingsState(getContext(), lock, file, 1,
|
||||
+ SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED, Looper.getMainLooper());
|
||||
+
|
||||
+ // Test inserting one key with default
|
||||
+ final String settingName = "test_setting";
|
||||
+ final String testKey1 = settingName;
|
||||
+ final String testValue1 = Strings.repeat("A", 100);
|
||||
+ settingsState.insertSettingLocked(testKey1, testValue1, null, true, testPackage);
|
||||
+ int expectedMemUsage = testKey1.length() + testValue1.length()
|
||||
+ + testValue1.length() /* size for default */;
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
+
|
||||
+ // Test inserting another key
|
||||
+ final String testKey2 = settingName + "2";
|
||||
+ settingsState.insertSettingLocked(testKey2, testValue1, null, false, testPackage);
|
||||
+ expectedMemUsage += testKey2.length() + testValue1.length();
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
+
|
||||
+ // Test updating first key with new default
|
||||
+ final String testValue2 = Strings.repeat("A", 300);
|
||||
+ settingsState.insertSettingLocked(testKey1, testValue2, null, true, testPackage);
|
||||
+ expectedMemUsage += (testValue2.length() - testValue1.length()) * 2;
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
+
|
||||
+ // Test updating first key without new default
|
||||
+ final String testValue3 = Strings.repeat("A", 50);
|
||||
+ settingsState.insertSettingLocked(testKey1, testValue3, null, false, testPackage);
|
||||
+ expectedMemUsage -= testValue2.length() - testValue3.length();
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
+
|
||||
+ // Test updating second key
|
||||
+ settingsState.insertSettingLocked(testKey2, testValue2, null, false, testPackage);
|
||||
+ expectedMemUsage -= testValue1.length() - testValue2.length();
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
+
|
||||
+ // Test resetting key
|
||||
+ settingsState.resetSettingLocked(testKey1);
|
||||
+ expectedMemUsage += testValue2.length() - testValue3.length();
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
+
|
||||
+ // Test resetting default value
|
||||
+ settingsState.resetSettingDefaultValueLocked(testKey1);
|
||||
+ expectedMemUsage -= testValue2.length();
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
+
|
||||
+ // Test deletion
|
||||
+ settingsState.deleteSettingLocked(testKey2);
|
||||
+ expectedMemUsage -= testValue2.length() + testKey2.length() /* key is deleted too */;
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
+
|
||||
+ // Test another package with a different key
|
||||
+ final String testPackage2 = testPackage + "2";
|
||||
+ final String testKey3 = settingName + "3";
|
||||
+ settingsState.insertSettingLocked(testKey3, testValue1, null, true, testPackage2);
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
+ final int expectedMemUsage2 = testKey3.length() + testValue1.length() * 2;
|
||||
+ assertEquals(expectedMemUsage2, settingsState.getMemoryUsage(testPackage2));
|
||||
+
|
||||
+ // Test system package
|
||||
+ settingsState.insertSettingLocked(testKey1, testValue1, null, true, "android");
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
+ assertEquals(expectedMemUsage2, settingsState.getMemoryUsage(testPackage2));
|
||||
+ assertEquals(0, settingsState.getMemoryUsage("android"));
|
||||
+
|
||||
+ // Test invalid value
|
||||
+ try {
|
||||
+ settingsState.insertSettingLocked(testKey1, Strings.repeat("A", 20001), null, false,
|
||||
+ testPackage);
|
||||
+ fail("Should throw because it exceeded per package memory usage");
|
||||
+ } catch (IllegalStateException ex) {
|
||||
+ assertTrue(ex.getMessage().contains("You are adding too many system settings"));
|
||||
+ }
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
+
|
||||
+ // Test invalid key
|
||||
+ try {
|
||||
+ settingsState.insertSettingLocked(Strings.repeat("A", 20001), "", null, false,
|
||||
+ testPackage);
|
||||
+ fail("Should throw because it exceeded per package memory usage");
|
||||
+ } catch (IllegalStateException ex) {
|
||||
+ assertTrue(ex.getMessage().contains("You are adding too many system settings"));
|
||||
+ }
|
||||
+ assertEquals(expectedMemUsage, settingsState.getMemoryUsage(testPackage));
|
||||
}
|
||||
}
|
129
Patches/LineageOS-16.0/android_frameworks_base/347050.patch
Normal file
129
Patches/LineageOS-16.0/android_frameworks_base/347050.patch
Normal file
|
@ -0,0 +1,129 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nate Myren <ntmyren@google.com>
|
||||
Date: Fri, 23 Sep 2022 12:04:57 -0700
|
||||
Subject: [PATCH] RESTRICT AUTOMERGE Revoke SYSTEM_ALERT_WINDOW on upgrade past
|
||||
api 23
|
||||
|
||||
Bug: 221040577
|
||||
Test: atest PermissionTest23#testPre23AppsWithSystemAlertWindowGetDeniedOnUpgrade
|
||||
Change-Id: I4b4605aaae107875811070dea6d031c5d9f25c96
|
||||
(cherry picked from commit f6ba142a84a38014e56c3178f0aa322a377b77cd)
|
||||
Merged-In: I4b4605aaae107875811070dea6d031c5d9f25c96
|
||||
---
|
||||
.../server/pm/PackageManagerService.java | 4 +-
|
||||
.../permission/PermissionManagerInternal.java | 20 ++++-----
|
||||
.../permission/PermissionManagerService.java | 44 ++++++++++++++++++-
|
||||
3 files changed, 54 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
index 5b454f2d8939..25f70b23e68f 100644
|
||||
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
|
||||
@@ -11812,8 +11812,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
|
||||
AsyncTask.execute(() -> {
|
||||
if (hasOldPkg) {
|
||||
- mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
|
||||
- allPackageNames, mPermissionCallback);
|
||||
+ mPermissionManager.onPackageUpdated(pkg, oldPkg, allPackageNames,
|
||||
+ mPermissionCallback);
|
||||
}
|
||||
if (hasPermissionDefinitionChanges) {
|
||||
mPermissionManager.revokeRuntimePermissionsIfPermissionDefinitionChanged(
|
||||
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
|
||||
index 185e0e1fda5f..0f98126171d8 100644
|
||||
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
|
||||
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
|
||||
@@ -91,17 +91,15 @@ public abstract class PermissionManagerInternal {
|
||||
public abstract void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated,
|
||||
@NonNull Collection<PackageParser.Package> allPacakges, PermissionCallback callback);
|
||||
|
||||
- /**
|
||||
- * We might auto-grant permissions if any permission of the group is already granted. Hence if
|
||||
- * the group of a granted permission changes we need to revoke it to avoid having permissions of
|
||||
- * the new group auto-granted.
|
||||
- *
|
||||
- * @param newPackage The new package that was installed
|
||||
- * @param oldPackage The old package that was updated
|
||||
- * @param allPackageNames All packages
|
||||
- * @param permissionCallback Callback for permission changed
|
||||
- */
|
||||
- public abstract void revokeRuntimePermissionsIfGroupChanged(
|
||||
+ /**
|
||||
+ * If the app is updated, then some checks need to be performed to ensure the package is not
|
||||
+ * attempting to expoit permission changes across API boundaries.
|
||||
+ * @param newPackage The new package that was installed
|
||||
+ * @param oldPackage The old package that was updated
|
||||
+ * @param allPackageNames The current packages in the system
|
||||
+ * @param permissionCallback Callback for permission changed
|
||||
+ */
|
||||
+ public abstract void onPackageUpdated(
|
||||
@NonNull PackageParser.Package newPackage,
|
||||
@NonNull PackageParser.Package oldPackage,
|
||||
@NonNull ArrayList<String> allPackageNames,
|
||||
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
|
||||
index a61f67d32452..bdfe64c2c348 100644
|
||||
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
|
||||
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
|
||||
@@ -392,6 +392,46 @@ public class PermissionManagerService {
|
||||
return protectionLevel;
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * If the package was below api 23, got the SYSTEM_ALERT_WINDOW permission automatically, and
|
||||
+ * then updated past api 23, and the app does not satisfy any of the other SAW permission flags,
|
||||
+ * the permission should be revoked.
|
||||
+ *
|
||||
+ * @param newPackage The new package that was installed
|
||||
+ * @param oldPackage The old package that was updated
|
||||
+ */
|
||||
+ private void revokeSystemAlertWindowIfUpgradedPast23(
|
||||
+ @NonNull PackageParser.Package newPackage,
|
||||
+ @NonNull PackageParser.Package oldPackage,
|
||||
+ @NonNull PermissionCallback permissionCallback) {
|
||||
+ if (oldPackage.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M
|
||||
+ || newPackage.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
|
||||
+ || !newPackage.requestedPermissions
|
||||
+ .contains(Manifest.permission.SYSTEM_ALERT_WINDOW)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ BasePermission saw;
|
||||
+ final int callingUid = Binder.getCallingUid();
|
||||
+ synchronized (mLock) {
|
||||
+ saw = mSettings.getPermissionLocked(Manifest.permission.SYSTEM_ALERT_WINDOW);
|
||||
+ }
|
||||
+ final PackageSetting ps = (PackageSetting) newPackage.mExtras;
|
||||
+ if (grantSignaturePermission(Manifest.permission.SYSTEM_ALERT_WINDOW, newPackage, saw,
|
||||
+ ps.getPermissionsState())) {
|
||||
+ return;
|
||||
+ }
|
||||
+ for (int userId: mUserManagerInt.getUserIds()) {
|
||||
+ try {
|
||||
+ revokeRuntimePermission(Manifest.permission.SYSTEM_ALERT_WINDOW,
|
||||
+ newPackage.packageName, false, callingUid, userId, permissionCallback);
|
||||
+ } catch (IllegalStateException | SecurityException e) {
|
||||
+ Log.e(TAG, "unable to revoke SYSTEM_ALERT_WINDOW for "
|
||||
+ + newPackage.packageName + " user " + userId, e);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* We might auto-grant permissions if any permission of the group is already granted. Hence if
|
||||
* the group of a granted permission changes we need to revoke it to avoid having permissions of
|
||||
@@ -2127,11 +2167,13 @@ public class PermissionManagerService {
|
||||
return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
|
||||
}
|
||||
@Override
|
||||
- public void revokeRuntimePermissionsIfGroupChanged(
|
||||
+ public void onPackageUpdated(
|
||||
@NonNull PackageParser.Package newPackage,
|
||||
@NonNull PackageParser.Package oldPackage,
|
||||
@NonNull ArrayList<String> allPackageNames,
|
||||
@NonNull PermissionCallback permissionCallback) {
|
||||
+ PermissionManagerService.this.revokeSystemAlertWindowIfUpgradedPast23(newPackage,
|
||||
+ oldPackage, permissionCallback);
|
||||
PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
|
||||
oldPackage, allPackageNames, permissionCallback);
|
||||
}
|
254
Patches/LineageOS-16.0/android_frameworks_base/347051.patch
Normal file
254
Patches/LineageOS-16.0/android_frameworks_base/347051.patch
Normal file
|
@ -0,0 +1,254 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Khoa Hong <khoahong@google.com>
|
||||
Date: Wed, 19 Oct 2022 16:29:18 +0800
|
||||
Subject: [PATCH] Add protections agains use-after-free issues if cancel() or
|
||||
queue() is called after a device connection has been closed.
|
||||
|
||||
This is a backport of ag/7528082 and ag/20033068.
|
||||
|
||||
Bug: 132319116
|
||||
Bug: 130571162
|
||||
Bug: 204584366
|
||||
Test: CTS Verifier: USB Accessory Test & USB Device Test
|
||||
Change-Id: I952ab566e26a808997e362dc85ebd1d8eb4574b9
|
||||
(cherry picked from commit 7a8d56b2fe3496f7717ad1afe45d2ef523b7e252)
|
||||
Merged-In: I952ab566e26a808997e362dc85ebd1d8eb4574b9
|
||||
---
|
||||
.../hardware/usb/UsbDeviceConnection.java | 71 +++++++++++++--
|
||||
.../java/android/hardware/usb/UsbRequest.java | 86 +++++++++++++++++--
|
||||
2 files changed, 143 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
|
||||
index 9e5174ad93a8..7a521166f35c 100644
|
||||
--- a/core/java/android/hardware/usb/UsbDeviceConnection.java
|
||||
+++ b/core/java/android/hardware/usb/UsbDeviceConnection.java
|
||||
@@ -50,6 +50,8 @@ public class UsbDeviceConnection {
|
||||
|
||||
private final CloseGuard mCloseGuard = CloseGuard.get();
|
||||
|
||||
+ private final Object mLock = new Object();
|
||||
+
|
||||
/**
|
||||
* UsbDevice should only be instantiated by UsbService implementation
|
||||
* @hide
|
||||
@@ -60,13 +62,23 @@ public class UsbDeviceConnection {
|
||||
|
||||
/* package */ boolean open(String name, ParcelFileDescriptor pfd, @NonNull Context context) {
|
||||
mContext = context.getApplicationContext();
|
||||
- boolean wasOpened = native_open(name, pfd.getFileDescriptor());
|
||||
|
||||
- if (wasOpened) {
|
||||
- mCloseGuard.open("close");
|
||||
+ synchronized (mLock) {
|
||||
+ boolean wasOpened = native_open(name, pfd.getFileDescriptor());
|
||||
+
|
||||
+ if (wasOpened) {
|
||||
+ mCloseGuard.open("close");
|
||||
+ }
|
||||
+
|
||||
+ return wasOpened;
|
||||
}
|
||||
+ }
|
||||
|
||||
- return wasOpened;
|
||||
+ /***
|
||||
+ * @return If this connection is currently open and usable.
|
||||
+ */
|
||||
+ boolean isOpen() {
|
||||
+ return mNativeContext != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,6 +90,49 @@ public class UsbDeviceConnection {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Cancel a request which relates to this connection.
|
||||
+ *
|
||||
+ * @return true if the request was successfully cancelled.
|
||||
+ */
|
||||
+ /* package */ boolean cancelRequest(UsbRequest request) {
|
||||
+ synchronized (mLock) {
|
||||
+ if (!isOpen()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return request.cancelIfOpen();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * This is meant to be called by UsbRequest's queue() in order to synchronize on
|
||||
+ * UsbDeviceConnection's mLock to prevent the connection being closed while queueing.
|
||||
+ */
|
||||
+ /* package */ boolean queueRequest(UsbRequest request, ByteBuffer buffer, int length) {
|
||||
+ synchronized (mLock) {
|
||||
+ if (!isOpen()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return request.queueIfConnectionOpen(buffer, length);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * This is meant to be called by UsbRequest's queue() in order to synchronize on
|
||||
+ * UsbDeviceConnection's mLock to prevent the connection being closed while queueing.
|
||||
+ */
|
||||
+ /* package */ boolean queueRequest(UsbRequest request, @Nullable ByteBuffer buffer) {
|
||||
+ synchronized (mLock) {
|
||||
+ if (!isOpen()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return request.queueIfConnectionOpen(buffer);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Releases all system resources related to the device.
|
||||
* Once the object is closed it cannot be used again.
|
||||
@@ -85,9 +140,11 @@ public class UsbDeviceConnection {
|
||||
* to retrieve a new instance to reestablish communication with the device.
|
||||
*/
|
||||
public void close() {
|
||||
- if (mNativeContext != 0) {
|
||||
- native_close();
|
||||
- mCloseGuard.close();
|
||||
+ synchronized (mLock) {
|
||||
+ if (isOpen()) {
|
||||
+ native_close();
|
||||
+ mCloseGuard.close();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/core/java/android/hardware/usb/UsbRequest.java b/core/java/android/hardware/usb/UsbRequest.java
|
||||
index f59c87eecfcb..441d718b6067 100644
|
||||
--- a/core/java/android/hardware/usb/UsbRequest.java
|
||||
+++ b/core/java/android/hardware/usb/UsbRequest.java
|
||||
@@ -108,11 +108,13 @@ public class UsbRequest {
|
||||
* Releases all resources related to this request.
|
||||
*/
|
||||
public void close() {
|
||||
- if (mNativeContext != 0) {
|
||||
- mEndpoint = null;
|
||||
- mConnection = null;
|
||||
- native_close();
|
||||
- mCloseGuard.close();
|
||||
+ synchronized (mLock) {
|
||||
+ if (mNativeContext != 0) {
|
||||
+ mEndpoint = null;
|
||||
+ mConnection = null;
|
||||
+ native_close();
|
||||
+ mCloseGuard.close();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,10 +188,32 @@ public class UsbRequest {
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean queue(ByteBuffer buffer, int length) {
|
||||
+ UsbDeviceConnection connection = mConnection;
|
||||
+ if (connection == null) {
|
||||
+ // The expected exception by CTS Verifier - USB Device test
|
||||
+ throw new NullPointerException("invalid connection");
|
||||
+ }
|
||||
+
|
||||
+ // Calling into the underlying UsbDeviceConnection to synchronize on its lock, to prevent
|
||||
+ // the connection being closed while queueing.
|
||||
+ return connection.queueRequest(this, buffer, length);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * This is meant to be called from UsbDeviceConnection after synchronizing using the lock over
|
||||
+ * there, to prevent the connection being closed while queueing.
|
||||
+ */
|
||||
+ /* package */ boolean queueIfConnectionOpen(ByteBuffer buffer, int length) {
|
||||
+ UsbDeviceConnection connection = mConnection;
|
||||
+ if (connection == null || !connection.isOpen()) {
|
||||
+ // The expected exception by CTS Verifier - USB Device test
|
||||
+ throw new NullPointerException("invalid connection");
|
||||
+ }
|
||||
+
|
||||
boolean out = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);
|
||||
boolean result;
|
||||
|
||||
- if (mConnection.getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P
|
||||
+ if (connection.getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P
|
||||
&& length > MAX_USBFS_BUFFER_SIZE) {
|
||||
length = MAX_USBFS_BUFFER_SIZE;
|
||||
}
|
||||
@@ -238,6 +262,28 @@ public class UsbRequest {
|
||||
* @return true if the queueing operation succeeded
|
||||
*/
|
||||
public boolean queue(@Nullable ByteBuffer buffer) {
|
||||
+ UsbDeviceConnection connection = mConnection;
|
||||
+ if (connection == null) {
|
||||
+ // The expected exception by CTS Verifier - USB Device test
|
||||
+ throw new IllegalStateException("invalid connection");
|
||||
+ }
|
||||
+
|
||||
+ // Calling into the underlying UsbDeviceConnection to synchronize on its lock, to prevent
|
||||
+ // the connection being closed while queueing.
|
||||
+ return connection.queueRequest(this, buffer);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * This is meant to be called from UsbDeviceConnection after synchronizing using the lock over
|
||||
+ * there, to prevent the connection being closed while queueing.
|
||||
+ */
|
||||
+ /* package */ boolean queueIfConnectionOpen(@Nullable ByteBuffer buffer) {
|
||||
+ UsbDeviceConnection connection = mConnection;
|
||||
+ if (connection == null || !connection.isOpen()) {
|
||||
+ // The expected exception by CTS Verifier - USB Device test
|
||||
+ throw new IllegalStateException("invalid connection");
|
||||
+ }
|
||||
+
|
||||
// Request need to be initialized
|
||||
Preconditions.checkState(mNativeContext != 0, "request is not initialized");
|
||||
|
||||
@@ -255,7 +301,7 @@ public class UsbRequest {
|
||||
mIsUsingNewQueue = true;
|
||||
wasQueued = native_queue(null, 0, 0);
|
||||
} else {
|
||||
- if (mConnection.getContext().getApplicationInfo().targetSdkVersion
|
||||
+ if (connection.getContext().getApplicationInfo().targetSdkVersion
|
||||
< Build.VERSION_CODES.P) {
|
||||
// Can only send/receive MAX_USBFS_BUFFER_SIZE bytes at once
|
||||
Preconditions.checkArgumentInRange(buffer.remaining(), 0, MAX_USBFS_BUFFER_SIZE,
|
||||
@@ -358,6 +404,32 @@ public class UsbRequest {
|
||||
* @return true if cancelling succeeded
|
||||
*/
|
||||
public boolean cancel() {
|
||||
+ UsbDeviceConnection connection = mConnection;
|
||||
+ if (connection == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return connection.cancelRequest(this);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Cancels a pending queue operation (for use when the UsbDeviceConnection associated
|
||||
+ * with this request is synchronized). This ensures we don't have a race where the
|
||||
+ * device is closed and then the request is canceled which would lead to a
|
||||
+ * use-after-free because the cancel operation uses the device connection
|
||||
+ * information freed in the when UsbDeviceConnection is closed.<br/>
|
||||
+ *
|
||||
+ * This method assumes the connected is not closed while this method is executed.
|
||||
+ *
|
||||
+ * @return true if cancelling succeeded.
|
||||
+ */
|
||||
+ /* package */ boolean cancelIfOpen() {
|
||||
+ UsbDeviceConnection connection = mConnection;
|
||||
+ if (mNativeContext == 0 || (connection != null && !connection.isOpen())) {
|
||||
+ Log.w(TAG,
|
||||
+ "Detected attempt to cancel a request on a connection which isn't open");
|
||||
+ return false;
|
||||
+ }
|
||||
return native_cancel();
|
||||
}
|
||||
|
57
Patches/LineageOS-16.0/android_frameworks_base/349330.patch
Normal file
57
Patches/LineageOS-16.0/android_frameworks_base/349330.patch
Normal file
|
@ -0,0 +1,57 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jackal Guo <jackalguo@google.com>
|
||||
Date: Tue, 25 Oct 2022 15:03:55 +0800
|
||||
Subject: [PATCH] Correct the behavior of ACTION_PACKAGE_DATA_CLEARED
|
||||
|
||||
This action should be only broadcasted when the user data is cleared
|
||||
successfully. Broadcasting this action when failed case may result in
|
||||
unexpected result.
|
||||
|
||||
Bug: 240267890
|
||||
Test: manually using the PoC in the buganizer to ensure the symptom
|
||||
no longer exists.
|
||||
Change-Id: I0bb612627c81a2f2d7e3dbf53ea891ee49cf734b
|
||||
(cherry picked from commit 8b2e092146c7ab5c2952818dab6dcb6af9c417ce)
|
||||
Merged-In: I0bb612627c81a2f2d7e3dbf53ea891ee49cf734b
|
||||
---
|
||||
.../server/am/ActivityManagerService.java | 26 ++++++++++---------
|
||||
1 file changed, 14 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
|
||||
index 8f1692a24d27..dd41196e62a4 100644
|
||||
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
|
||||
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
|
||||
@@ -6718,19 +6718,21 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
finishForceStopPackageLocked(packageName, appInfo.uid);
|
||||
}
|
||||
}
|
||||
- final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
|
||||
- Uri.fromParts("package", packageName, null));
|
||||
- intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
|
||||
- intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
|
||||
- intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
|
||||
- if (isInstantApp) {
|
||||
- intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
|
||||
- broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
|
||||
- null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
|
||||
+ if (succeeded) {
|
||||
+ final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
|
||||
+ Uri.fromParts("package", packageName, null /* fragment */));
|
||||
+ intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
|
||||
+ intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
|
||||
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
|
||||
+ if (isInstantApp) {
|
||||
+ intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
|
||||
+ }
|
||||
+ broadcastIntentInPackage("android", SYSTEM_UID,
|
||||
+ intent, null /* resolvedType */, null /* resultTo */,
|
||||
+ 0 /* resultCode */, null /* resultData */, null /* resultExtras */,
|
||||
+ isInstantApp ? permission.ACCESS_INSTANT_APPS : null,
|
||||
+ null /* bOptions */, false /* serialized */, false /* sticky */,
|
||||
resolvedUserId);
|
||||
- } else {
|
||||
- broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
|
||||
- null, null, null, null, false, false, resolvedUserId);
|
||||
}
|
||||
|
||||
if (observer != null) {
|
27
Patches/LineageOS-16.0/android_frameworks_base/349331.patch
Normal file
27
Patches/LineageOS-16.0/android_frameworks_base/349331.patch
Normal file
|
@ -0,0 +1,27 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Dementyev <dementyev@google.com>
|
||||
Date: Tue, 22 Nov 2022 22:54:01 +0000
|
||||
Subject: [PATCH] Convert argument to intent in ChooseTypeAndAccountActivity
|
||||
|
||||
Bug: 244154558
|
||||
Test: manual
|
||||
Change-Id: I5a86639cd571e14e9a9f5d5ded631b5a7c08db7e
|
||||
(cherry picked from commit ede0a767c26f144e38b4a0c1c2f530b05ffd29a8)
|
||||
Merged-In: I5a86639cd571e14e9a9f5d5ded631b5a7c08db7e
|
||||
---
|
||||
core/java/android/accounts/ChooseTypeAndAccountActivity.java | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
|
||||
index 887ba18822f8..96f23a314e7b 100644
|
||||
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
|
||||
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
|
||||
@@ -407,7 +407,7 @@ public class ChooseTypeAndAccountActivity extends Activity
|
||||
mExistingAccounts = AccountManager.get(this).getAccountsForPackage(mCallingPackage,
|
||||
mCallingUid);
|
||||
intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
- startActivityForResult(intent, REQUEST_ADD_ACCOUNT);
|
||||
+ startActivityForResult(new Intent(intent), REQUEST_ADD_ACCOUNT);
|
||||
return;
|
||||
}
|
||||
} catch (OperationCanceledException e) {
|
47
Patches/LineageOS-16.0/android_frameworks_base/351910.patch
Normal file
47
Patches/LineageOS-16.0/android_frameworks_base/351910.patch
Normal file
|
@ -0,0 +1,47 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Reynolds <juliacr@google.com>
|
||||
Date: Mon, 16 May 2022 15:28:24 -0400
|
||||
Subject: [PATCH] Move service initialization
|
||||
|
||||
Occasionally ILockSettings can fail to be initialized otherwise
|
||||
Fixes: 232714129
|
||||
Test: boot (and eventually bootstress/reboot-long)
|
||||
|
||||
Change-Id: I2f9f9bdba37f4ebfaea56c1a6662f0474ae8a002
|
||||
Merged-In: I2f9f9bdba37f4ebfaea56c1a6662f0474ae8a002
|
||||
(cherry picked from commit 8e278543bd290d4b6c417758554d6dee93a4fe74)
|
||||
(cherry picked from commit caa5a22ea0c401c4eef548fb8161820beda3ff13)
|
||||
Merged-In: I2f9f9bdba37f4ebfaea56c1a6662f0474ae8a002
|
||||
---
|
||||
.../server/notification/NotificationManagerService.java | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
index a53f2aec436c..bcb657b5a8e2 100755
|
||||
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
@@ -1319,7 +1319,6 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
- private LockPatternUtils mLockPatternUtils;
|
||||
private StrongAuthTracker mStrongAuthTracker;
|
||||
|
||||
public NotificationManagerService(Context context) {
|
||||
@@ -1490,7 +1489,6 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
mHandler = new WorkerHandler(looper);
|
||||
mRankingThread.start();
|
||||
- mLockPatternUtils = new LockPatternUtils(getContext());
|
||||
mStrongAuthTracker = new StrongAuthTracker(getContext());
|
||||
String[] extractorNames;
|
||||
try {
|
||||
@@ -1737,7 +1735,7 @@ public class NotificationManagerService extends SystemService {
|
||||
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
|
||||
mKeyguardManager = getContext().getSystemService(KeyguardManager.class);
|
||||
mZenModeHelper.onSystemReady();
|
||||
- mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
|
||||
+ new LockPatternUtils(getContext()).registerStrongAuthTracker(mStrongAuthTracker);
|
||||
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
|
||||
// This observer will force an update when observe is called, causing us to
|
||||
// bind to listener services.
|
212
Patches/LineageOS-16.0/android_frameworks_base/351911.patch
Normal file
212
Patches/LineageOS-16.0/android_frameworks_base/351911.patch
Normal file
|
@ -0,0 +1,212 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Wenhao Wang <wenhaowang@google.com>
|
||||
Date: Tue, 30 Aug 2022 11:09:46 -0700
|
||||
Subject: [PATCH] Enable user graularity for lockdown mode
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The NotificationManagerService registers a LockPatternUtils.StrongAuthTracker
|
||||
to observe the StrongAuth changes of every user.
|
||||
More specifically, it’s the STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN flag.
|
||||
Via this flag, NotificationManagerService can perform the following operations
|
||||
when the user enter or exit lockdown mode:
|
||||
|
||||
Enter lockdown:
|
||||
1. Remove all the notifications belonging to the user.
|
||||
2. Set the local flag to indicate the lockdown is on for the user.
|
||||
The local flag will suppress the user's notifications on the
|
||||
post, remove and update functions.
|
||||
|
||||
Exit lockdown:
|
||||
1. Clear the local flag to indicate the lockdown is off for the user.
|
||||
2. Repost the user’s notifications (suppressed during lockdown mode).
|
||||
|
||||
The CL also updates corresponding tests.
|
||||
|
||||
Bug: 173721373
|
||||
Bug: 250743174
|
||||
Test: atest NotificationManagerServiceTest
|
||||
Test: atest NotificationListenersTest
|
||||
Ignore-AOSP-First: pending fix for a security issue.
|
||||
|
||||
Change-Id: I4f30e56550729db7d673a92d2a1250509713f36d
|
||||
Merged-In: I4f30e56550729db7d673a92d2a1250509713f36d
|
||||
(cherry picked from commit de3b12fca23178d8c821058261572449b67d5967)
|
||||
(cherry picked from commit 5e40f39f5bd4ae769d79ce022a64f1345512b65d)
|
||||
Merged-In: I4f30e56550729db7d673a92d2a1250509713f36d
|
||||
---
|
||||
.../NotificationManagerService.java | 75 ++++++++++++-------
|
||||
1 file changed, 46 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
index bcb657b5a8e2..0ac51524a648 100755
|
||||
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
@@ -1287,34 +1287,39 @@ public class NotificationManagerService extends SystemService {
|
||||
return (haystack & needle) != 0;
|
||||
}
|
||||
|
||||
- public boolean isInLockDownMode() {
|
||||
- return mIsInLockDownMode;
|
||||
+ // Return whether the user is in lockdown mode.
|
||||
+ // If the flag is not set, we assume the user is not in lockdown.
|
||||
+ public boolean isInLockDownMode(int userId) {
|
||||
+ return mUserInLockDownMode.get(userId, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onStrongAuthRequiredChanged(int userId) {
|
||||
boolean userInLockDownModeNext = containsFlag(getStrongAuthForUser(userId),
|
||||
STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
||||
- mUserInLockDownMode.put(userId, userInLockDownModeNext);
|
||||
- boolean isInLockDownModeNext = mUserInLockDownMode.indexOfValue(true) != -1;
|
||||
|
||||
- if (mIsInLockDownMode == isInLockDownModeNext) {
|
||||
+ // Nothing happens if the lockdown mode of userId keeps the same.
|
||||
+ if (userInLockDownModeNext == isInLockDownMode(userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
- if (isInLockDownModeNext) {
|
||||
- cancelNotificationsWhenEnterLockDownMode();
|
||||
+ // When the lockdown mode is changed, we perform the following steps.
|
||||
+ // If the userInLockDownModeNext is true, all the function calls to
|
||||
+ // notifyPostedLocked and notifyRemovedLocked will not be executed.
|
||||
+ // The cancelNotificationsWhenEnterLockDownMode calls notifyRemovedLocked
|
||||
+ // and postNotificationsWhenExitLockDownMode calls notifyPostedLocked.
|
||||
+ // So we shall call cancelNotificationsWhenEnterLockDownMode before
|
||||
+ // we set mUserInLockDownMode as true.
|
||||
+ // On the other hand, if the userInLockDownModeNext is false, we shall call
|
||||
+ // postNotificationsWhenExitLockDownMode after we put false into mUserInLockDownMode
|
||||
+ if (userInLockDownModeNext) {
|
||||
+ cancelNotificationsWhenEnterLockDownMode(userId);
|
||||
}
|
||||
|
||||
- // When the mIsInLockDownMode is true, both notifyPostedLocked and
|
||||
- // notifyRemovedLocked will be dismissed. So we shall call
|
||||
- // cancelNotificationsWhenEnterLockDownMode before we set mIsInLockDownMode
|
||||
- // as true and call postNotificationsWhenExitLockDownMode after we set
|
||||
- // mIsInLockDownMode as false.
|
||||
- mIsInLockDownMode = isInLockDownModeNext;
|
||||
+ mUserInLockDownMode.put(userId, userInLockDownModeNext);
|
||||
|
||||
- if (!isInLockDownModeNext) {
|
||||
- postNotificationsWhenExitLockDownMode();
|
||||
+ if (!userInLockDownModeNext) {
|
||||
+ postNotificationsWhenExitLockDownMode(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6417,11 +6422,14 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
- private void cancelNotificationsWhenEnterLockDownMode() {
|
||||
+ private void cancelNotificationsWhenEnterLockDownMode(int userId) {
|
||||
synchronized (mNotificationLock) {
|
||||
int numNotifications = mNotificationList.size();
|
||||
for (int i = 0; i < numNotifications; i++) {
|
||||
NotificationRecord rec = mNotificationList.get(i);
|
||||
+ if (rec.getUser().getIdentifier() != userId) {
|
||||
+ continue;
|
||||
+ }
|
||||
mListeners.notifyRemovedLocked(rec, REASON_CANCEL_ALL,
|
||||
rec.getStats());
|
||||
}
|
||||
@@ -6429,14 +6437,23 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
- private void postNotificationsWhenExitLockDownMode() {
|
||||
+ private void postNotificationsWhenExitLockDownMode(int userId) {
|
||||
synchronized (mNotificationLock) {
|
||||
int numNotifications = mNotificationList.size();
|
||||
+ // Set the delay to spread out the burst of notifications.
|
||||
+ long delay = 0;
|
||||
for (int i = 0; i < numNotifications; i++) {
|
||||
NotificationRecord rec = mNotificationList.get(i);
|
||||
- mListeners.notifyPostedLocked(rec, rec);
|
||||
+ if (rec.getUser().getIdentifier() != userId) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ mHandler.postDelayed(() -> {
|
||||
+ synchronized (mNotificationLock) {
|
||||
+ mListeners.notifyPostedLocked(rec, rec);
|
||||
+ }
|
||||
+ }, delay);
|
||||
+ delay += 20;
|
||||
}
|
||||
-
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6545,7 +6562,7 @@ public class NotificationManagerService extends SystemService {
|
||||
* notifications visible to the given listener.
|
||||
*/
|
||||
@GuardedBy("mNotificationLock")
|
||||
- private NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) {
|
||||
+ NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) {
|
||||
final int N = mNotificationList.size();
|
||||
ArrayList<String> keys = new ArrayList<String>(N);
|
||||
ArrayList<String> interceptedKeys = new ArrayList<String>(N);
|
||||
@@ -6562,6 +6579,9 @@ public class NotificationManagerService extends SystemService {
|
||||
Bundle hidden = new Bundle();
|
||||
for (int i = 0; i < N; i++) {
|
||||
NotificationRecord record = mNotificationList.get(i);
|
||||
+ if (isInLockDownMode(record.getUser().getIdentifier())) {
|
||||
+ continue;
|
||||
+ }
|
||||
if (!isVisibleToListener(record.sbn, info)) {
|
||||
continue;
|
||||
}
|
||||
@@ -6600,8 +6620,8 @@ public class NotificationManagerService extends SystemService {
|
||||
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, hidden);
|
||||
}
|
||||
|
||||
- boolean isInLockDownMode() {
|
||||
- return mStrongAuthTracker.isInLockDownMode();
|
||||
+ boolean isInLockDownMode(int userId) {
|
||||
+ return mStrongAuthTracker.isInLockDownMode(userId);
|
||||
}
|
||||
|
||||
boolean hasCompanionDevice(ManagedServiceInfo info) {
|
||||
@@ -6636,7 +6656,8 @@ public class NotificationManagerService extends SystemService {
|
||||
ServiceManager.getService(Context.COMPANION_DEVICE_SERVICE));
|
||||
}
|
||||
|
||||
- private boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) {
|
||||
+ @VisibleForTesting
|
||||
+ boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) {
|
||||
if (!listener.enabledAndUserMatches(sbn.getUserId())) {
|
||||
return false;
|
||||
}
|
||||
@@ -6926,7 +6947,7 @@ public class NotificationManagerService extends SystemService {
|
||||
@GuardedBy("mNotificationLock")
|
||||
void notifyPostedLocked(NotificationRecord r, NotificationRecord old,
|
||||
boolean notifyAllListeners) {
|
||||
- if (isInLockDownMode()) {
|
||||
+ if (isInLockDownMode(r.getUser().getIdentifier())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6992,7 +7013,7 @@ public class NotificationManagerService extends SystemService {
|
||||
@GuardedBy("mNotificationLock")
|
||||
public void notifyRemovedLocked(NotificationRecord r, int reason,
|
||||
NotificationStats notificationStats) {
|
||||
- if (isInLockDownMode()) {
|
||||
+ if (isInLockDownMode(r.getUser().getIdentifier())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7047,10 +7068,6 @@ public class NotificationManagerService extends SystemService {
|
||||
*/
|
||||
@GuardedBy("mNotificationLock")
|
||||
public void notifyRankingUpdateLocked(List<NotificationRecord> changedHiddenNotifications) {
|
||||
- if (isInLockDownMode()) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
boolean isHiddenRankingUpdate = changedHiddenNotifications != null
|
||||
&& changedHiddenNotifications.size() > 0;
|
||||
|
55
Patches/LineageOS-16.0/android_frameworks_base/351912.patch
Normal file
55
Patches/LineageOS-16.0/android_frameworks_base/351912.patch
Normal file
|
@ -0,0 +1,55 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nate Myren <ntmyren@google.com>
|
||||
Date: Fri, 2 Dec 2022 09:44:31 -0800
|
||||
Subject: [PATCH] RESTRICT AUTOMERGE Revoke dev perm if app is upgrading to
|
||||
post 23 and perm has pre23 flag
|
||||
|
||||
If a permission has the "pre23" flag, and an app is upgrading past api
|
||||
23, then we should not assume that a "development" permission remains
|
||||
granted
|
||||
|
||||
Fixes: 259458532
|
||||
Test: atest RevokeSawPermissionTest
|
||||
Change-Id: I214396f455c5ed9e8bac2e50b1525b86475c81c7
|
||||
(cherry picked from commit 2f30a63b11e59f9daf42f51eb85aa91c86f4baf4)
|
||||
Merged-In: I214396f455c5ed9e8bac2e50b1525b86475c81c7
|
||||
---
|
||||
.../pm/permission/PermissionManagerService.java | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
|
||||
index bdfe64c2c348..b902001cd359 100644
|
||||
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
|
||||
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
|
||||
@@ -418,7 +418,7 @@ public class PermissionManagerService {
|
||||
}
|
||||
final PackageSetting ps = (PackageSetting) newPackage.mExtras;
|
||||
if (grantSignaturePermission(Manifest.permission.SYSTEM_ALERT_WINDOW, newPackage, saw,
|
||||
- ps.getPermissionsState())) {
|
||||
+ ps.getPermissionsState(), true)) {
|
||||
return;
|
||||
}
|
||||
for (int userId: mUserManagerInt.getUserIds()) {
|
||||
@@ -1147,6 +1147,13 @@ public class PermissionManagerService {
|
||||
|
||||
private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
|
||||
BasePermission bp, PermissionsState origPermissions) {
|
||||
+ return grantSignaturePermission(perm, pkg, bp, origPermissions, false);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
|
||||
+ BasePermission bp, PermissionsState origPermissions,
|
||||
+ boolean isApi23Upgrade) {
|
||||
boolean oemPermission = bp.isOEM();
|
||||
boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
|
||||
boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
|
||||
@@ -1324,7 +1331,7 @@ public class PermissionManagerService {
|
||||
// Any pre-installed system app is allowed to get this permission.
|
||||
allowed = true;
|
||||
}
|
||||
- if (!allowed && bp.isDevelopment()) {
|
||||
+ if (!allowed && bp.isDevelopment() && !(bp.isPre23() && isApi23Upgrade)) {
|
||||
// For development permissions, a development permission
|
||||
// is granted only if it was already granted.
|
||||
allowed = origPermissions.hasInstallPermission(perm);
|
41
Patches/LineageOS-16.0/android_frameworks_base/351913.patch
Normal file
41
Patches/LineageOS-16.0/android_frameworks_base/351913.patch
Normal file
|
@ -0,0 +1,41 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Wright <michaelwr@google.com>
|
||||
Date: Mon, 26 Sep 2022 20:37:33 +0100
|
||||
Subject: [PATCH] Reconcile WorkSource parcel and unparcel code.
|
||||
|
||||
Prior to this CL, WorkSources would Parcel their list of WorkChains as
|
||||
-1 if null, or the size of the list followed by the list itself if
|
||||
non-null. When reading it back in, on the other hand, they would check
|
||||
if the size was positive, and only then read the list from the Parcel.
|
||||
This works for all cases except when the WorkSource has an empty but
|
||||
non-null list of WorkChains as the list would get written to the parcel,
|
||||
but then never read on the other side.
|
||||
|
||||
If parceling a list was a no-op when empty this wouldn't be an issue,
|
||||
but it must write at least its size into the parcel to know how many
|
||||
elements to extract. In the empty list case, this single element is left
|
||||
unread as the size is not positive which essentially corrupts any future
|
||||
items read from that same parcelable.
|
||||
|
||||
Bug: 220302519
|
||||
Test: atest android.security.cts.WorkSourceTest#testWorkChainParceling
|
||||
Change-Id: I2fec40dfced420ca38e717059b0e95ee8ef9946a
|
||||
(cherry picked from commit 266b3bddcf14d448c0972db64b42950f76c759e3)
|
||||
Merged-In: I2fec40dfced420ca38e717059b0e95ee8ef9946a
|
||||
---
|
||||
core/java/android/os/WorkSource.java | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
|
||||
index 327071906e18..c2f43edfc8af 100644
|
||||
--- a/core/java/android/os/WorkSource.java
|
||||
+++ b/core/java/android/os/WorkSource.java
|
||||
@@ -107,7 +107,7 @@ public class WorkSource implements Parcelable {
|
||||
mNames = in.createStringArray();
|
||||
|
||||
int numChains = in.readInt();
|
||||
- if (numChains > 0) {
|
||||
+ if (numChains >= 0) {
|
||||
mChains = new ArrayList<>(numChains);
|
||||
in.readParcelableList(mChains, WorkChain.class.getClassLoader());
|
||||
} else {
|
97
Patches/LineageOS-16.0/android_frameworks_base/354242.patch
Normal file
97
Patches/LineageOS-16.0/android_frameworks_base/354242.patch
Normal file
|
@ -0,0 +1,97 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jing Ji <jji@google.com>
|
||||
Date: Thu, 4 Aug 2022 11:36:26 -0700
|
||||
Subject: [PATCH] DO NOT MERGE: Context#startInstrumentation could be started
|
||||
from SHELL only now.
|
||||
|
||||
Or, if an instrumentation starts another instrumentation and so on,
|
||||
and the original instrumentation is started from SHELL, allow all
|
||||
Context#startInstrumentation calls in this chain.
|
||||
|
||||
Otherwise, it'll throw a SecurityException.
|
||||
|
||||
Bug: 237766679
|
||||
Test: atest CtsAppTestCases:InstrumentationTest
|
||||
Merged-In: Ia08f225c21a3933067d066a578ea4af9c23e7d4c
|
||||
Merged-In: I1b76f61c5fd6c9f7e738978592260945a606f40c
|
||||
Merged-In: I3ea7aa27bd776fec546908a37f667f680da9c892
|
||||
Change-Id: I7ca7345b064e8e74f7037b8fa3ed45bb6423e406
|
||||
(cherry picked from commit 8c90891a38ecb5047e115e13baf700a8b486a5d1)
|
||||
Merged-In: I7ca7345b064e8e74f7037b8fa3ed45bb6423e406
|
||||
---
|
||||
.../server/am/ActivityManagerService.java | 34 +++++++++++++++++++
|
||||
.../com/android/server/am/ProcessRecord.java | 4 +++
|
||||
2 files changed, 38 insertions(+)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
|
||||
index dd41196e62a4..f522b20f7ccd 100644
|
||||
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
|
||||
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
|
||||
@@ -4907,6 +4907,26 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
return procState;
|
||||
}
|
||||
|
||||
+ @GuardedBy("this")
|
||||
+ private boolean hasActiveInstrumentationLocked(int pid) {
|
||||
+ if (pid == 0) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ synchronized (mPidsSelfLocked) {
|
||||
+ ProcessRecord process = mPidsSelfLocked.get(pid);
|
||||
+ return process != null && process.getActiveInstrumentation() != null;
|
||||
+ }
|
||||
+ }
|
||||
+ private String getPackageNameByPid(int pid) {
|
||||
+ synchronized (mPidsSelfLocked) {
|
||||
+ final ProcessRecord app = mPidsSelfLocked.get(pid);
|
||||
+ if (app != null && app.info != null) {
|
||||
+ return app.info.packageName;
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private boolean isCallerShell() {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
return callingUid == SHELL_UID || callingUid == ROOT_UID;
|
||||
@@ -22264,6 +22284,8 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
|
||||
int userId, String abiOverride) {
|
||||
enforceNotIsolatedCaller("startInstrumentation");
|
||||
+ final int callingUid = Binder.getCallingUid();
|
||||
+ final int callingPid = Binder.getCallingPid();
|
||||
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
|
||||
userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
|
||||
// Refuse possible leaked file descriptors
|
||||
@@ -22312,6 +22334,18 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
throw new SecurityException(msg);
|
||||
}
|
||||
|
||||
+ if (!Build.IS_DEBUGGABLE && callingUid != ROOT_UID && callingUid != SHELL_UID
|
||||
+ && callingUid != SYSTEM_UID && !hasActiveInstrumentationLocked(callingPid)) {
|
||||
+ // If it's not debug build and not called from root/shell/system uid, reject it.
|
||||
+ final String msg = "Permission Denial: instrumentation test "
|
||||
+ + className + " from pid=" + callingPid + ", uid=" + callingUid
|
||||
+ + ", pkgName=" + getPackageNameByPid(callingPid)
|
||||
+ + " not allowed because it's not started from SHELL";
|
||||
+ Slog.wtfQuiet(TAG, msg);
|
||||
+ reportStartInstrumentationFailureLocked(watcher, className, msg);
|
||||
+ throw new SecurityException(msg);
|
||||
+ }
|
||||
+
|
||||
ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
|
||||
activeInstr.mClass = className;
|
||||
String defProcess = ai.processName;;
|
||||
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
|
||||
index b15cf6a606cc..5e14e81acac6 100644
|
||||
--- a/services/core/java/com/android/server/am/ProcessRecord.java
|
||||
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
|
||||
@@ -870,4 +870,8 @@ final class ProcessRecord {
|
||||
boolean hasForegroundServices() {
|
||||
return foregroundServices;
|
||||
}
|
||||
+
|
||||
+ ActiveInstrumentation getActiveInstrumentation() {
|
||||
+ return instr;
|
||||
+ }
|
||||
}
|
33
Patches/LineageOS-16.0/android_frameworks_base/354243.patch
Normal file
33
Patches/LineageOS-16.0/android_frameworks_base/354243.patch
Normal file
|
@ -0,0 +1,33 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kunal Malhotra <malhk@google.com>
|
||||
Date: Mon, 7 Nov 2022 23:33:55 +0000
|
||||
Subject: [PATCH] Checking if package belongs to UID before registering
|
||||
broadcast receiver
|
||||
|
||||
Test: manual testing done on device by installing test APK and checking if receiver can register
|
||||
Bug: 242040055
|
||||
Change-Id: Ia525f218a46f8bf7fff660cec0d6432f09fdf24d
|
||||
Merged-In: Ia525f218a46f8bf7fff660cec0d6432f09fdf24d
|
||||
(cherry picked from commit 790a8d0dd329460bc60456681cb446accf2a27e0)
|
||||
(cherry picked from commit 4f0dc37b896e06086391e71ce471e413215e1130)
|
||||
Merged-In: Ia525f218a46f8bf7fff660cec0d6432f09fdf24d
|
||||
---
|
||||
services/core/java/com/android/server/am/ActiveServices.java | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
|
||||
index 8b4013405b22..05be900e5403 100644
|
||||
--- a/services/core/java/com/android/server/am/ActiveServices.java
|
||||
+++ b/services/core/java/com/android/server/am/ActiveServices.java
|
||||
@@ -1971,6 +1971,11 @@ public final class ActiveServices {
|
||||
throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name +
|
||||
" is not an isolatedProcess");
|
||||
}
|
||||
+ if (AppGlobals.getPackageManager().getPackageUid(callingPackage,
|
||||
+ 0, userId) != callingUid) {
|
||||
+ throw new SecurityException("BIND_EXTERNAL_SERVICE failed, "
|
||||
+ + "calling package not owned by calling UID ");
|
||||
+ }
|
||||
// Run the service under the calling package's application.
|
||||
ApplicationInfo aInfo = AppGlobals.getPackageManager().getApplicationInfo(
|
||||
callingPackage, ActivityManagerService.STOCK_PM_FLAGS, userId);
|
71
Patches/LineageOS-16.0/android_frameworks_base/354244.patch
Normal file
71
Patches/LineageOS-16.0/android_frameworks_base/354244.patch
Normal file
|
@ -0,0 +1,71 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hao Ke <haok@google.com>
|
||||
Date: Mon, 12 Dec 2022 15:49:16 +0000
|
||||
Subject: [PATCH] Fix checkKeyIntentParceledCorrectly's bypass
|
||||
|
||||
The checkKeyIntentParceledCorrectly method was added in checkKeyIntent, which was originaly only invoked when AccountManagerService deserializes the KEY_INTENT value as not NULL. However, due to the self-changing bundle technique in Parcel mismatch problems, the Intent value can change after reparceling; hence would bypass the added checkKeyIntentParceledCorrectly call.
|
||||
|
||||
This CL did the following:
|
||||
|
||||
- Ensure the checkKeyIntent method is also called when result.getParcelable(AccountManager.KEY_INTENT) == null.
|
||||
|
||||
Bug: 260567867
|
||||
Bug: 262230405
|
||||
Test: local test, see b/262230405
|
||||
Test: atest CtsAccountManagerTestCases
|
||||
Merged-In: I7b528f52c41767ae12731838fdd36aa26a8f3477
|
||||
Change-Id: I7b528f52c41767ae12731838fdd36aa26a8f3477
|
||||
(cherry picked from commit 9f623983a8d4ec48d58b0eda56fa461fc6748981)
|
||||
Merged-In: I7b528f52c41767ae12731838fdd36aa26a8f3477
|
||||
---
|
||||
.../server/accounts/AccountManagerService.java | 15 +++++++++------
|
||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
index c1f401e9a11f..d2f5d59e7030 100644
|
||||
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
@@ -3408,8 +3408,7 @@ public class AccountManagerService
|
||||
Bundle.setDefusable(result, true);
|
||||
mNumResults++;
|
||||
Intent intent = null;
|
||||
- if (result != null
|
||||
- && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
|
||||
+ if (result != null) {
|
||||
if (!checkKeyIntent(
|
||||
Binder.getCallingUid(),
|
||||
result)) {
|
||||
@@ -4777,8 +4776,10 @@ public class AccountManagerService
|
||||
EventLog.writeEvent(0x534e4554, "250588548", authUid, "");
|
||||
return false;
|
||||
}
|
||||
-
|
||||
Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
|
||||
+ if (intent == null) {
|
||||
+ return true;
|
||||
+ }
|
||||
// Explicitly set an empty ClipData to ensure that we don't offer to
|
||||
// promote any Uris contained inside for granting purposes
|
||||
if (intent.getClipData() == null) {
|
||||
@@ -4831,7 +4832,10 @@ public class AccountManagerService
|
||||
p.recycle();
|
||||
Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
|
||||
Intent simulateIntent = simulateBundle.getParcelable(AccountManager.KEY_INTENT);
|
||||
- return (intent.filterEquals(simulateIntent));
|
||||
+ if (intent == null) {
|
||||
+ return (simulateIntent == null);
|
||||
+ }
|
||||
+ return intent.filterEquals(simulateIntent);
|
||||
}
|
||||
|
||||
private boolean isExportedSystemActivity(ActivityInfo activityInfo) {
|
||||
@@ -4976,8 +4980,7 @@ public class AccountManagerService
|
||||
}
|
||||
}
|
||||
}
|
||||
- if (result != null
|
||||
- && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
|
||||
+ if (result != null) {
|
||||
if (!checkKeyIntent(
|
||||
Binder.getCallingUid(),
|
||||
result)) {
|
34
Patches/LineageOS-16.0/android_frameworks_base/354245.patch
Normal file
34
Patches/LineageOS-16.0/android_frameworks_base/354245.patch
Normal file
|
@ -0,0 +1,34 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Winson Chiu <chiuwinson@google.com>
|
||||
Date: Fri, 6 Jan 2023 21:26:24 +0000
|
||||
Subject: [PATCH] Encode Intent scheme when serializing to URI string RESTRICT
|
||||
AUTOMERGE
|
||||
|
||||
Avoids deserialization error when the scheme contains a
|
||||
reserved character.
|
||||
|
||||
Bug: 261858325
|
||||
|
||||
Test: atest android.content.cts.IntentTest#testEncoding
|
||||
|
||||
Merged-In: Ic34b3f796b762763db5aa7b5d7c109ae70607470
|
||||
Change-Id: Ic34b3f796b762763db5aa7b5d7c109ae70607470
|
||||
(cherry picked from commit 43437b4ee6424933d4e403f0375ef8c1f07986f4)
|
||||
Merged-In: Ic34b3f796b762763db5aa7b5d7c109ae70607470
|
||||
---
|
||||
core/java/android/content/Intent.java | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
|
||||
index e4502ffdd61f..66c2658f9f13 100644
|
||||
--- a/core/java/android/content/Intent.java
|
||||
+++ b/core/java/android/content/Intent.java
|
||||
@@ -9860,7 +9860,7 @@ public class Intent implements Parcelable, Cloneable {
|
||||
private void toUriInner(StringBuilder uri, String scheme, String defAction,
|
||||
String defPackage, int flags) {
|
||||
if (scheme != null) {
|
||||
- uri.append("scheme=").append(scheme).append(';');
|
||||
+ uri.append("scheme=").append(Uri.encode(scheme)).append(';');
|
||||
}
|
||||
if (mAction != null && !mAction.equals(defAction)) {
|
||||
uri.append("action=").append(Uri.encode(mAction)).append(';');
|
81
Patches/LineageOS-16.0/android_frameworks_base/356154.patch
Normal file
81
Patches/LineageOS-16.0/android_frameworks_base/356154.patch
Normal file
|
@ -0,0 +1,81 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Norman <danielnorman@google.com>
|
||||
Date: Thu, 9 Feb 2023 12:28:26 -0800
|
||||
Subject: [PATCH] Checks if AccessibilityServiceInfo is within parcelable size.
|
||||
|
||||
- If too large when parsing service XMLs then skip this service.
|
||||
- If too large when a service attempts to update its own info
|
||||
then throw an error.
|
||||
|
||||
Bug: 261589597
|
||||
Test: atest AccessibilityServiceInfoTest
|
||||
Change-Id: Iffc0cd48cc713f7904d68059e141cb7de5a4b906
|
||||
Merged-In: Iffc0cd48cc713f7904d68059e141cb7de5a4b906
|
||||
(cherry picked from commit on googleplex-android-review.googlesource.com host: 553232c29079fbeab28f95307d025c1426aa7142)
|
||||
Merged-In: Iffc0cd48cc713f7904d68059e141cb7de5a4b906
|
||||
---
|
||||
.../accessibilityservice/AccessibilityService.java | 4 ++++
|
||||
.../accessibilityservice/AccessibilityServiceInfo.java | 10 ++++++++++
|
||||
.../accessibility/AccessibilityManagerService.java | 6 ++++++
|
||||
3 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
|
||||
index 6933e5201a21..ef59803e3ede 100644
|
||||
--- a/core/java/android/accessibilityservice/AccessibilityService.java
|
||||
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
|
||||
@@ -1488,6 +1488,10 @@ public abstract class AccessibilityService extends Service {
|
||||
IAccessibilityServiceConnection connection =
|
||||
AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
|
||||
if (mInfo != null && connection != null) {
|
||||
+ if (!mInfo.isWithinParcelableSize()) {
|
||||
+ throw new IllegalStateException(
|
||||
+ "Cannot update service info: size is larger than safe parcelable limits.");
|
||||
+ }
|
||||
try {
|
||||
connection.setServiceInfo(mInfo);
|
||||
mInfo = null;
|
||||
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
|
||||
index f85f35889aae..76930d75c5de 100644
|
||||
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
|
||||
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
|
||||
@@ -29,6 +29,7 @@ import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
+import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.AttributeSet;
|
||||
@@ -766,6 +767,15 @@ public class AccessibilityServiceInfo implements Parcelable {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ /** @hide */
|
||||
+ public final boolean isWithinParcelableSize() {
|
||||
+ final Parcel parcel = Parcel.obtain();
|
||||
+ writeToParcel(parcel, 0);
|
||||
+ final boolean result = parcel.dataSize() <= IBinder.MAX_IPC_SIZE;
|
||||
+ parcel.recycle();
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
public void writeToParcel(Parcel parcel, int flagz) {
|
||||
parcel.writeInt(eventTypes);
|
||||
parcel.writeStringArray(packageNames);
|
||||
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
|
||||
index 91d1b7576ca7..fd87be3e5649 100644
|
||||
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
|
||||
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
|
||||
@@ -1302,6 +1302,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
AccessibilityServiceInfo accessibilityServiceInfo;
|
||||
try {
|
||||
accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext);
|
||||
+ if (!accessibilityServiceInfo.isWithinParcelableSize()) {
|
||||
+ Slog.e(LOG_TAG, "Skipping service "
|
||||
+ + accessibilityServiceInfo.getResolveInfo().getComponentInfo()
|
||||
+ + " because service info size is larger than safe parcelable limits.");
|
||||
+ continue;
|
||||
+ }
|
||||
mTempAccessibilityServiceInfoList.add(accessibilityServiceInfo);
|
||||
} catch (XmlPullParserException | IOException xppe) {
|
||||
Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", xppe);
|
62
Patches/LineageOS-16.0/android_frameworks_base/356155.patch
Normal file
62
Patches/LineageOS-16.0/android_frameworks_base/356155.patch
Normal file
|
@ -0,0 +1,62 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Orion Hodson <oth@google.com>
|
||||
Date: Thu, 7 Apr 2022 21:42:04 +0100
|
||||
Subject: [PATCH] Uri: check authority and scheme as part of determining URI
|
||||
path
|
||||
|
||||
The interpretation of the path depends on whether the scheme or
|
||||
authority are specified and should be observed when unparcelling
|
||||
URIs.
|
||||
|
||||
Bug: 171966843
|
||||
Test: atest FrameworksCoreTests:android.net.UriTest
|
||||
Test: atest com.android.devicehealthchecks.SystemAppCheck
|
||||
Change-Id: I06981d1c6e387b16df792494523994518848db37
|
||||
Merged-In: I06981d1c6e387b16df792494523994518848db37
|
||||
(cherry picked from commit f37a94ae920fa5879c557603fc285942ec4b84b1)
|
||||
(cherry picked from commit on googleplex-android-review.googlesource.com host: c87f0623be4042c39a9b73f7a6e02aa116925e50)
|
||||
Merged-In: I06981d1c6e387b16df792494523994518848db37
|
||||
---
|
||||
core/java/android/net/Uri.java | 22 +++++++++++++++-------
|
||||
1 file changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
|
||||
index 0fb84b723634..af1c0e8e9178 100644
|
||||
--- a/core/java/android/net/Uri.java
|
||||
+++ b/core/java/android/net/Uri.java
|
||||
@@ -1179,13 +1179,16 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
}
|
||||
|
||||
static Uri readFrom(Parcel parcel) {
|
||||
- return new HierarchicalUri(
|
||||
- parcel.readString(),
|
||||
- Part.readFrom(parcel),
|
||||
- PathPart.readFrom(parcel),
|
||||
- Part.readFrom(parcel),
|
||||
- Part.readFrom(parcel)
|
||||
- );
|
||||
+ final String scheme = parcel.readString();
|
||||
+ final Part authority = Part.readFrom(parcel);
|
||||
+ // In RFC3986 the path should be determined based on whether there is a scheme or
|
||||
+ // authority present (https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3).
|
||||
+ final boolean hasSchemeOrAuthority =
|
||||
+ (scheme != null && scheme.length() > 0) || !authority.isEmpty();
|
||||
+ final PathPart path = PathPart.readFrom(hasSchemeOrAuthority, parcel);
|
||||
+ final Part query = Part.readFrom(parcel);
|
||||
+ final Part fragment = Part.readFrom(parcel);
|
||||
+ return new HierarchicalUri(scheme, authority, path, query, fragment);
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
@@ -2240,6 +2243,11 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
}
|
||||
}
|
||||
|
||||
+ static PathPart readFrom(boolean hasSchemeOrAuthority, Parcel parcel) {
|
||||
+ final PathPart path = readFrom(parcel);
|
||||
+ return hasSchemeOrAuthority ? makeAbsolute(path) : path;
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Creates a path from the encoded string.
|
||||
*
|
74
Patches/LineageOS-16.0/android_frameworks_base/356156.patch
Normal file
74
Patches/LineageOS-16.0/android_frameworks_base/356156.patch
Normal file
|
@ -0,0 +1,74 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Stuart <tjstuart@google.com>
|
||||
Date: Mon, 21 Nov 2022 17:38:21 -0800
|
||||
Subject: [PATCH] enforce stricter rules when registering phoneAccounts
|
||||
|
||||
- include disable accounts when looking up accounts for a package to
|
||||
check if the limit is reached (10)
|
||||
- put a new limit of 10 supported schemes
|
||||
- put a new limit of 256 characters per scheme
|
||||
- put a new limit of 256 characters per address
|
||||
- ensure the Icon can write to memory w/o throwing an exception
|
||||
|
||||
bug: 259064622
|
||||
bug: 256819769
|
||||
Test: cts + unit
|
||||
Change-Id: Ia7d8d00d9de0fb6694ded6a80c40bd55d7fdf7a7
|
||||
Merged-In: Ia7d8d00d9de0fb6694ded6a80c40bd55d7fdf7a7
|
||||
(cherry picked from commit on googleplex-android-review.googlesource.com host: a66a3156e03fbd1c3a29015db9193d66f2709f98)
|
||||
Merged-In: Ia7d8d00d9de0fb6694ded6a80c40bd55d7fdf7a7
|
||||
---
|
||||
.../java/android/telecom/PhoneAccount.java | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
|
||||
index 8e22221d7876..702b1cf87d7d 100644
|
||||
--- a/telecomm/java/android/telecom/PhoneAccount.java
|
||||
+++ b/telecomm/java/android/telecom/PhoneAccount.java
|
||||
@@ -439,6 +439,11 @@ public final class PhoneAccount implements Parcelable {
|
||||
|
||||
/**
|
||||
* Sets the address. See {@link PhoneAccount#getAddress}.
|
||||
+ * <p>
|
||||
+ * Note: The entire URI value is limited to 256 characters. This check is
|
||||
+ * enforced when registering the PhoneAccount via
|
||||
+ * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} and will cause an
|
||||
+ * {@link IllegalArgumentException} to be thrown if URI is over 256.
|
||||
*
|
||||
* @param value The address of the phone account.
|
||||
* @return The builder.
|
||||
@@ -472,6 +477,10 @@ public final class PhoneAccount implements Parcelable {
|
||||
|
||||
/**
|
||||
* Sets the icon. See {@link PhoneAccount#getIcon}.
|
||||
+ * <p>
|
||||
+ * Note: An {@link IllegalArgumentException} if the Icon cannot be written to memory.
|
||||
+ * This check is enforced when registering the PhoneAccount via
|
||||
+ * {@link TelecomManager#registerPhoneAccount(PhoneAccount)}
|
||||
*
|
||||
* @param icon The icon to set.
|
||||
*/
|
||||
@@ -505,6 +514,10 @@ public final class PhoneAccount implements Parcelable {
|
||||
/**
|
||||
* Specifies an additional URI scheme supported by the {@link PhoneAccount}.
|
||||
*
|
||||
+ * <p>
|
||||
+ * Each URI scheme is limited to 256 characters. Adding a scheme over 256 characters will
|
||||
+ * cause an {@link IllegalArgumentException} to be thrown when the account is registered.
|
||||
+ *
|
||||
* @param uriScheme The URI scheme.
|
||||
* @return The builder.
|
||||
*/
|
||||
@@ -518,6 +531,12 @@ public final class PhoneAccount implements Parcelable {
|
||||
/**
|
||||
* Specifies the URI schemes supported by the {@link PhoneAccount}.
|
||||
*
|
||||
+ * <p>
|
||||
+ * A max of 10 URI schemes can be added per account. Additionally, each URI scheme is
|
||||
+ * limited to 256 characters. Adding more than 10 URI schemes or 256 characters on any
|
||||
+ * scheme will cause an {@link IllegalArgumentException} to be thrown when the account
|
||||
+ * is registered.
|
||||
+ *
|
||||
* @param uriSchemes The URI schemes.
|
||||
* @return The builder.
|
||||
*/
|
167
Patches/LineageOS-16.0/android_frameworks_base/359730.patch
Normal file
167
Patches/LineageOS-16.0/android_frameworks_base/359730.patch
Normal file
|
@ -0,0 +1,167 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Lee <brnlee@google.com>
|
||||
Date: Fri, 17 Feb 2023 16:05:17 -0800
|
||||
Subject: [PATCH] Check key intent for selectors and prohibited flags
|
||||
|
||||
Bug: 265015796
|
||||
Test: atest
|
||||
FrameworksServicesTests: com.android.server.accounts.AccountManagerServiceTest
|
||||
(cherry picked from commit e53a96304352e2965176c8d32ac1b504e52ef185)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:92114886bdce8467c52c655c186f3e7ab1e134d8)
|
||||
Merged-In: Ie16f8654337bd75eaad3156817470674b4f0cee3
|
||||
Change-Id: Ie16f8654337bd75eaad3156817470674b4f0cee3
|
||||
---
|
||||
.../accounts/AccountManagerService.java | 18 +++++++---
|
||||
.../accounts/AccountManagerServiceTest.java | 36 +++++++++++++++++++
|
||||
.../AccountManagerServiceTestFixtures.java | 5 ++-
|
||||
.../TestAccountType1Authenticator.java | 5 +--
|
||||
4 files changed, 54 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
index d2f5d59e7030..36732273ab6f 100644
|
||||
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
@@ -4785,10 +4785,6 @@ public class AccountManagerService
|
||||
if (intent.getClipData() == null) {
|
||||
intent.setClipData(ClipData.newPlainText(null, null));
|
||||
}
|
||||
- intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
- | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
- | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
|
||||
- | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION));
|
||||
long bid = Binder.clearCallingIdentity();
|
||||
try {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
@@ -4835,7 +4831,19 @@ public class AccountManagerService
|
||||
if (intent == null) {
|
||||
return (simulateIntent == null);
|
||||
}
|
||||
- return intent.filterEquals(simulateIntent);
|
||||
+ if (!intent.filterEquals(simulateIntent)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (intent.getSelector() != simulateIntent.getSelector()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ int prohibitedFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
|
||||
+ return (simulateIntent.getFlags() & prohibitedFlags) == 0;
|
||||
}
|
||||
|
||||
private boolean isExportedSystemActivity(ActivityInfo activityInfo) {
|
||||
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
|
||||
index 73267e4868a6..c063f645a4ea 100644
|
||||
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
|
||||
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.accounts;
|
||||
|
||||
import static android.database.sqlite.SQLiteDatabase.deleteDatabase;
|
||||
+import static org.mockito.ArgumentMatchers.contains;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
@@ -681,6 +682,41 @@ public class AccountManagerServiceTest extends AndroidTestCase {
|
||||
assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
|
||||
}
|
||||
|
||||
+ @SmallTest
|
||||
+ public void testStartAddAccountSessionWhereAuthenticatorReturnsIntentWithProhibitedFlags()
|
||||
+ throws Exception {
|
||||
+ unlockSystemUser();
|
||||
+ ResolveInfo resolveInfo = new ResolveInfo();
|
||||
+ resolveInfo.activityInfo = new ActivityInfo();
|
||||
+ resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
|
||||
+ when(mMockPackageManager.resolveActivityAsUser(
|
||||
+ any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
|
||||
+ when(mMockPackageManager.checkSignatures(
|
||||
+ anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
|
||||
+
|
||||
+ final CountDownLatch latch = new CountDownLatch(1);
|
||||
+ Response response = new Response(latch, mMockAccountManagerResponse);
|
||||
+ Bundle options = createOptionsWithAccountName(
|
||||
+ AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE);
|
||||
+ int prohibitedFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
|
||||
+ options.putInt(AccountManagerServiceTestFixtures.KEY_INTENT_FLAGS, prohibitedFlags);
|
||||
+
|
||||
+ mAms.startAddAccountSession(
|
||||
+ response, // response
|
||||
+ AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
|
||||
+ "authTokenType",
|
||||
+ null, // requiredFeatures
|
||||
+ true, // expectActivityLaunch
|
||||
+ options); // optionsIn
|
||||
+ waitForLatch(latch);
|
||||
+
|
||||
+ verify(mMockAccountManagerResponse).onError(
|
||||
+ eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), contains("invalid intent"));
|
||||
+ }
|
||||
+
|
||||
@SmallTest
|
||||
public void testStartAddAccountSessionError() throws Exception {
|
||||
unlockSystemUser();
|
||||
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
|
||||
index 73f30d9f9e79..b98a6a891d55 100644
|
||||
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
|
||||
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
|
||||
@@ -17,9 +17,6 @@ package com.android.server.accounts;
|
||||
|
||||
import android.accounts.Account;
|
||||
|
||||
-import java.util.ArrayList;
|
||||
-import java.util.List;
|
||||
-
|
||||
/**
|
||||
* Constants shared between test AccountAuthenticators and AccountManagerServiceTest.
|
||||
*/
|
||||
@@ -31,6 +28,8 @@ public final class AccountManagerServiceTestFixtures {
|
||||
"account_manager_service_test:account_status_token_key";
|
||||
public static final String KEY_ACCOUNT_PASSWORD =
|
||||
"account_manager_service_test:account_password_key";
|
||||
+ public static final String KEY_INTENT_FLAGS =
|
||||
+ "account_manager_service_test:intent_flags_key";
|
||||
public static final String KEY_OPTIONS_BUNDLE =
|
||||
"account_manager_service_test:option_bundle_key";
|
||||
public static final String ACCOUNT_NAME_SUCCESS = "success_on_return@fixture.com";
|
||||
diff --git a/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java b/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
|
||||
index 8106364477d9..924443e9d5cf 100644
|
||||
--- a/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
|
||||
+++ b/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
|
||||
@@ -24,8 +24,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
-import com.android.frameworks.servicestests.R;
|
||||
-
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
@@ -270,11 +268,13 @@ public class TestAccountType1Authenticator extends AbstractAccountAuthenticator
|
||||
String accountName = null;
|
||||
Bundle sessionBundle = null;
|
||||
String password = null;
|
||||
+ int intentFlags = 0;
|
||||
if (options != null) {
|
||||
accountName = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME);
|
||||
sessionBundle = options.getBundle(
|
||||
AccountManagerServiceTestFixtures.KEY_ACCOUNT_SESSION_BUNDLE);
|
||||
password = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_PASSWORD);
|
||||
+ intentFlags = options.getInt(AccountManagerServiceTestFixtures.KEY_INTENT_FLAGS, 0);
|
||||
}
|
||||
|
||||
Bundle result = new Bundle();
|
||||
@@ -302,6 +302,7 @@ public class TestAccountType1Authenticator extends AbstractAccountAuthenticator
|
||||
intent.putExtra(AccountManagerServiceTestFixtures.KEY_RESULT,
|
||||
eventualActivityResultData);
|
||||
intent.putExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK, response);
|
||||
+ intent.setFlags(intentFlags);
|
||||
|
||||
result.putParcelable(AccountManager.KEY_INTENT, intent);
|
||||
} else {
|
79
Patches/LineageOS-16.0/android_frameworks_base/359731.patch
Normal file
79
Patches/LineageOS-16.0/android_frameworks_base/359731.patch
Normal file
|
@ -0,0 +1,79 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kweku Adams <kwekua@google.com>
|
||||
Date: Wed, 21 Sep 2022 22:13:01 +0000
|
||||
Subject: [PATCH] Handle invalid data during job loading.
|
||||
|
||||
Catch exceptions that may be thrown if invalid data ended up in the
|
||||
persisted job file.
|
||||
|
||||
Bug: 246541702
|
||||
Bug: 246542132
|
||||
Bug: 246542285
|
||||
Bug: 246542330
|
||||
Test: install test app with invalid job config, start app to schedule job, then reboot device
|
||||
(cherry picked from commit c98fb42b480b3beedc2d94de6110f50212c4aa0b)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:df1ba00dd9f64a3ae9a9e05979dfae6a15c7e203)
|
||||
Merged-In: Id0ceba345942baf21177f687b8dd85ef001c0a9e
|
||||
Change-Id: Id0ceba345942baf21177f687b8dd85ef001c0a9e
|
||||
---
|
||||
.../java/com/android/server/job/JobStore.java | 26 ++++++++++++++++---
|
||||
1 file changed, 23 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
|
||||
index 4f8b1dcc6bb4..7f2d7fb5987d 100644
|
||||
--- a/services/core/java/com/android/server/job/JobStore.java
|
||||
+++ b/services/core/java/com/android/server/job/JobStore.java
|
||||
@@ -623,6 +623,10 @@ public final class JobStore {
|
||||
}
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
Slog.wtf(TAG, "Error jobstore xml.", e);
|
||||
+ } catch (Exception e) {
|
||||
+ // Crashing at this point would result in a boot loop, so live with a general
|
||||
+ // Exception for system stability's sake.
|
||||
+ Slog.wtf(TAG, "Unexpected exception", e);
|
||||
} finally {
|
||||
if (mPersistInfo.countAllJobsLoaded < 0) { // Only set them once.
|
||||
mPersistInfo.countAllJobsLoaded = numJobs;
|
||||
@@ -753,6 +757,15 @@ public final class JobStore {
|
||||
} catch (NumberFormatException e) {
|
||||
Slog.d(TAG, "Error reading constraints, skipping.");
|
||||
return null;
|
||||
+ } catch (XmlPullParserException e) {
|
||||
+ Slog.d(TAG, "Error Parser Exception.", e);
|
||||
+ return null;
|
||||
+ } catch (IOException e) {
|
||||
+ Slog.d(TAG, "Error I/O Exception.", e);
|
||||
+ return null;
|
||||
+ } catch (IllegalArgumentException e) {
|
||||
+ Slog.e(TAG, "Constraints contained invalid data", e);
|
||||
+ return null;
|
||||
}
|
||||
parser.next(); // Consume </constraints>
|
||||
|
||||
@@ -848,8 +861,14 @@ public final class JobStore {
|
||||
return null;
|
||||
}
|
||||
|
||||
- PersistableBundle extras = PersistableBundle.restoreFromXml(parser);
|
||||
- jobBuilder.setExtras(extras);
|
||||
+ final PersistableBundle extras;
|
||||
+ try {
|
||||
+ extras = PersistableBundle.restoreFromXml(parser);
|
||||
+ jobBuilder.setExtras(extras);
|
||||
+ } catch (IllegalArgumentException e) {
|
||||
+ Slog.e(TAG, "Persisted extras contained invalid data", e);
|
||||
+ return null;
|
||||
+ }
|
||||
parser.nextTag(); // Consume </extras>
|
||||
|
||||
// Migrate sync jobs forward from earlier, incomplete representation
|
||||
@@ -887,7 +906,8 @@ public final class JobStore {
|
||||
return new JobInfo.Builder(jobId, cname);
|
||||
}
|
||||
|
||||
- private void buildConstraintsFromXml(JobInfo.Builder jobBuilder, XmlPullParser parser) {
|
||||
+ private void buildConstraintsFromXml(JobInfo.Builder jobBuilder, XmlPullParser parser)
|
||||
+ throws XmlPullParserException, IOException {
|
||||
String val;
|
||||
|
||||
final String netCapabilities = parser.getAttributeValue(null, "net-capabilities");
|
232
Patches/LineageOS-16.0/android_frameworks_base/359732.patch
Normal file
232
Patches/LineageOS-16.0/android_frameworks_base/359732.patch
Normal file
|
@ -0,0 +1,232 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Reynolds <juliacr@google.com>
|
||||
Date: Tue, 7 Mar 2023 15:44:49 -0500
|
||||
Subject: [PATCH] Allow filtering of services
|
||||
|
||||
Test: ServiceListingTest
|
||||
Bug: 260570119
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:44dcb8351e61f4b3a63ec68fa5d8490501e8a823)
|
||||
Merged-In: Ib4740ba401667de62fa1a33334c2c1fbee25b760
|
||||
Change-Id: Ib4740ba401667de62fa1a33334c2c1fbee25b760
|
||||
---
|
||||
.../applications/ServiceListing.java | 19 +++-
|
||||
.../applications/ServiceListingTest.java | 98 ++++++++++++++++++-
|
||||
2 files changed, 113 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java b/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
|
||||
index 3c3c70ac364e..8c1cc256eee4 100644
|
||||
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
|
||||
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
|
||||
@@ -37,6 +37,7 @@ import com.android.settingslib.wrapper.PackageManagerWrapper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
+import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Class for managing services matching a given intent and requesting a given permission.
|
||||
@@ -52,11 +53,13 @@ public class ServiceListing {
|
||||
private final HashSet<ComponentName> mEnabledServices = new HashSet<>();
|
||||
private final List<ServiceInfo> mServices = new ArrayList<>();
|
||||
private final List<Callback> mCallbacks = new ArrayList<>();
|
||||
+ private final Predicate mValidator;
|
||||
|
||||
private boolean mListening;
|
||||
|
||||
private ServiceListing(Context context, String tag,
|
||||
- String setting, String intentAction, String permission, String noun) {
|
||||
+ String setting, String intentAction, String permission, String noun,
|
||||
+ Predicate validator) {
|
||||
mContentResolver = context.getContentResolver();
|
||||
mContext = context;
|
||||
mTag = tag;
|
||||
@@ -64,6 +67,7 @@ public class ServiceListing {
|
||||
mIntentAction = intentAction;
|
||||
mPermission = permission;
|
||||
mNoun = noun;
|
||||
+ mValidator = validator;
|
||||
}
|
||||
|
||||
public void addCallback(Callback callback) {
|
||||
@@ -133,7 +137,6 @@ public class ServiceListing {
|
||||
new Intent(mIntentAction),
|
||||
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
|
||||
user);
|
||||
-
|
||||
for (ResolveInfo resolveInfo : installedServices) {
|
||||
ServiceInfo info = resolveInfo.serviceInfo;
|
||||
|
||||
@@ -144,6 +147,9 @@ public class ServiceListing {
|
||||
+ mPermission);
|
||||
continue;
|
||||
}
|
||||
+ if (mValidator != null && !mValidator.test(info)) {
|
||||
+ continue;
|
||||
+ }
|
||||
mServices.add(info);
|
||||
}
|
||||
for (Callback callback : mCallbacks) {
|
||||
@@ -189,6 +195,7 @@ public class ServiceListing {
|
||||
private String mIntentAction;
|
||||
private String mPermission;
|
||||
private String mNoun;
|
||||
+ private Predicate mValidator;
|
||||
|
||||
public Builder(Context context) {
|
||||
mContext = context;
|
||||
@@ -219,8 +226,14 @@ public class ServiceListing {
|
||||
return this;
|
||||
}
|
||||
|
||||
+ public Builder setValidator(Predicate<ServiceInfo> validator) {
|
||||
+ mValidator = validator;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
public ServiceListing build() {
|
||||
- return new ServiceListing(mContext, mTag, mSetting, mIntentAction, mPermission, mNoun);
|
||||
+ return new ServiceListing(mContext, mTag, mSetting, mIntentAction, mPermission, mNoun,
|
||||
+ mValidator);
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
|
||||
index 060b716bb435..6cfbd458fd79 100644
|
||||
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
|
||||
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
|
||||
@@ -17,21 +17,36 @@
|
||||
package com.android.settingslib.applications;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
+import static org.mockito.ArgumentMatchers.any;
|
||||
+import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.Mockito.mock;
|
||||
+import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
+import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.content.ComponentName;
|
||||
+import android.content.Context;
|
||||
+import android.content.pm.PackageManager;
|
||||
+import android.content.pm.ResolveInfo;
|
||||
+import android.content.pm.ServiceInfo;
|
||||
import android.provider.Settings;
|
||||
|
||||
+import androidx.test.core.app.ApplicationProvider;
|
||||
+
|
||||
import com.android.settingslib.SettingsLibRobolectricTestRunner;
|
||||
|
||||
+import com.google.common.collect.ImmutableList;
|
||||
+
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
+import org.mockito.ArgumentCaptor;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
+import java.util.List;
|
||||
+
|
||||
@RunWith(SettingsLibRobolectricTestRunner.class)
|
||||
public class ServiceListingTest {
|
||||
|
||||
@@ -39,16 +54,97 @@ public class ServiceListingTest {
|
||||
private static final String TEST_INTENT = "com.example.intent";
|
||||
|
||||
private ServiceListing mServiceListing;
|
||||
+ private Context mContext;
|
||||
+ private PackageManager mPm;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
- mServiceListing = new ServiceListing.Builder(RuntimeEnvironment.application)
|
||||
+ mPm = mock(PackageManager.class);
|
||||
+ mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
+ when(mContext.getPackageManager()).thenReturn(mPm);
|
||||
+
|
||||
+ mServiceListing = new ServiceListing.Builder(mContext)
|
||||
+ .setTag("testTag")
|
||||
+ .setSetting(TEST_SETTING)
|
||||
+ .setNoun("testNoun")
|
||||
+ .setIntentAction(TEST_INTENT)
|
||||
+ .setPermission("testPermission")
|
||||
+ .build();
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testValidator() {
|
||||
+ ServiceInfo s1 = new ServiceInfo();
|
||||
+ s1.permission = "testPermission";
|
||||
+ s1.packageName = "pkg";
|
||||
+ ServiceInfo s2 = new ServiceInfo();
|
||||
+ s2.permission = "testPermission";
|
||||
+ s2.packageName = "pkg2";
|
||||
+ ResolveInfo r1 = new ResolveInfo();
|
||||
+ r1.serviceInfo = s1;
|
||||
+ ResolveInfo r2 = new ResolveInfo();
|
||||
+ r2.serviceInfo = s2;
|
||||
+
|
||||
+ when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(
|
||||
+ ImmutableList.of(r1, r2));
|
||||
+
|
||||
+ mServiceListing = new ServiceListing.Builder(mContext)
|
||||
+ .setTag("testTag")
|
||||
+ .setSetting(TEST_SETTING)
|
||||
+ .setNoun("testNoun")
|
||||
+ .setIntentAction(TEST_INTENT)
|
||||
+ .setValidator(info -> {
|
||||
+ if (info.packageName.equals("pkg")) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ })
|
||||
+ .setPermission("testPermission")
|
||||
+ .build();
|
||||
+ ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
|
||||
+ mServiceListing.addCallback(callback);
|
||||
+ mServiceListing.reload();
|
||||
+
|
||||
+ verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt());
|
||||
+ ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class);
|
||||
+ verify(callback, times(1)).onServicesReloaded(captor.capture());
|
||||
+
|
||||
+ assertThat(captor.getValue().size()).isEqualTo(1);
|
||||
+ assertThat(captor.getValue().get(0)).isEqualTo(s1);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testNoValidator() {
|
||||
+ ServiceInfo s1 = new ServiceInfo();
|
||||
+ s1.permission = "testPermission";
|
||||
+ s1.packageName = "pkg";
|
||||
+ ServiceInfo s2 = new ServiceInfo();
|
||||
+ s2.permission = "testPermission";
|
||||
+ s2.packageName = "pkg2";
|
||||
+ ResolveInfo r1 = new ResolveInfo();
|
||||
+ r1.serviceInfo = s1;
|
||||
+ ResolveInfo r2 = new ResolveInfo();
|
||||
+ r2.serviceInfo = s2;
|
||||
+
|
||||
+ when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(
|
||||
+ ImmutableList.of(r1, r2));
|
||||
+
|
||||
+ mServiceListing = new ServiceListing.Builder(mContext)
|
||||
.setTag("testTag")
|
||||
.setSetting(TEST_SETTING)
|
||||
.setNoun("testNoun")
|
||||
.setIntentAction(TEST_INTENT)
|
||||
.setPermission("testPermission")
|
||||
.build();
|
||||
+ ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
|
||||
+ mServiceListing.addCallback(callback);
|
||||
+ mServiceListing.reload();
|
||||
+
|
||||
+ verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt());
|
||||
+ ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class);
|
||||
+ verify(callback, times(1)).onServicesReloaded(captor.capture());
|
||||
+
|
||||
+ assertThat(captor.getValue().size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
85
Patches/LineageOS-16.0/android_frameworks_base/359733.patch
Normal file
85
Patches/LineageOS-16.0/android_frameworks_base/359733.patch
Normal file
|
@ -0,0 +1,85 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Valentin Iftime <valiiftime@google.com>
|
||||
Date: Wed, 22 Feb 2023 09:38:55 +0100
|
||||
Subject: [PATCH] Prevent RemoteViews crashing SystemUi
|
||||
|
||||
Catch canvas drawing exceptions caused by unsuported image sizes.
|
||||
|
||||
Test: 1. Post a custom view notification with a layout
|
||||
containing an ImageView that references a 5k x 5k image
|
||||
2. Add an App Widget to the home screen with that has the
|
||||
layout mentioned above as preview/initial layout.
|
||||
|
||||
Bug: 268193777
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:cfc0b34432ab54e3fa472db5c43e620293f64a5d)
|
||||
Merged-In: Ib3bda769c499b4069b49c566b1b227f98f707a8a
|
||||
Change-Id: Ib3bda769c499b4069b49c566b1b227f98f707a8a
|
||||
---
|
||||
.../android/appwidget/AppWidgetHostView.java | 39 ++++++++++++++-----
|
||||
1 file changed, 29 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
|
||||
index ab0eb92e1726..02b244bdd9a6 100644
|
||||
--- a/core/java/android/appwidget/AppWidgetHostView.java
|
||||
+++ b/core/java/android/appwidget/AppWidgetHostView.java
|
||||
@@ -21,6 +21,7 @@ import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources;
|
||||
+import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
@@ -248,19 +249,26 @@ public class AppWidgetHostView extends FrameLayout {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
} catch (final RuntimeException e) {
|
||||
Log.e(TAG, "Remote provider threw runtime exception, using error view instead.", e);
|
||||
- removeViewInLayout(mView);
|
||||
- View child = getErrorView();
|
||||
- prepareView(child);
|
||||
- addViewInLayout(child, 0, child.getLayoutParams());
|
||||
- measureChild(child, MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
|
||||
- MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
|
||||
- child.layout(0, 0, child.getMeasuredWidth() + mPaddingLeft + mPaddingRight,
|
||||
- child.getMeasuredHeight() + mPaddingTop + mPaddingBottom);
|
||||
- mView = child;
|
||||
- mViewMode = VIEW_MODE_ERROR;
|
||||
+ handleViewError();
|
||||
}
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Remove bad view and replace with error message view
|
||||
+ */
|
||||
+ private void handleViewError() {
|
||||
+ removeViewInLayout(mView);
|
||||
+ View child = getErrorView();
|
||||
+ prepareView(child);
|
||||
+ addViewInLayout(child, 0, child.getLayoutParams());
|
||||
+ measureChild(child, MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
|
||||
+ MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
|
||||
+ child.layout(0, 0, child.getMeasuredWidth() + mPaddingLeft + mPaddingRight,
|
||||
+ child.getMeasuredHeight() + mPaddingTop + mPaddingBottom);
|
||||
+ mView = child;
|
||||
+ mViewMode = VIEW_MODE_ERROR;
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Provide guidance about the size of this widget to the AppWidgetManager. The widths and
|
||||
* heights should correspond to the full area the AppWidgetHostView is given. Padding added by
|
||||
@@ -646,4 +654,15 @@ public class AppWidgetHostView extends FrameLayout {
|
||||
super.onInitializeAccessibilityNodeInfoInternal(info);
|
||||
info.setClassName(AppWidgetHostView.class.getName());
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ protected void dispatchDraw(Canvas canvas) {
|
||||
+ try {
|
||||
+ super.dispatchDraw(canvas);
|
||||
+ } catch (Exception e) {
|
||||
+ // Catch draw exceptions that may be caused by RemoteViews
|
||||
+ Log.e(TAG, "Drawing view failed: " + e);
|
||||
+ post(this::handleViewError);
|
||||
+ }
|
||||
+ }
|
||||
}
|
145
Patches/LineageOS-16.0/android_frameworks_base/361254.patch
Normal file
145
Patches/LineageOS-16.0/android_frameworks_base/361254.patch
Normal file
|
@ -0,0 +1,145 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lucas Lin <lucaslin@google.com>
|
||||
Date: Fri, 3 Mar 2023 08:13:50 +0000
|
||||
Subject: [PATCH] Sanitize VPN label to prevent HTML injection
|
||||
|
||||
This commit will try to sanitize the content of VpnDialog. This
|
||||
commit creates a function which will try to sanitize the VPN
|
||||
label, if the sanitized VPN label is different from the original
|
||||
one, which means the VPN label might contain HTML tag or the VPN
|
||||
label violates the words restriction(may contain some wording
|
||||
which will mislead the user). For this kind of case, show the
|
||||
package name instead of the VPN label to prevent misleading the
|
||||
user.
|
||||
|
||||
The malicious VPN app might be able to add a large number of line
|
||||
breaks with HTML in order to hide the system-displayed text from
|
||||
the user in the connection request dialog. Thus, sanitizing the
|
||||
content of the dialog is needed.
|
||||
|
||||
Bug: 204554636
|
||||
Test: N/A
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2178216b98bf9865edee198f45192f0b883624ab)
|
||||
Merged-In: I8eb890fd2e5797d8d6ab5b12f9c628bc9616081d
|
||||
Change-Id: I8eb890fd2e5797d8d6ab5b12f9c628bc9616081d
|
||||
---
|
||||
packages/VpnDialogs/res/values/strings.xml | 28 ++++++++++
|
||||
.../com/android/vpndialogs/ConfirmDialog.java | 53 +++++++++++++++++--
|
||||
2 files changed, 76 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/packages/VpnDialogs/res/values/strings.xml b/packages/VpnDialogs/res/values/strings.xml
|
||||
index 443a9bc33b90..b4166f0bedfd 100644
|
||||
--- a/packages/VpnDialogs/res/values/strings.xml
|
||||
+++ b/packages/VpnDialogs/res/values/strings.xml
|
||||
@@ -89,4 +89,32 @@
|
||||
without any consequences. [CHAR LIMIT=20] -->
|
||||
<string name="dismiss">Dismiss</string>
|
||||
|
||||
+ <!-- Malicious VPN apps may provide very long labels or cunning HTML to trick the system dialogs
|
||||
+ into displaying what they want. The system will attempt to sanitize the label, and if the
|
||||
+ label is deemed dangerous, then this string is used instead. The first argument is the
|
||||
+ first 30 characters of the label, and the second argument is the package name of the app.
|
||||
+ Example : Normally a VPN app may be called "My VPN app" in which case the dialog will read
|
||||
+ "My VPN app wants to set up a VPN connection...". If the label is very long, then, this
|
||||
+ will be used to show "VerylongVPNlabel… (com.my.vpn.app) wants to set up a VPN
|
||||
+ connection...". For this case, the code will refer to sanitized_vpn_label_with_ellipsis.
|
||||
+ -->
|
||||
+ <string name="sanitized_vpn_label_with_ellipsis">
|
||||
+ <xliff:g id="sanitized_vpn_label_with_ellipsis" example="My VPN app">%1$s</xliff:g>… (
|
||||
+ <xliff:g id="sanitized_vpn_label_with_ellipsis" example="com.my.vpn.app">%2$s</xliff:g>)
|
||||
+ </string>
|
||||
+
|
||||
+ <!-- Malicious VPN apps may provide very long labels or cunning HTML to trick the system dialogs
|
||||
+ into displaying what they want. The system will attempt to sanitize the label, and if the
|
||||
+ label is deemed dangerous, then this string is used instead. The first argument is the
|
||||
+ label, and the second argument is the package name of the app.
|
||||
+ Example : Normally a VPN app may be called "My VPN app" in which case the dialog will read
|
||||
+ "My VPN app wants to set up a VPN connection...". If the VPN label contains HTML tag but
|
||||
+ the length is not very long, the dialog will show "VpnLabelWith<br>HtmlTag
|
||||
+ (com.my.vpn.app) wants to set up a VPN connection...". For this case, the code will refer
|
||||
+ to sanitized_vpn_label.
|
||||
+ -->
|
||||
+ <string name="sanitized_vpn_label">
|
||||
+ <xliff:g id="sanitized_vpn_label" example="My VPN app">%1$s</xliff:g> (
|
||||
+ <xliff:g id="sanitized_vpn_label" example="com.my.vpn.app">%2$s</xliff:g>)
|
||||
+ </string>
|
||||
</resources>
|
||||
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
|
||||
index 09339743db5c..43d18df3a10d 100644
|
||||
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
|
||||
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
|
||||
@@ -42,10 +42,52 @@ public class ConfirmDialog extends AlertActivity
|
||||
implements DialogInterface.OnClickListener, ImageGetter {
|
||||
private static final String TAG = "VpnConfirm";
|
||||
|
||||
+ // Usually the label represents the app name, 150 code points might be enough to display the app
|
||||
+ // name, and 150 code points won't cover the warning message from VpnDialog.
|
||||
+ static final int MAX_VPN_LABEL_LENGTH = 150;
|
||||
+
|
||||
private String mPackage;
|
||||
|
||||
private IConnectivityManager mService;
|
||||
|
||||
+ private View mView;
|
||||
+
|
||||
+ /**
|
||||
+ * This function will use the string resource to combine the VPN label and the package name.
|
||||
+ *
|
||||
+ * If the VPN label violates the length restriction, the first 30 code points of VPN label and
|
||||
+ * the package name will be returned. Or return the VPN label and the package name directly if
|
||||
+ * the VPN label doesn't violate the length restriction.
|
||||
+ *
|
||||
+ * The result will be something like,
|
||||
+ * - ThisIsAVeryLongVpnAppNameWhich... (com.vpn.app)
|
||||
+ * if the VPN label violates the length restriction.
|
||||
+ * or
|
||||
+ * - VpnLabelWith<br>HtmlTag (com.vpn.app)
|
||||
+ * if the VPN label doesn't violate the length restriction.
|
||||
+ *
|
||||
+ */
|
||||
+ private String getSimplifiedLabel(String vpnLabel, String packageName) {
|
||||
+ if (vpnLabel.codePointCount(0, vpnLabel.length()) > 30) {
|
||||
+ return getString(R.string.sanitized_vpn_label_with_ellipsis,
|
||||
+ vpnLabel.substring(0, vpnLabel.offsetByCodePoints(0, 30)),
|
||||
+ packageName);
|
||||
+ }
|
||||
+
|
||||
+ return getString(R.string.sanitized_vpn_label, vpnLabel, packageName);
|
||||
+ }
|
||||
+
|
||||
+ protected String getSanitizedVpnLabel(String vpnLabel, String packageName) {
|
||||
+ final String sanitizedVpnLabel = Html.escapeHtml(vpnLabel);
|
||||
+ final boolean exceedMaxVpnLabelLength = sanitizedVpnLabel.codePointCount(0,
|
||||
+ sanitizedVpnLabel.length()) > MAX_VPN_LABEL_LENGTH;
|
||||
+ if (exceedMaxVpnLabelLength || !vpnLabel.equals(sanitizedVpnLabel)) {
|
||||
+ return getSimplifiedLabel(sanitizedVpnLabel, packageName);
|
||||
+ }
|
||||
+
|
||||
+ return sanitizedVpnLabel;
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -68,15 +110,16 @@ public class ConfirmDialog extends AlertActivity
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
- View view = View.inflate(this, R.layout.confirm, null);
|
||||
- ((TextView) view.findViewById(R.id.warning)).setText(
|
||||
- Html.fromHtml(getString(R.string.warning, getVpnLabel()),
|
||||
- this, null /* tagHandler */));
|
||||
+ mView = View.inflate(this, R.layout.confirm, null);
|
||||
+ ((TextView) mView.findViewById(R.id.warning)).setText(
|
||||
+ Html.fromHtml(getString(R.string.warning, getSanitizedVpnLabel(
|
||||
+ getVpnLabel().toString(), mPackage)),
|
||||
+ this /* imageGetter */, null /* tagHandler */));
|
||||
mAlertParams.mTitle = getText(R.string.prompt);
|
||||
mAlertParams.mPositiveButtonText = getText(android.R.string.ok);
|
||||
mAlertParams.mPositiveButtonListener = this;
|
||||
mAlertParams.mNegativeButtonText = getText(android.R.string.cancel);
|
||||
- mAlertParams.mView = view;
|
||||
+ mAlertParams.mView = mView;
|
||||
setupAlert();
|
||||
|
||||
getWindow().setCloseOnTouchOutside(false);
|
84
Patches/LineageOS-16.0/android_frameworks_base/361255.patch
Normal file
84
Patches/LineageOS-16.0/android_frameworks_base/361255.patch
Normal file
|
@ -0,0 +1,84 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Groover <mpgroover@google.com>
|
||||
Date: Fri, 31 Mar 2023 21:31:22 +0000
|
||||
Subject: [PATCH] Limit the number of supported v1 and v2 signers
|
||||
|
||||
The v1 and v2 APK Signature Schemes support multiple signers; this
|
||||
was intended to allow multiple entities to sign an APK. Previously,
|
||||
the platform had no limits placed on the number of signers supported
|
||||
in an APK, but this commit sets a hard limit of 10 supported signers
|
||||
for these signature schemes to ensure a large number of signers
|
||||
does not place undue burden on the platform.
|
||||
|
||||
Bug: 266580022
|
||||
Test: Manually verified the platform only allowed an APK with the
|
||||
maximum number of supported signers.
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:6f6ee8a55f37c2b8c0df041b2bd53ec928764597)
|
||||
Merged-In: I6aa86b615b203cdc69d58a593ccf8f18474ca091
|
||||
Change-Id: I6aa86b615b203cdc69d58a593ccf8f18474ca091
|
||||
---
|
||||
.../util/apk/ApkSignatureSchemeV2Verifier.java | 10 ++++++++++
|
||||
core/java/android/util/jar/StrictJarVerifier.java | 11 +++++++++++
|
||||
2 files changed, 21 insertions(+)
|
||||
|
||||
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
|
||||
index 533d72590f0a..d5f6ebe8c2e9 100644
|
||||
--- a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
|
||||
+++ b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
|
||||
@@ -83,6 +83,11 @@ public class ApkSignatureSchemeV2Verifier {
|
||||
|
||||
private static final int APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a;
|
||||
|
||||
+ /**
|
||||
+ * The maximum number of signers supported by the v2 APK signature scheme.
|
||||
+ */
|
||||
+ private static final int MAX_V2_SIGNERS = 10;
|
||||
+
|
||||
/**
|
||||
* Returns {@code true} if the provided APK contains an APK Signature Scheme V2 signature.
|
||||
*
|
||||
@@ -188,6 +193,11 @@ public class ApkSignatureSchemeV2Verifier {
|
||||
}
|
||||
while (signers.hasRemaining()) {
|
||||
signerCount++;
|
||||
+ if (signerCount > MAX_V2_SIGNERS) {
|
||||
+ throw new SecurityException(
|
||||
+ "APK Signature Scheme v2 only supports a maximum of " + MAX_V2_SIGNERS
|
||||
+ + " signers");
|
||||
+ }
|
||||
try {
|
||||
ByteBuffer signer = getLengthPrefixedSlice(signers);
|
||||
X509Certificate[] certs = verifySigner(signer, contentDigests, certFactory);
|
||||
diff --git a/core/java/android/util/jar/StrictJarVerifier.java b/core/java/android/util/jar/StrictJarVerifier.java
|
||||
index 45254908c5c9..a6aca330d323 100644
|
||||
--- a/core/java/android/util/jar/StrictJarVerifier.java
|
||||
+++ b/core/java/android/util/jar/StrictJarVerifier.java
|
||||
@@ -78,6 +78,11 @@ class StrictJarVerifier {
|
||||
"SHA1",
|
||||
};
|
||||
|
||||
+ /**
|
||||
+ * The maximum number of signers supported by the JAR signature scheme.
|
||||
+ */
|
||||
+ private static final int MAX_JAR_SIGNERS = 10;
|
||||
+
|
||||
private final String jarName;
|
||||
private final StrictJarManifest manifest;
|
||||
private final HashMap<String, byte[]> metaEntries;
|
||||
@@ -293,10 +298,16 @@ class StrictJarVerifier {
|
||||
return false;
|
||||
}
|
||||
|
||||
+ int signerCount = 0;
|
||||
Iterator<String> it = metaEntries.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
String key = it.next();
|
||||
if (key.endsWith(".DSA") || key.endsWith(".RSA") || key.endsWith(".EC")) {
|
||||
+ if (++signerCount > MAX_JAR_SIGNERS) {
|
||||
+ throw new SecurityException(
|
||||
+ "APK Signature Scheme v1 only supports a maximum of " + MAX_JAR_SIGNERS
|
||||
+ + " signers");
|
||||
+ }
|
||||
verifyCertificate(key);
|
||||
it.remove();
|
||||
}
|
1034
Patches/LineageOS-16.0/android_frameworks_base/361256.patch
Normal file
1034
Patches/LineageOS-16.0/android_frameworks_base/361256.patch
Normal file
File diff suppressed because it is too large
Load diff
39
Patches/LineageOS-16.0/android_frameworks_base/361257.patch
Normal file
39
Patches/LineageOS-16.0/android_frameworks_base/361257.patch
Normal file
|
@ -0,0 +1,39 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aaron Liu <aaronjli@google.com>
|
||||
Date: Tue, 28 Mar 2023 13:15:04 -0700
|
||||
Subject: [PATCH] DO NOT MERGE Dismiss keyguard when simpin auth'd and...
|
||||
|
||||
security method is none. This is mostly to fix the case where we auth
|
||||
sim pin in the set up wizard and it goes straight to keyguard instead of
|
||||
the setup wizard activity.
|
||||
|
||||
This works with the prevent bypass keyguard flag because the device
|
||||
should be noe secure in this case.
|
||||
|
||||
Fixes: 222446076
|
||||
Test: turn locked sim on, which opens the sim pin screen. Auth the
|
||||
screen and observe that keyguard is not shown.
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:48fa9bef3451e4a358c941af5b230f99881c5cb6)
|
||||
Cherry-picking this CL as a security fix
|
||||
|
||||
Bug: 222446076
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:09f004722284ef6b9790ddf9338a1708b3f0833c)
|
||||
Merged-In: If4360dd6ae2e5f79b43eaf1a29687ac9cc4b6101
|
||||
Change-Id: If4360dd6ae2e5f79b43eaf1a29687ac9cc4b6101
|
||||
---
|
||||
.../src/com/android/keyguard/KeyguardSecurityContainer.java | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
|
||||
index 6a71cf84759c..bb205956e932 100644
|
||||
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
|
||||
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
|
||||
@@ -351,7 +351,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
|
||||
case SimPuk:
|
||||
// Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
|
||||
SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId);
|
||||
- if (securityMode == SecurityMode.None && mLockPatternUtils.isLockScreenDisabled(
|
||||
+ if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled(
|
||||
KeyguardUpdateMonitor.getCurrentUser())) {
|
||||
finish = true;
|
||||
} else {
|
100
Patches/LineageOS-16.0/android_frameworks_base/361258.patch
Normal file
100
Patches/LineageOS-16.0/android_frameworks_base/361258.patch
Normal file
|
@ -0,0 +1,100 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Andr=C3=A1s=20Kurucz?= <kurucz@google.com>
|
||||
Date: Fri, 21 Apr 2023 09:45:07 +0000
|
||||
Subject: [PATCH] Truncate ShortcutInfo Id
|
||||
|
||||
Creating Conversation with a ShortcutId longer than 65_535 (max unsigned short), we did not save the conversation settings into the notification_policy.xml due to a restriction in FastDataOutput.
|
||||
This put us to a state where the user changing the importance or turning off the notifications for the given conversation had no effect on notification behavior.
|
||||
|
||||
Fixes: 273729476
|
||||
Test: atest ShortcutManagerTest2
|
||||
Test: Create a test app which creates a Conversation with a long shortcutId. Go to the Conversation Settings and turn off Notifications. Post a new Notification to this Conversation and see if it is displayed.
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f31df6234091b5b1de258a01dd4b2d8e5415ee2e)
|
||||
Merged-In: I2617de6f9e8a7dbfd8fbeff589a7d592f00d87c5
|
||||
|
||||
Change-Id: I2617de6f9e8a7dbfd8fbeff589a7d592f00d87c5
|
||||
---
|
||||
.../java/android/content/pm/ShortcutInfo.java | 20 ++++++++++++++++---
|
||||
.../server/pm/ShortcutManagerTest2.java | 10 ++++++++++
|
||||
2 files changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
|
||||
index ea476b0abf33..cddad1798219 100644
|
||||
--- a/core/java/android/content/pm/ShortcutInfo.java
|
||||
+++ b/core/java/android/content/pm/ShortcutInfo.java
|
||||
@@ -214,6 +214,12 @@ public final class ShortcutInfo implements Parcelable {
|
||||
*/
|
||||
public static final int DISABLED_REASON_OTHER_RESTORE_ISSUE = 103;
|
||||
|
||||
+ /**
|
||||
+ * The maximum length of Shortcut ID. IDs will be truncated at this limit.
|
||||
+ * @hide
|
||||
+ */
|
||||
+ public static final int MAX_ID_LENGTH = 1000;
|
||||
+
|
||||
/** @hide */
|
||||
@IntDef(prefix = { "DISABLED_REASON_" }, value = {
|
||||
DISABLED_REASON_NOT_DISABLED,
|
||||
@@ -380,8 +386,7 @@ public final class ShortcutInfo implements Parcelable {
|
||||
|
||||
private ShortcutInfo(Builder b) {
|
||||
mUserId = b.mContext.getUserId();
|
||||
-
|
||||
- mId = Preconditions.checkStringNotEmpty(b.mId, "Shortcut ID must be provided");
|
||||
+ mId = getSafeId(Preconditions.checkStringNotEmpty(b.mId, "Shortcut ID must be provided"));
|
||||
|
||||
// Note we can't do other null checks here because SM.updateShortcuts() takes partial
|
||||
// information.
|
||||
@@ -463,6 +468,14 @@ public final class ShortcutInfo implements Parcelable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ @NonNull
|
||||
+ private static String getSafeId(@NonNull String id) {
|
||||
+ if (id.length() > MAX_ID_LENGTH) {
|
||||
+ return id.substring(0, MAX_ID_LENGTH);
|
||||
+ }
|
||||
+ return id;
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Throws if any of the mandatory fields is not set.
|
||||
*
|
||||
@@ -1851,7 +1864,8 @@ public final class ShortcutInfo implements Parcelable {
|
||||
final ClassLoader cl = getClass().getClassLoader();
|
||||
|
||||
mUserId = source.readInt();
|
||||
- mId = source.readString();
|
||||
+ mId = getSafeId(Preconditions.checkStringNotEmpty(source.readString(),
|
||||
+ "Shortcut ID must be provided"));
|
||||
mPackageName = source.readString();
|
||||
mActivity = source.readParcelable(cl);
|
||||
mFlags = source.readInt();
|
||||
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
|
||||
index fcdadaccd2ac..464f563640c1 100644
|
||||
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
|
||||
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
|
||||
@@ -53,6 +53,7 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
+import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
@@ -223,6 +224,15 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
|
||||
});
|
||||
}
|
||||
|
||||
+ public void testShortcutIdTruncated() {
|
||||
+ ShortcutInfo si = new ShortcutInfo.Builder(getTestContext(),
|
||||
+ String.join("", Collections.nCopies(Short.MAX_VALUE, "s"))).build();
|
||||
+
|
||||
+ assertTrue(
|
||||
+ "id must be truncated to MAX_ID_LENGTH",
|
||||
+ si.getId().length() <= ShortcutInfo.MAX_ID_LENGTH);
|
||||
+ }
|
||||
+
|
||||
public void testShortcutInfoParcel() {
|
||||
setCaller(CALLING_PACKAGE_1, USER_10);
|
||||
ShortcutInfo si = parceled(new ShortcutInfo.Builder(mClientContext)
|
128
Patches/LineageOS-16.0/android_frameworks_base/361259.patch
Normal file
128
Patches/LineageOS-16.0/android_frameworks_base/361259.patch
Normal file
|
@ -0,0 +1,128 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ioana Alexandru <aioana@google.com>
|
||||
Date: Thu, 27 Apr 2023 12:36:05 +0000
|
||||
Subject: [PATCH] Visit URIs in landscape/portrait custom remote views.
|
||||
|
||||
Bug: 277740848
|
||||
Test: atest RemoteViewsTest NotificationManagerServiceTest & tested with POC from bug
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e8acb2f660bdb03616989852f9dbbf1726f8237e)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:43e1ae4e0d408604b9e3c18ac0e9bf87529b92a8)
|
||||
Merged-In: I7d3d35df0ec38945019f71755bed8797b7af4517
|
||||
Change-Id: I7d3d35df0ec38945019f71755bed8797b7af4517
|
||||
---
|
||||
core/java/android/widget/RemoteViews.java | 6 ++
|
||||
.../src/android/widget/RemoteViewsTest.java | 65 +++++++++++++++++++
|
||||
2 files changed, 71 insertions(+)
|
||||
|
||||
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
|
||||
index 4865dab6056a..10053dddb0fb 100644
|
||||
--- a/core/java/android/widget/RemoteViews.java
|
||||
+++ b/core/java/android/widget/RemoteViews.java
|
||||
@@ -543,6 +543,12 @@ public class RemoteViews implements Parcelable, Filter {
|
||||
mActions.get(i).visitUris(visitor);
|
||||
}
|
||||
}
|
||||
+ if (mLandscape != null) {
|
||||
+ mLandscape.visitUris(visitor);
|
||||
+ }
|
||||
+ if (mPortrait != null) {
|
||||
+ mPortrait.visitUris(visitor);
|
||||
+ }
|
||||
}
|
||||
|
||||
private static void visitIconUri(Icon icon, @NonNull Consumer<Uri> visitor) {
|
||||
diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
|
||||
index 70cf097f42a3..7d2e07ecbd71 100644
|
||||
--- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java
|
||||
+++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
|
||||
@@ -19,6 +19,10 @@ package android.widget;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
+import static org.mockito.ArgumentMatchers.eq;
|
||||
+import static org.mockito.Mockito.spy;
|
||||
+import static org.mockito.Mockito.times;
|
||||
+import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
@@ -26,6 +30,8 @@ import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
+import android.graphics.drawable.Icon;
|
||||
+import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Binder;
|
||||
import android.os.Parcel;
|
||||
@@ -46,6 +52,7 @@ import org.junit.runner.RunWith;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
+import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Tests for RemoteViews.
|
||||
@@ -444,4 +451,62 @@ public class RemoteViewsTest {
|
||||
}
|
||||
return found[0];
|
||||
}
|
||||
+
|
||||
+
|
||||
+ @Test
|
||||
+ public void visitUris() {
|
||||
+ RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test);
|
||||
+
|
||||
+ final Uri imageUri = Uri.parse("content://media/image");
|
||||
+ final Icon icon1 = Icon.createWithContentUri("content://media/icon1");
|
||||
+ final Icon icon2 = Icon.createWithContentUri("content://media/icon2");
|
||||
+ final Icon icon3 = Icon.createWithContentUri("content://media/icon3");
|
||||
+ final Icon icon4 = Icon.createWithContentUri("content://media/icon4");
|
||||
+ views.setImageViewUri(R.id.image, imageUri);
|
||||
+ views.setTextViewCompoundDrawables(R.id.text, icon1, icon2, icon3, icon4);
|
||||
+
|
||||
+ Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
|
||||
+ views.visitUris(visitor);
|
||||
+ verify(visitor, times(1)).accept(eq(imageUri));
|
||||
+ verify(visitor, times(1)).accept(eq(icon1.getUri()));
|
||||
+ verify(visitor, times(1)).accept(eq(icon2.getUri()));
|
||||
+ verify(visitor, times(1)).accept(eq(icon3.getUri()));
|
||||
+ verify(visitor, times(1)).accept(eq(icon4.getUri()));
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void visitUris_separateOrientation() {
|
||||
+ final RemoteViews landscape = new RemoteViews(mPackage, R.layout.remote_views_test);
|
||||
+ final Uri imageUriL = Uri.parse("content://landscape/image");
|
||||
+ final Icon icon1L = Icon.createWithContentUri("content://landscape/icon1");
|
||||
+ final Icon icon2L = Icon.createWithContentUri("content://landscape/icon2");
|
||||
+ final Icon icon3L = Icon.createWithContentUri("content://landscape/icon3");
|
||||
+ final Icon icon4L = Icon.createWithContentUri("content://landscape/icon4");
|
||||
+ landscape.setImageViewUri(R.id.image, imageUriL);
|
||||
+ landscape.setTextViewCompoundDrawables(R.id.text, icon1L, icon2L, icon3L, icon4L);
|
||||
+
|
||||
+ final RemoteViews portrait = new RemoteViews(mPackage, 33);
|
||||
+ final Uri imageUriP = Uri.parse("content://portrait/image");
|
||||
+ final Icon icon1P = Icon.createWithContentUri("content://portrait/icon1");
|
||||
+ final Icon icon2P = Icon.createWithContentUri("content://portrait/icon2");
|
||||
+ final Icon icon3P = Icon.createWithContentUri("content://portrait/icon3");
|
||||
+ final Icon icon4P = Icon.createWithContentUri("content://portrait/icon4");
|
||||
+ portrait.setImageViewUri(R.id.image, imageUriP);
|
||||
+ portrait.setTextViewCompoundDrawables(R.id.text, icon1P, icon2P, icon3P, icon4P);
|
||||
+
|
||||
+ RemoteViews views = new RemoteViews(landscape, portrait);
|
||||
+
|
||||
+ Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
|
||||
+ views.visitUris(visitor);
|
||||
+ verify(visitor, times(1)).accept(eq(imageUriL));
|
||||
+ verify(visitor, times(1)).accept(eq(icon1L.getUri()));
|
||||
+ verify(visitor, times(1)).accept(eq(icon2L.getUri()));
|
||||
+ verify(visitor, times(1)).accept(eq(icon3L.getUri()));
|
||||
+ verify(visitor, times(1)).accept(eq(icon4L.getUri()));
|
||||
+ verify(visitor, times(1)).accept(eq(imageUriP));
|
||||
+ verify(visitor, times(1)).accept(eq(icon1P.getUri()));
|
||||
+ verify(visitor, times(1)).accept(eq(icon2P.getUri()));
|
||||
+ verify(visitor, times(1)).accept(eq(icon3P.getUri()));
|
||||
+ verify(visitor, times(1)).accept(eq(icon4P.getUri()));
|
||||
+ }
|
||||
}
|
109
Patches/LineageOS-16.0/android_frameworks_base/364607.patch
Normal file
109
Patches/LineageOS-16.0/android_frameworks_base/364607.patch
Normal file
|
@ -0,0 +1,109 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jing Ji <jji@google.com>
|
||||
Date: Tue, 25 Oct 2022 22:39:52 -0700
|
||||
Subject: [PATCH] DO NOT MERGE: ActivityManager#killBackgroundProcesses can
|
||||
kill caller's own app only
|
||||
|
||||
unless it's a system app.
|
||||
|
||||
Bug: 239423414
|
||||
Bug: 223376078
|
||||
Test: atest CtsAppTestCases:ActivityManagerTest
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8b382775b258220466a977453905797521e159de)
|
||||
Merged-In: Iac6baa889965b8ffecd9a43179a4c96632ad1d02
|
||||
Change-Id: Iac6baa889965b8ffecd9a43179a4c96632ad1d02
|
||||
---
|
||||
core/java/android/app/ActivityManager.java | 3 ++
|
||||
core/res/AndroidManifest.xml | 6 +++-
|
||||
.../server/am/ActivityManagerService.java | 32 +++++++++++++++++--
|
||||
3 files changed, 38 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
|
||||
index 83630f4c3693..51411c9e208e 100644
|
||||
--- a/core/java/android/app/ActivityManager.java
|
||||
+++ b/core/java/android/app/ActivityManager.java
|
||||
@@ -3615,6 +3615,9 @@ public class ActivityManager {
|
||||
* processes to reclaim memory; the system will take care of restarting
|
||||
* these processes in the future as needed.
|
||||
*
|
||||
+ * <p class="note">Third party applications can only use this API to kill their own processes.
|
||||
+ * </p>
|
||||
+ *
|
||||
* @param packageName The name of the package whose processes are to
|
||||
* be killed.
|
||||
*/
|
||||
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
|
||||
index 0aafab66dabd..d23501a86b79 100644
|
||||
--- a/core/res/AndroidManifest.xml
|
||||
+++ b/core/res/AndroidManifest.xml
|
||||
@@ -2092,7 +2092,11 @@
|
||||
android:protectionLevel="normal" />
|
||||
|
||||
<!-- Allows an application to call
|
||||
- {@link android.app.ActivityManager#killBackgroundProcesses}.
|
||||
+ {@link android.app.ActivityManager#killBackgroundProcesses}.
|
||||
+
|
||||
+ <p class="note">Third party applications can only use this API to kill their own
|
||||
+ processes.</p>
|
||||
+
|
||||
<p>Protection level: normal
|
||||
-->
|
||||
<permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"
|
||||
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
|
||||
index f522b20f7ccd..44761a523abb 100644
|
||||
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
|
||||
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
|
||||
@@ -6810,8 +6810,20 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
Slog.w(TAG, msg);
|
||||
throw new SecurityException(msg);
|
||||
}
|
||||
+ final int callingUid = Binder.getCallingUid();
|
||||
+ final int callingPid = Binder.getCallingPid();
|
||||
+ final int callingAppId = UserHandle.getAppId(callingUid);
|
||||
|
||||
- userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
|
||||
+ ProcessRecord proc;
|
||||
+ synchronized (mPidsSelfLocked) {
|
||||
+ proc = mPidsSelfLocked.get(callingPid);
|
||||
+ }
|
||||
+ final boolean hasKillAllPermission = PERMISSION_GRANTED == checkPermission(
|
||||
+ android.Manifest.permission.FORCE_STOP_PACKAGES, callingPid, callingUid)
|
||||
+ || UserHandle.isCore(callingUid)
|
||||
+ || (proc != null && proc.info.isSystemApp());
|
||||
+
|
||||
+ userId = mUserController.handleIncomingUser(callingPid, callingUid,
|
||||
userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
|
||||
final int[] userIds = mUserController.expandUserId(userId);
|
||||
|
||||
@@ -6826,7 +6838,7 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
targetUserId));
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
- if (appId == -1) {
|
||||
+ if (appId == -1 || (!hasKillAllPermission && appId != callingAppId)) {
|
||||
Slog.w(TAG, "Invalid packageName: " + packageName);
|
||||
return;
|
||||
}
|
||||
@@ -6851,6 +6863,22 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
throw new SecurityException(msg);
|
||||
}
|
||||
|
||||
+ final int callingUid = Binder.getCallingUid();
|
||||
+ final int callingPid = Binder.getCallingPid();
|
||||
+
|
||||
+ ProcessRecord proc;
|
||||
+ synchronized (mPidsSelfLocked) {
|
||||
+ proc = mPidsSelfLocked.get(callingPid);
|
||||
+ }
|
||||
+ if (callingUid >= FIRST_APPLICATION_UID
|
||||
+ && (proc == null || !proc.info.isSystemApp())) {
|
||||
+ final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
|
||||
+ + callingPid + ", uid=" + callingUid + " is not allowed";
|
||||
+ Slog.w(TAG, msg);
|
||||
+ // Silently return to avoid existing apps from crashing.
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
final long callingId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (this) {
|
60
Patches/LineageOS-16.0/android_frameworks_base/364608.patch
Normal file
60
Patches/LineageOS-16.0/android_frameworks_base/364608.patch
Normal file
|
@ -0,0 +1,60 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ioana Alexandru <aioana@google.com>
|
||||
Date: Thu, 27 Apr 2023 14:55:28 +0000
|
||||
Subject: [PATCH] Verify URI permissions for notification shortcutIcon.
|
||||
|
||||
Bug: 277593270
|
||||
Test: atest NotificationManagerServiceTest
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:47e661cbf37e1dedf676f482ac07ffc433c92d0b)
|
||||
Merged-In: I1efaa1301bca36895ad4322a919d7421156a60df
|
||||
Change-Id: I1efaa1301bca36895ad4322a919d7421156a60df
|
||||
---
|
||||
core/java/android/app/Notification.java | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
|
||||
index 21bc17172b1f..d8e7d0199615 100644
|
||||
--- a/core/java/android/app/Notification.java
|
||||
+++ b/core/java/android/app/Notification.java
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.app;
|
||||
|
||||
import static com.android.internal.util.NotificationColorUtil.satisfiesTextContrast;
|
||||
+import static android.graphics.drawable.Icon.TYPE_URI;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.annotation.DrawableRes;
|
||||
@@ -2329,6 +2330,14 @@ public class Notification implements Parcelable
|
||||
}
|
||||
}
|
||||
|
||||
+ private static void visitIconUri(@NonNull Consumer<Uri> visitor, @Nullable Icon icon) {
|
||||
+ if (icon == null) return;
|
||||
+ final int iconType = icon.getType();
|
||||
+ if (iconType == TYPE_URI /*|| iconType == TYPE_URI_ADAPTIVE_BITMAP*/) {
|
||||
+ visitor.accept(icon.getUri());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Note all {@link Uri} that are referenced internally, with the expectation
|
||||
* that Uri permission grants will need to be issued to ensure the recipient
|
||||
@@ -2344,7 +2353,18 @@ public class Notification implements Parcelable
|
||||
if (bigContentView != null) bigContentView.visitUris(visitor);
|
||||
if (headsUpContentView != null) headsUpContentView.visitUris(visitor);
|
||||
|
||||
+ visitIconUri(visitor, mSmallIcon);
|
||||
+ visitIconUri(visitor, mLargeIcon);
|
||||
+
|
||||
+ if (actions != null) {
|
||||
+ for (Action action : actions) {
|
||||
+ visitIconUri(visitor, action.getIcon());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (extras != null) {
|
||||
+ visitIconUri(visitor, extras.getParcelable(EXTRA_LARGE_ICON_BIG));
|
||||
+
|
||||
visitor.accept(extras.getParcelable(EXTRA_AUDIO_CONTENTS_URI));
|
||||
visitor.accept(extras.getParcelable(EXTRA_BACKGROUND_IMAGE_URI));
|
||||
}
|
51
Patches/LineageOS-16.0/android_frameworks_base/364609.patch
Normal file
51
Patches/LineageOS-16.0/android_frameworks_base/364609.patch
Normal file
|
@ -0,0 +1,51 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Beverly <beverlyt@google.com>
|
||||
Date: Mon, 8 May 2023 16:33:12 +0000
|
||||
Subject: [PATCH] On device lockdown, always show the keyguard
|
||||
|
||||
Manual test steps:
|
||||
1. Enable app pinning and disable "Ask for PIN before unpinning" setting
|
||||
2. Pin an app (ie: Settings)
|
||||
3. Lockdown from the power menu
|
||||
Observe: user is brought to the keyguard, primary auth is required
|
||||
to enter the device. After entering credential, the device is still in
|
||||
app pinning mode.
|
||||
|
||||
Test: atest KeyguardViewMediatorTest
|
||||
Test: manual steps outlined above
|
||||
Bug: 218495634
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:b23c2d5fb6630ea0da503b937f62880594b13e94)
|
||||
Merged-In: I9a7c5e1acadabd4484e58573331f98dba895f2a2
|
||||
Change-Id: I9a7c5e1acadabd4484e58573331f98dba895f2a2
|
||||
---
|
||||
.../systemui/keyguard/KeyguardViewMediator.java | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
|
||||
index bac481c8e478..f0d389c15228 100644
|
||||
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
|
||||
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
|
||||
@@ -586,6 +586,13 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
notifyHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public void onStrongAuthStateChanged(int userId) {
|
||||
+ if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
|
||||
+ doKeyguardLocked(null);
|
||||
+ }
|
||||
+ }
|
||||
};
|
||||
|
||||
ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
|
||||
@@ -1341,7 +1348,8 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
}
|
||||
|
||||
// if another app is disabling us, don't show
|
||||
- if (!mExternallyEnabled) {
|
||||
+ if (!mExternallyEnabled
|
||||
+ && !mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
|
||||
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
|
||||
|
||||
// note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
|
242
Patches/LineageOS-16.0/android_frameworks_base/364610.patch
Normal file
242
Patches/LineageOS-16.0/android_frameworks_base/364610.patch
Normal file
|
@ -0,0 +1,242 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Grafov <pgrafov@google.com>
|
||||
Date: Wed, 5 Apr 2023 15:15:41 +0000
|
||||
Subject: [PATCH] Ensure policy has no absurdly long strings
|
||||
|
||||
The following APIs now enforce limits and throw IllegalArgumentException
|
||||
when limits are violated:
|
||||
* DPM.setTrustAgentConfiguration() limits agent packgage name,
|
||||
component name, and strings within configuration bundle.
|
||||
* DPM.setPermittedAccessibilityServices() limits package names.
|
||||
* DPM.setPermittedInputMethods() limits package names.
|
||||
* DPM.setAccountManagementDisabled() limits account name.
|
||||
* DPM.setLockTaskPackages() limits package names.
|
||||
* DPM.setAffiliationIds() limits id.
|
||||
* DPM.transferOwnership() limits strings inside the bundle.
|
||||
|
||||
Package names are limited at 223, because they become directory names
|
||||
and it is a filesystem restriction, see FrameworkParsingPackageUtils.
|
||||
|
||||
All other strings are limited at 65535, because longer ones break binary
|
||||
XML serializer.
|
||||
|
||||
The following APIs silently truncate strings that are long beyond reason:
|
||||
* DPM.setShortSupportMessage() truncates message at 200.
|
||||
* DPM.setLongSupportMessage() truncates message at 20000.
|
||||
* DPM.setOrganizationName() truncates org name at 200.
|
||||
|
||||
Bug: 260729089
|
||||
Test: atest com.android.server.devicepolicy
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:bb7e82ceaa6d16267e7b0e14563161b506d26be8)
|
||||
Merged-In: Idcf54e408722f164d16bf2f24a00cd1f5b626d23
|
||||
Change-Id: Idcf54e408722f164d16bf2f24a00cd1f5b626d23
|
||||
---
|
||||
.../app/admin/DevicePolicyManager.java | 3 +-
|
||||
.../DevicePolicyManagerService.java | 91 ++++++++++++++++++-
|
||||
2 files changed, 90 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
|
||||
index 485ce78c3320..28b7ccb7b946 100644
|
||||
--- a/core/java/android/app/admin/DevicePolicyManager.java
|
||||
+++ b/core/java/android/app/admin/DevicePolicyManager.java
|
||||
@@ -8100,7 +8100,8 @@ public class DevicePolicyManager {
|
||||
|
||||
/**
|
||||
* Called by a device admin to set the long support message. This will be displayed to the user
|
||||
- * in the device administators settings screen.
|
||||
+ * in the device administrators settings screen. If the message is longer than 20000 characters
|
||||
+ * it may be truncated.
|
||||
* <p>
|
||||
* If the long support message needs to be localized, it is the responsibility of the
|
||||
* {@link DeviceAdminReceiver} to listen to the {@link Intent#ACTION_LOCALE_CHANGED} broadcast
|
||||
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
|
||||
index d7539e11bea9..2fd54b4981af 100644
|
||||
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
|
||||
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
|
||||
@@ -250,6 +250,7 @@ import java.lang.reflect.Constructor;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DateFormat;
|
||||
import java.time.LocalDate;
|
||||
+import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -260,6 +261,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
+import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -325,6 +327,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
|
||||
private static final int REQUEST_EXPIRE_PASSWORD = 5571;
|
||||
|
||||
+ // Binary XML serializer doesn't support longer strings
|
||||
+ private static final int MAX_POLICY_STRING_LENGTH = 65535;
|
||||
+ // FrameworkParsingPackageUtils#MAX_FILE_NAME_SIZE, Android packages are used in dir names.
|
||||
+ private static final int MAX_PACKAGE_NAME_LENGTH = 223;
|
||||
+
|
||||
+ private static final int MAX_LONG_SUPPORT_MESSAGE_LENGTH = 20000;
|
||||
+ private static final int MAX_SHORT_SUPPORT_MESSAGE_LENGTH = 200;
|
||||
+ private static final int MAX_ORG_NAME_LENGTH = 200;
|
||||
+
|
||||
private static final long MS_PER_DAY = TimeUnit.DAYS.toMillis(1);
|
||||
|
||||
private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * MS_PER_DAY; // 5 days, in ms
|
||||
@@ -8284,6 +8295,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
}
|
||||
Preconditions.checkNotNull(admin, "admin is null");
|
||||
Preconditions.checkNotNull(agent, "agent is null");
|
||||
+ enforceMaxPackageNameLength(agent.getPackageName());
|
||||
+ final String agentAsString = agent.flattenToString();
|
||||
+ enforceMaxStringLength(agentAsString, "agent name");
|
||||
+ if (args != null) {
|
||||
+ enforceMaxStringLength(args, "args");
|
||||
+ }
|
||||
final int userHandle = UserHandle.getCallingUserId();
|
||||
synchronized (getLockObject()) {
|
||||
ActiveAdmin ap = getActiveAdminForCallerLocked(admin,
|
||||
@@ -8486,6 +8503,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
Preconditions.checkNotNull(who, "ComponentName is null");
|
||||
|
||||
if (packageList != null) {
|
||||
+ for (String pkg : (List<String>) packageList) {
|
||||
+ enforceMaxPackageNameLength(pkg);
|
||||
+ }
|
||||
+
|
||||
int userId = UserHandle.getCallingUserId();
|
||||
List<AccessibilityServiceInfo> enabledServices = null;
|
||||
long id = mInjector.binderClearCallingIdentity();
|
||||
@@ -8668,6 +8689,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
|
||||
final int callingUserId = mInjector.userHandleGetCallingUserId();
|
||||
if (packageList != null) {
|
||||
+ for (String pkg : (List<String>) packageList) {
|
||||
+ enforceMaxPackageNameLength(pkg);
|
||||
+ }
|
||||
+
|
||||
// InputMethodManager fetches input methods for current user.
|
||||
// So this can only be set when calling user is the current user
|
||||
// or parent is current user in case of managed profiles.
|
||||
@@ -9608,6 +9633,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
return;
|
||||
}
|
||||
Preconditions.checkNotNull(who, "ComponentName is null");
|
||||
+ enforceMaxStringLength(accountType, "account type");
|
||||
synchronized (getLockObject()) {
|
||||
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
|
||||
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
|
||||
@@ -9871,6 +9897,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
throws SecurityException {
|
||||
Preconditions.checkNotNull(who, "ComponentName is null");
|
||||
Preconditions.checkNotNull(packages, "packages is null");
|
||||
+ for (String pkg : packages) {
|
||||
+ enforceMaxPackageNameLength(pkg);
|
||||
+ }
|
||||
|
||||
synchronized (getLockObject()) {
|
||||
enforceCanCallLockTaskLocked(who);
|
||||
@@ -11249,6 +11278,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
if (!mHasFeature) {
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ message = truncateIfLonger(message, MAX_LONG_SUPPORT_MESSAGE_LENGTH);
|
||||
+
|
||||
Preconditions.checkNotNull(who, "ComponentName is null");
|
||||
final int userHandle = mInjector.userHandleGetCallingUserId();
|
||||
synchronized (getLockObject()) {
|
||||
@@ -11280,6 +11312,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
return;
|
||||
}
|
||||
Preconditions.checkNotNull(who, "ComponentName is null");
|
||||
+ message = truncateIfLonger(message, MAX_SHORT_SUPPORT_MESSAGE_LENGTH);
|
||||
+
|
||||
final int userHandle = mInjector.userHandleGetCallingUserId();
|
||||
synchronized (getLockObject()) {
|
||||
ActiveAdmin admin = getActiveAdminForUidLocked(who,
|
||||
@@ -11408,6 +11442,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
Preconditions.checkNotNull(who, "ComponentName is null");
|
||||
final int userHandle = mInjector.userHandleGetCallingUserId();
|
||||
|
||||
+ text = truncateIfLonger(text, MAX_ORG_NAME_LENGTH);
|
||||
+
|
||||
synchronized (getLockObject()) {
|
||||
ActiveAdmin admin = getActiveAdminForCallerLocked(who,
|
||||
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
|
||||
@@ -11572,9 +11608,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
throw new IllegalArgumentException("ids must not be null");
|
||||
}
|
||||
for (String id : ids) {
|
||||
- if (TextUtils.isEmpty(id)) {
|
||||
- throw new IllegalArgumentException("ids must not contain empty string");
|
||||
- }
|
||||
+ Preconditions.checkArgument(!TextUtils.isEmpty(id), "ids must not have empty string");
|
||||
+ enforceMaxStringLength(id, "affiliation id");
|
||||
}
|
||||
|
||||
final Set<String> affiliationIds = new ArraySet<>(ids);
|
||||
@@ -12740,6 +12775,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
|
||||
Preconditions.checkNotNull(admin, "Admin cannot be null.");
|
||||
Preconditions.checkNotNull(target, "Target cannot be null.");
|
||||
+ if (bundle != null) {
|
||||
+ enforceMaxStringLength(bundle, "bundle");
|
||||
+ }
|
||||
|
||||
enforceProfileOrDeviceOwner(admin);
|
||||
|
||||
@@ -13194,4 +13232,51 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
private static String getManagedProvisioningPackage(Context context) {
|
||||
return context.getResources().getString(R.string.config_managed_provisioning_package);
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Truncates char sequence to maximum length, nulls are ignored.
|
||||
+ */
|
||||
+ private static CharSequence truncateIfLonger(CharSequence input, int maxLength) {
|
||||
+ return input == null || input.length() <= maxLength
|
||||
+ ? input
|
||||
+ : input.subSequence(0, maxLength);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Throw if string argument is too long to be serialized.
|
||||
+ */
|
||||
+ private static void enforceMaxStringLength(String str, String argName) {
|
||||
+ Preconditions.checkArgument(
|
||||
+ str.length() <= MAX_POLICY_STRING_LENGTH, argName + " loo long");
|
||||
+ }
|
||||
+
|
||||
+ private static void enforceMaxPackageNameLength(String pkg) {
|
||||
+ Preconditions.checkArgument(
|
||||
+ pkg.length() <= MAX_PACKAGE_NAME_LENGTH, "Package name too long");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Throw if persistable bundle contains any string that we can't serialize.
|
||||
+ */
|
||||
+ private static void enforceMaxStringLength(PersistableBundle bundle, String argName) {
|
||||
+ // Persistable bundles can have other persistable bundles as values, traverse with a queue.
|
||||
+ Queue<PersistableBundle> queue = new ArrayDeque<>();
|
||||
+ queue.add(bundle);
|
||||
+ while (!queue.isEmpty()) {
|
||||
+ PersistableBundle current = queue.remove();
|
||||
+ for (String key : current.keySet()) {
|
||||
+ enforceMaxStringLength(key, "key in " + argName);
|
||||
+ Object value = current.get(key);
|
||||
+ if (value instanceof String) {
|
||||
+ enforceMaxStringLength((String) value, "string value in " + argName);
|
||||
+ } else if (value instanceof String[]) {
|
||||
+ for (String str : (String[]) value) {
|
||||
+ enforceMaxStringLength(str, "string value in " + argName);
|
||||
+ }
|
||||
+ } else if (value instanceof PersistableBundle) {
|
||||
+ queue.add((PersistableBundle) value);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue