linux-trace-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] fix UAF when lookup kallsym after ftrace disabled
@ 2025-05-29 11:19 Ye Bin
  2025-05-29 11:19 ` [PATCH v3 1/2] ftrace: " Ye Bin
  2025-05-29 11:19 ` [PATCH v3 2/2] ftrace: don't allocate ftrace module map if ftrace is disabled Ye Bin
  0 siblings, 2 replies; 6+ messages in thread
From: Ye Bin @ 2025-05-29 11:19 UTC (permalink / raw)
  To: rostedt, mhiramat, mathieu.desnoyers, mark.rutland,
	linux-trace-kernel
  Cc: yebin, yebin10

Diff v3 vs v2:
(1) Only release 'mod_map' resource in ftrace_release_mod() when
    ftrace_disabled.

Diff v2 vs v1:
(1) Add description for PATCH[1/2];
(2) Move judgement from ftrace_free_mem() to allocate_ftrace_mod_map()

Ye Bin (2):
  ftrace: fix UAF when lookup kallsym after ftrace disabled
  ftrace: don't allocate ftrace module map if ftrace is disabled

 kernel/trace/ftrace.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3 1/2] ftrace: fix UAF when lookup kallsym after ftrace disabled
  2025-05-29 11:19 [PATCH v3 0/2] fix UAF when lookup kallsym after ftrace disabled Ye Bin
@ 2025-05-29 11:19 ` Ye Bin
  2025-06-02 15:28   ` Steven Rostedt
  2025-05-29 11:19 ` [PATCH v3 2/2] ftrace: don't allocate ftrace module map if ftrace is disabled Ye Bin
  1 sibling, 1 reply; 6+ messages in thread
From: Ye Bin @ 2025-05-29 11:19 UTC (permalink / raw)
  To: rostedt, mhiramat, mathieu.desnoyers, mark.rutland,
	linux-trace-kernel
  Cc: yebin, yebin10

From: Ye Bin <yebin10@huawei.com>

There's issue as follows:
BUG: unable to handle page fault for address: ffffffffc05d0218
PGD 1bd66f067 P4D 1bd66f067 PUD 1bd671067 PMD 101808067 PTE 0
Oops: Oops: 0000 [#1] SMP KASAN PTI
Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
RIP: 0010:sized_strscpy+0x81/0x2f0
RSP: 0018:ffff88812d76fa08 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffffffffc0601010 RCX: dffffc0000000000
RDX: 0000000000000038 RSI: dffffc0000000000 RDI: ffff88812608da2d
RBP: 8080808080808080 R08: ffff88812608da2d R09: ffff88812608da68
R10: ffff88812608d82d R11: ffff88812608d810 R12: 0000000000000038
R13: ffff88812608da2d R14: ffffffffc05d0218 R15: fefefefefefefeff
FS:  00007fef552de740(0000) GS:ffff8884251c7000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffffffc05d0218 CR3: 00000001146f0000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
 ftrace_mod_get_kallsym+0x1ac/0x590
 update_iter_mod+0x239/0x5b0
 s_next+0x5b/0xa0
 seq_read_iter+0x8c9/0x1070
 seq_read+0x249/0x3b0
 proc_reg_read+0x1b0/0x280
 vfs_read+0x17f/0x920
 ksys_read+0xf3/0x1c0
 do_syscall_64+0x5f/0x2e0
 entry_SYSCALL_64_after_hwframe+0x76/0x7e

Above issue may happens as follow:
(1) Add kprobe trace point;
(2) insmod test.ko;
(3) Trigger ftrace disabled;
(4) rmmod test.ko;
(5) cat /proc/kallsyms; --> Will trigger UAF as test.ko already removed;
ftrace_mod_get_kallsym()
...
strscpy(module_name, mod_map->mod->name, MODULE_NAME_LEN);
...

As ftrace_release_mod() judge 'ftrace_disabled' is true will return,
and 'mod_map' will remaining in ftrace_mod_maps. 'mod_map' has no
chance to release. Therefore, this also causes residual resources to
accumulate. To solve above issue, unconditionally clean up'mod_map'.
Of course, the root cause of this problem is the presence of
ftrace_disabled. The fixes tags patch introduces the possibility of
residual resources in the case of ftrace_disabled. The root cause of
the problem is ftrace_disabled. This patch only adds protection when
ftrace_disabled occurs.

Fixes: aba4b5c22cba ("ftrace: Save module init functions kallsyms symbols for tracing")
Signed-off-by: Ye Bin <yebin10@huawei.com>
---
 kernel/trace/ftrace.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index a3d4dfad0cbc..4f9677141d03 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -7438,9 +7438,10 @@ void ftrace_release_mod(struct module *mod)
 
 	mutex_lock(&ftrace_lock);
 
-	if (ftrace_disabled)
-		goto out_unlock;
-
+	/*
+	 * To avoid the UAF problem after the module is unloaded, the
+	 * 'mod_map' resource needs to be released unconditionally.
+	 */
 	list_for_each_entry_safe(mod_map, n, &ftrace_mod_maps, list) {
 		if (mod_map->mod == mod) {
 			list_del_rcu(&mod_map->list);
@@ -7451,6 +7452,9 @@ void ftrace_release_mod(struct module *mod)
 		}
 	}
 
+	if (ftrace_disabled)
+		goto out_unlock;
+
 	/*
 	 * Each module has its own ftrace_pages, remove
 	 * them from the list.
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 2/2] ftrace: don't allocate ftrace module map if ftrace is disabled
  2025-05-29 11:19 [PATCH v3 0/2] fix UAF when lookup kallsym after ftrace disabled Ye Bin
  2025-05-29 11:19 ` [PATCH v3 1/2] ftrace: " Ye Bin
@ 2025-05-29 11:19 ` Ye Bin
  1 sibling, 0 replies; 6+ messages in thread
From: Ye Bin @ 2025-05-29 11:19 UTC (permalink / raw)
  To: rostedt, mhiramat, mathieu.desnoyers, mark.rutland,
	linux-trace-kernel
  Cc: yebin, yebin10

From: Ye Bin <yebin10@huawei.com>

If the ftrace is disabled, it is meaningless to allocate module map.
So add check in allocate_ftrace_mod_map().

Signed-off-by: Ye Bin <yebin10@huawei.com>
---
 kernel/trace/ftrace.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 4f9677141d03..b3436d86e470 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -7633,6 +7633,9 @@ allocate_ftrace_mod_map(struct module *mod,
 {
 	struct ftrace_mod_map *mod_map;
 
+	if (ftrace_disabled)
+		return NULL;
+
 	mod_map = kmalloc(sizeof(*mod_map), GFP_KERNEL);
 	if (!mod_map)
 		return NULL;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3 1/2] ftrace: fix UAF when lookup kallsym after ftrace disabled
  2025-05-29 11:19 ` [PATCH v3 1/2] ftrace: " Ye Bin
@ 2025-06-02 15:28   ` Steven Rostedt
  2025-06-06  1:52     ` yebin
  0 siblings, 1 reply; 6+ messages in thread
From: Steven Rostedt @ 2025-06-02 15:28 UTC (permalink / raw)
  To: Ye Bin
  Cc: mhiramat, mathieu.desnoyers, mark.rutland, linux-trace-kernel,
	yebin10

On Thu, 29 May 2025 19:19:54 +0800
Ye Bin <yebin@huaweicloud.com> wrote:

> From: Ye Bin <yebin10@huawei.com>
> 
> There's issue as follows:
> BUG: unable to handle page fault for address: ffffffffc05d0218
> PGD 1bd66f067 P4D 1bd66f067 PUD 1bd671067 PMD 101808067 PTE 0
> Oops: Oops: 0000 [#1] SMP KASAN PTI
> Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> RIP: 0010:sized_strscpy+0x81/0x2f0
> RSP: 0018:ffff88812d76fa08 EFLAGS: 00010246
> RAX: 0000000000000000 RBX: ffffffffc0601010 RCX: dffffc0000000000
> RDX: 0000000000000038 RSI: dffffc0000000000 RDI: ffff88812608da2d
> RBP: 8080808080808080 R08: ffff88812608da2d R09: ffff88812608da68
> R10: ffff88812608d82d R11: ffff88812608d810 R12: 0000000000000038
> R13: ffff88812608da2d R14: ffffffffc05d0218 R15: fefefefefefefeff
> FS:  00007fef552de740(0000) GS:ffff8884251c7000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: ffffffffc05d0218 CR3: 00000001146f0000 CR4: 00000000000006f0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> Call Trace:
>  <TASK>
>  ftrace_mod_get_kallsym+0x1ac/0x590
>  update_iter_mod+0x239/0x5b0
>  s_next+0x5b/0xa0
>  seq_read_iter+0x8c9/0x1070
>  seq_read+0x249/0x3b0
>  proc_reg_read+0x1b0/0x280
>  vfs_read+0x17f/0x920
>  ksys_read+0xf3/0x1c0
>  do_syscall_64+0x5f/0x2e0
>  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> 
> Above issue may happens as follow:
> (1) Add kprobe trace point;
> (2) insmod test.ko;
> (3) Trigger ftrace disabled;
> (4) rmmod test.ko;
> (5) cat /proc/kallsyms; --> Will trigger UAF as test.ko already removed;
> ftrace_mod_get_kallsym()
> ...
> strscpy(module_name, mod_map->mod->name, MODULE_NAME_LEN);
> ...
> 
> As ftrace_release_mod() judge 'ftrace_disabled' is true will return,
> and 'mod_map' will remaining in ftrace_mod_maps. 'mod_map' has no
> chance to release. Therefore, this also causes residual resources to
> accumulate. To solve above issue, unconditionally clean up'mod_map'.
> Of course, the root cause of this problem is the presence of
> ftrace_disabled. The fixes tags patch introduces the possibility of
> residual resources in the case of ftrace_disabled. The root cause of
> the problem is ftrace_disabled. This patch only adds protection when
> ftrace_disabled occurs.
> 

I've updated the above change log to state the below. It adds a bit more
details about what exactly went wrong:

-- Steve


The following issue happens with a buggy module:

BUG: unable to handle page fault for address: ffffffffc05d0218
PGD 1bd66f067 P4D 1bd66f067 PUD 1bd671067 PMD 101808067 PTE 0
Oops: Oops: 0000 [#1] SMP KASAN PTI
Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
RIP: 0010:sized_strscpy+0x81/0x2f0
RSP: 0018:ffff88812d76fa08 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffffffffc0601010 RCX: dffffc0000000000
RDX: 0000000000000038 RSI: dffffc0000000000 RDI: ffff88812608da2d
RBP: 8080808080808080 R08: ffff88812608da2d R09: ffff88812608da68
R10: ffff88812608d82d R11: ffff88812608d810 R12: 0000000000000038
R13: ffff88812608da2d R14: ffffffffc05d0218 R15: fefefefefefefeff
FS:  00007fef552de740(0000) GS:ffff8884251c7000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffffffc05d0218 CR3: 00000001146f0000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
 ftrace_mod_get_kallsym+0x1ac/0x590
 update_iter_mod+0x239/0x5b0
 s_next+0x5b/0xa0
 seq_read_iter+0x8c9/0x1070
 seq_read+0x249/0x3b0
 proc_reg_read+0x1b0/0x280
 vfs_read+0x17f/0x920
 ksys_read+0xf3/0x1c0
 do_syscall_64+0x5f/0x2e0
 entry_SYSCALL_64_after_hwframe+0x76/0x7e

The above issue may happen as follows:
(1) Add kprobe tracepoint;
(2) insmod test.ko;
(3)  Module triggers ftrace disabled;
(4) rmmod test.ko;
(5) cat /proc/kallsyms; --> Will trigger UAF as test.ko already removed;
ftrace_mod_get_kallsym()
...
strscpy(module_name, mod_map->mod->name, MODULE_NAME_LEN);
...

The problem is when a module triggers an issue with ftrace and
sets ftrace_disable. The ftrace_disable is set when an anomaly is
discovered and to prevent any more damage, ftrace stops all text
modification. The issue that happened was that the ftrace_disable stops
more than just the text modification.

When a module is loaded, its init functions can also be traced. Because
kallsyms deletes the init functions after a module has loaded, ftrace
saves them when the module is loaded and function tracing is enabled. This
allows the output of the function trace to show the init function names
instead of just their raw memory addresses.

When a module is removed, ftrace_release_mod() is called, and if
ftrace_disable is set, it just returns without doing anything more. The
problem here is that it leaves the mod_list still around and if kallsyms
is called, it will call into this code and access the module memory that
has already been freed as it will return:

  strscpy(module_name, mod_map->mod->name, MODULE_NAME_LEN);

Where the "mod" no longer exists and triggers a UAF bug.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3 1/2] ftrace: fix UAF when lookup kallsym after ftrace disabled
  2025-06-02 15:28   ` Steven Rostedt
@ 2025-06-06  1:52     ` yebin
  2025-06-06  2:49       ` Steven Rostedt
  0 siblings, 1 reply; 6+ messages in thread
From: yebin @ 2025-06-06  1:52 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: mhiramat, mathieu.desnoyers, mark.rutland, linux-trace-kernel,
	yebin10



On 2025/6/2 23:28, Steven Rostedt wrote:
> On Thu, 29 May 2025 19:19:54 +0800
> Ye Bin <yebin@huaweicloud.com> wrote:
>
>> From: Ye Bin <yebin10@huawei.com>
>>
>> There's issue as follows:
>> BUG: unable to handle page fault for address: ffffffffc05d0218
>> PGD 1bd66f067 P4D 1bd66f067 PUD 1bd671067 PMD 101808067 PTE 0
>> Oops: Oops: 0000 [#1] SMP KASAN PTI
>> Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
>> RIP: 0010:sized_strscpy+0x81/0x2f0
>> RSP: 0018:ffff88812d76fa08 EFLAGS: 00010246
>> RAX: 0000000000000000 RBX: ffffffffc0601010 RCX: dffffc0000000000
>> RDX: 0000000000000038 RSI: dffffc0000000000 RDI: ffff88812608da2d
>> RBP: 8080808080808080 R08: ffff88812608da2d R09: ffff88812608da68
>> R10: ffff88812608d82d R11: ffff88812608d810 R12: 0000000000000038
>> R13: ffff88812608da2d R14: ffffffffc05d0218 R15: fefefefefefefeff
>> FS:  00007fef552de740(0000) GS:ffff8884251c7000(0000) knlGS:0000000000000000
>> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> CR2: ffffffffc05d0218 CR3: 00000001146f0000 CR4: 00000000000006f0
>> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
>> Call Trace:
>>   <TASK>
>>   ftrace_mod_get_kallsym+0x1ac/0x590
>>   update_iter_mod+0x239/0x5b0
>>   s_next+0x5b/0xa0
>>   seq_read_iter+0x8c9/0x1070
>>   seq_read+0x249/0x3b0
>>   proc_reg_read+0x1b0/0x280
>>   vfs_read+0x17f/0x920
>>   ksys_read+0xf3/0x1c0
>>   do_syscall_64+0x5f/0x2e0
>>   entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>
>> Above issue may happens as follow:
>> (1) Add kprobe trace point;
>> (2) insmod test.ko;
>> (3) Trigger ftrace disabled;
>> (4) rmmod test.ko;
>> (5) cat /proc/kallsyms; --> Will trigger UAF as test.ko already removed;
>> ftrace_mod_get_kallsym()
>> ...
>> strscpy(module_name, mod_map->mod->name, MODULE_NAME_LEN);
>> ...
>>
>> As ftrace_release_mod() judge 'ftrace_disabled' is true will return,
>> and 'mod_map' will remaining in ftrace_mod_maps. 'mod_map' has no
>> chance to release. Therefore, this also causes residual resources to
>> accumulate. To solve above issue, unconditionally clean up'mod_map'.
>> Of course, the root cause of this problem is the presence of
>> ftrace_disabled. The fixes tags patch introduces the possibility of
>> residual resources in the case of ftrace_disabled. The root cause of
>> the problem is ftrace_disabled. This patch only adds protection when
>> ftrace_disabled occurs.
>>
>
> I've updated the above change log to state the below. It adds a bit more
> details about what exactly went wrong:
>
> -- Steve
>
Thank you very much for your detailed and clear explanation. Do I need 
to send another version?
>
> The following issue happens with a buggy module:
>
> BUG: unable to handle page fault for address: ffffffffc05d0218
> PGD 1bd66f067 P4D 1bd66f067 PUD 1bd671067 PMD 101808067 PTE 0
> Oops: Oops: 0000 [#1] SMP KASAN PTI
> Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> RIP: 0010:sized_strscpy+0x81/0x2f0
> RSP: 0018:ffff88812d76fa08 EFLAGS: 00010246
> RAX: 0000000000000000 RBX: ffffffffc0601010 RCX: dffffc0000000000
> RDX: 0000000000000038 RSI: dffffc0000000000 RDI: ffff88812608da2d
> RBP: 8080808080808080 R08: ffff88812608da2d R09: ffff88812608da68
> R10: ffff88812608d82d R11: ffff88812608d810 R12: 0000000000000038
> R13: ffff88812608da2d R14: ffffffffc05d0218 R15: fefefefefefefeff
> FS:  00007fef552de740(0000) GS:ffff8884251c7000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: ffffffffc05d0218 CR3: 00000001146f0000 CR4: 00000000000006f0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> Call Trace:
>   <TASK>
>   ftrace_mod_get_kallsym+0x1ac/0x590
>   update_iter_mod+0x239/0x5b0
>   s_next+0x5b/0xa0
>   seq_read_iter+0x8c9/0x1070
>   seq_read+0x249/0x3b0
>   proc_reg_read+0x1b0/0x280
>   vfs_read+0x17f/0x920
>   ksys_read+0xf3/0x1c0
>   do_syscall_64+0x5f/0x2e0
>   entry_SYSCALL_64_after_hwframe+0x76/0x7e
>
> The above issue may happen as follows:
> (1) Add kprobe tracepoint;
> (2) insmod test.ko;
> (3)  Module triggers ftrace disabled;
> (4) rmmod test.ko;
> (5) cat /proc/kallsyms; --> Will trigger UAF as test.ko already removed;
> ftrace_mod_get_kallsym()
> ...
> strscpy(module_name, mod_map->mod->name, MODULE_NAME_LEN);
> ...
>
> The problem is when a module triggers an issue with ftrace and
> sets ftrace_disable. The ftrace_disable is set when an anomaly is
> discovered and to prevent any more damage, ftrace stops all text
> modification. The issue that happened was that the ftrace_disable stops
> more than just the text modification.
>
> When a module is loaded, its init functions can also be traced. Because
> kallsyms deletes the init functions after a module has loaded, ftrace
> saves them when the module is loaded and function tracing is enabled. This
> allows the output of the function trace to show the init function names
> instead of just their raw memory addresses.
>
> When a module is removed, ftrace_release_mod() is called, and if
> ftrace_disable is set, it just returns without doing anything more. The
> problem here is that it leaves the mod_list still around and if kallsyms
> is called, it will call into this code and access the module memory that
> has already been freed as it will return:
>
>    strscpy(module_name, mod_map->mod->name, MODULE_NAME_LEN);
>
> Where the "mod" no longer exists and triggers a UAF bug.
>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3 1/2] ftrace: fix UAF when lookup kallsym after ftrace disabled
  2025-06-06  1:52     ` yebin
@ 2025-06-06  2:49       ` Steven Rostedt
  0 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2025-06-06  2:49 UTC (permalink / raw)
  To: yebin
  Cc: mhiramat, mathieu.desnoyers, mark.rutland, linux-trace-kernel,
	yebin10

On Fri, 6 Jun 2025 09:52:07 +0800
yebin <yebin@huaweicloud.com> wrote:

> Thank you very much for your detailed and clear explanation. Do I need 
> to send another version?

Nope, it's already been pulled into mainline:

  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f914b52c379c12288b7623bb814d0508dbe7481d

-- Steve

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-06-06  2:47 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-29 11:19 [PATCH v3 0/2] fix UAF when lookup kallsym after ftrace disabled Ye Bin
2025-05-29 11:19 ` [PATCH v3 1/2] ftrace: " Ye Bin
2025-06-02 15:28   ` Steven Rostedt
2025-06-06  1:52     ` yebin
2025-06-06  2:49       ` Steven Rostedt
2025-05-29 11:19 ` [PATCH v3 2/2] ftrace: don't allocate ftrace module map if ftrace is disabled Ye Bin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).