linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 0/2] Command line randomness
@ 2017-08-16 23:14 Laura Abbott
  2017-08-16 23:14 ` [PATCHv3 1/2] init: Move stack canary initialization after setup_arch Laura Abbott
  2017-08-16 23:14 ` [PATCHv3 2/2] extract early boot entropy from the passed cmdline Laura Abbott
  0 siblings, 2 replies; 10+ messages in thread
From: Laura Abbott @ 2017-08-16 23:14 UTC (permalink / raw)
  To: Kees Cook
  Cc: Laura Abbott, kernel-hardening, linux-kernel, linux-mm,
	Andrew Morton, Daniel Micay

Hi,

This is v3 of the series to add the kernel command line as a source
of randomness. The main change from v2 is to correctly place the
command line randomness _before_ the stack canary initialization
so the canary can take advantage of that.

Daniel Micay (1):
  extract early boot entropy from the passed cmdline

Laura Abbott (1):
  init: Move stack canary initialization after setup_arch

 init/main.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

-- 
2.13.0

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

* [PATCHv3 1/2] init: Move stack canary initialization after setup_arch
  2017-08-16 23:14 [PATCHv3 0/2] Command line randomness Laura Abbott
@ 2017-08-16 23:14 ` Laura Abbott
  2017-08-16 23:14 ` [PATCHv3 2/2] extract early boot entropy from the passed cmdline Laura Abbott
  1 sibling, 0 replies; 10+ messages in thread
From: Laura Abbott @ 2017-08-16 23:14 UTC (permalink / raw)
  To: Kees Cook
  Cc: Laura Abbott, kernel-hardening, linux-kernel, linux-mm,
	Andrew Morton, Daniel Micay, Laura Abbott

From: Laura Abbott <lauraa@codeaurora.org>


Stack canary intialization involves getting a random number.
Getting this random number may involve accessing caches or other
architectural specific features which are not available until
after the architecture is setup. Move the stack canary initialization
later to accomodate this.

Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
v3: Ack from Kees
---
 init/main.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/init/main.c b/init/main.c
index 052481fbe363..21d599eaad06 100644
--- a/init/main.c
+++ b/init/main.c
@@ -515,12 +515,6 @@ asmlinkage __visible void __init start_kernel(void)
 	smp_setup_processor_id();
 	debug_objects_early_init();
 
-	/*
-	 * Set up the initial canary ASAP:
-	 */
-	add_latent_entropy();
-	boot_init_stack_canary();
-
 	cgroup_init_early();
 
 	local_irq_disable();
@@ -534,6 +528,11 @@ asmlinkage __visible void __init start_kernel(void)
 	page_address_init();
 	pr_notice("%s", linux_banner);
 	setup_arch(&command_line);
+	/*
+	 * Set up the the initial canary and entropy after arch
+	 */
+	add_latent_entropy();
+	boot_init_stack_canary();
 	mm_init_cpumask(&init_mm);
 	setup_command_line(command_line);
 	setup_nr_cpu_ids();
-- 
2.13.0

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

* [PATCHv3 2/2] extract early boot entropy from the passed cmdline
  2017-08-16 23:14 [PATCHv3 0/2] Command line randomness Laura Abbott
  2017-08-16 23:14 ` [PATCHv3 1/2] init: Move stack canary initialization after setup_arch Laura Abbott
@ 2017-08-16 23:14 ` Laura Abbott
  2017-08-16 23:23   ` Kees Cook
  2017-08-17  3:31   ` Theodore Ts'o
  1 sibling, 2 replies; 10+ messages in thread
From: Laura Abbott @ 2017-08-16 23:14 UTC (permalink / raw)
  To: Kees Cook
  Cc: Daniel Micay, kernel-hardening, linux-kernel, linux-mm,
	Andrew Morton, Laura Abbott

From: Daniel Micay <danielmicay@gmail.com>


Existing Android bootloaders usually pass data useful as early entropy
on the kernel command-line. It may also be the case on other embedded
systems. Sample command-line from a Google Pixel running CopperheadOS:

    console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0
    androidboot.hardware=sailfish user_debug=31 ehci-hcd.park=3
    lpm_levels.sleep_disabled=1 cma=32M@0-0xffffffff buildvariant=user
    veritykeyid=id:dfcb9db0089e5b3b4090a592415c28e1cb4545ab
    androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=yellow
    androidboot.veritymode=enforcing androidboot.keymaster=1
    androidboot.serialno=FA6CE0305299 androidboot.baseband=msm
    mdss_mdp.panel=1:dsi:0:qcom,mdss_dsi_samsung_ea8064tg_1080p_cmd:1:none:cfg:single_dsi
    androidboot.slot_suffix=_b fpsimd.fpsimd_settings=0
    app_setting.use_app_setting=0 kernelflag=0x00000000 debugflag=0x00000000
    androidboot.hardware.revision=PVT radioflag=0x00000000
    radioflagex1=0x00000000 radioflagex2=0x00000000 cpumask=0x00000000
    androidboot.hardware.ddr=4096MB,Hynix,LPDDR4 androidboot.ddrinfo=00000006
    androidboot.ddrsize=4GB androidboot.hardware.color=GRA00
    androidboot.hardware.ufs=32GB,Samsung androidboot.msm.hw_ver_id=268824801
    androidboot.qf.st=2 androidboot.cid=11111111 androidboot.mid=G-2PW4100
    androidboot.bootloader=8996-012001-1704121145
    androidboot.oem_unlock_support=1 androidboot.fp_src=1
    androidboot.htc.hrdump=detected androidboot.ramdump.opt=mem@2g:2g,mem@4g:2g
    androidboot.bootreason=reboot androidboot.ramdump_enable=0 ro
    root=/dev/dm-0 dm="system none ro,0 1 android-verity /dev/sda34"
    rootwait skip_initramfs init=/init androidboot.wificountrycode=US
    androidboot.boottime=1BLL:85,1BLE:669,2BLL:0,2BLE:1777,SW:6,KL:8136

Among other things, it contains a value unique to the device
(androidboot.serialno=FA6CE0305299), unique to the OS builds for the
device variant (veritykeyid=id:dfcb9db0089e5b3b4090a592415c28e1cb4545ab)
and timings from the bootloader stages in milliseconds
(androidboot.boottime=1BLL:85,1BLE:669,2BLL:0,2BLE:1777,SW:6,KL:8136).

Signed-off-by: Daniel Micay <danielmicay@gmail.com>
[labbott: Line-wrapped command line]
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
v3: add_device_randomness comes before canary initialization, clarified comment.
---
 init/main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/init/main.c b/init/main.c
index 21d599eaad06..ba2b3a8a2382 100644
--- a/init/main.c
+++ b/init/main.c
@@ -530,8 +530,10 @@ asmlinkage __visible void __init start_kernel(void)
 	setup_arch(&command_line);
 	/*
 	 * Set up the the initial canary and entropy after arch
+	 * and after adding latent and command line entropy.
 	 */
 	add_latent_entropy();
+	add_device_randomness(command_line, strlen(command_line));
 	boot_init_stack_canary();
 	mm_init_cpumask(&init_mm);
 	setup_command_line(command_line);
-- 
2.13.0

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

* Re: [PATCHv3 2/2] extract early boot entropy from the passed cmdline
  2017-08-16 23:14 ` [PATCHv3 2/2] extract early boot entropy from the passed cmdline Laura Abbott
@ 2017-08-16 23:23   ` Kees Cook
  2017-08-17  3:31   ` Theodore Ts'o
  1 sibling, 0 replies; 10+ messages in thread
From: Kees Cook @ 2017-08-16 23:23 UTC (permalink / raw)
  To: Laura Abbott
  Cc: Daniel Micay, kernel-hardening, LKML, Linux-MM, Andrew Morton

On Wed, Aug 16, 2017 at 4:14 PM, Laura Abbott <labbott@redhat.com> wrote:
> From: Daniel Micay <danielmicay@gmail.com>
>
>
> Existing Android bootloaders usually pass data useful as early entropy
> on the kernel command-line. It may also be the case on other embedded
> systems. Sample command-line from a Google Pixel running CopperheadOS:
>
>     console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0
>     androidboot.hardware=sailfish user_debug=31 ehci-hcd.park=3
>     lpm_levels.sleep_disabled=1 cma=32M@0-0xffffffff buildvariant=user
>     veritykeyid=id:dfcb9db0089e5b3b4090a592415c28e1cb4545ab
>     androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=yellow
>     androidboot.veritymode=enforcing androidboot.keymaster=1
>     androidboot.serialno=FA6CE0305299 androidboot.baseband=msm
>     mdss_mdp.panel=1:dsi:0:qcom,mdss_dsi_samsung_ea8064tg_1080p_cmd:1:none:cfg:single_dsi
>     androidboot.slot_suffix=_b fpsimd.fpsimd_settings=0
>     app_setting.use_app_setting=0 kernelflag=0x00000000 debugflag=0x00000000
>     androidboot.hardware.revision=PVT radioflag=0x00000000
>     radioflagex1=0x00000000 radioflagex2=0x00000000 cpumask=0x00000000
>     androidboot.hardware.ddr=4096MB,Hynix,LPDDR4 androidboot.ddrinfo=00000006
>     androidboot.ddrsize=4GB androidboot.hardware.color=GRA00
>     androidboot.hardware.ufs=32GB,Samsung androidboot.msm.hw_ver_id=268824801
>     androidboot.qf.st=2 androidboot.cid=11111111 androidboot.mid=G-2PW4100
>     androidboot.bootloader=8996-012001-1704121145
>     androidboot.oem_unlock_support=1 androidboot.fp_src=1
>     androidboot.htc.hrdump=detected androidboot.ramdump.opt=mem@2g:2g,mem@4g:2g
>     androidboot.bootreason=reboot androidboot.ramdump_enable=0 ro
>     root=/dev/dm-0 dm="system none ro,0 1 android-verity /dev/sda34"
>     rootwait skip_initramfs init=/init androidboot.wificountrycode=US
>     androidboot.boottime=1BLL:85,1BLE:669,2BLL:0,2BLE:1777,SW:6,KL:8136
>
> Among other things, it contains a value unique to the device
> (androidboot.serialno=FA6CE0305299), unique to the OS builds for the
> device variant (veritykeyid=id:dfcb9db0089e5b3b4090a592415c28e1cb4545ab)
> and timings from the bootloader stages in milliseconds
> (androidboot.boottime=1BLL:85,1BLE:669,2BLL:0,2BLE:1777,SW:6,KL:8136).
>
> Signed-off-by: Daniel Micay <danielmicay@gmail.com>
> [labbott: Line-wrapped command line]
> Signed-off-by: Laura Abbott <labbott@redhat.com>

Acked-by: Kees Cook <keescook@chromium.org>

Thanks!

-Kees

> ---
> v3: add_device_randomness comes before canary initialization, clarified comment.
> ---
>  init/main.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/init/main.c b/init/main.c
> index 21d599eaad06..ba2b3a8a2382 100644
> --- a/init/main.c
> +++ b/init/main.c
> @@ -530,8 +530,10 @@ asmlinkage __visible void __init start_kernel(void)
>         setup_arch(&command_line);
>         /*
>          * Set up the the initial canary and entropy after arch
> +        * and after adding latent and command line entropy.
>          */
>         add_latent_entropy();
> +       add_device_randomness(command_line, strlen(command_line));
>         boot_init_stack_canary();
>         mm_init_cpumask(&init_mm);
>         setup_command_line(command_line);
> --
> 2.13.0
>



-- 
Kees Cook
Pixel Security

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

* Re: [PATCHv3 2/2] extract early boot entropy from the passed cmdline
  2017-08-16 23:14 ` [PATCHv3 2/2] extract early boot entropy from the passed cmdline Laura Abbott
  2017-08-16 23:23   ` Kees Cook
@ 2017-08-17  3:31   ` Theodore Ts'o
  2017-08-17  4:23     ` Daniel Micay
  2017-08-30  9:57     ` Pavel Machek
  1 sibling, 2 replies; 10+ messages in thread
From: Theodore Ts'o @ 2017-08-17  3:31 UTC (permalink / raw)
  To: Laura Abbott
  Cc: Kees Cook, Daniel Micay, kernel-hardening, linux-kernel,
	linux-mm, Andrew Morton

On Wed, Aug 16, 2017 at 04:14:58PM -0700, Laura Abbott wrote:
> From: Daniel Micay <danielmicay@gmail.com>
> 
> Existing Android bootloaders usually pass data useful as early entropy
> on the kernel command-line. It may also be the case on other embedded
> systems.....

May I suggest a slight adjustment to the beginning commit description?

   Feed the boot command-line as to the /dev/random entropy pool

   Existing Android bootloaders usually pass data which may not be
   known by an external attacker on the kernel command-line.  It may
   also be the case on other embedded systems.  Sample command-line
   from a Google Pixel running CopperheadOS....

The idea here is to if anything, err on the side of under-promising
the amount of security we can guarantee that this technique will
provide.  For example, how hard is it really for an attacker who has
an APK installed locally to get the device serial number?  Or the OS
version?  And how much variability is there in the bootloader stages
in milliseconds?

I think we should definitely do this.  So this is more of a request to
be very careful what we promise in the commit description, not an
objection to the change itself.

Cheers,

					- Ted

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

* Re: [PATCHv3 2/2] extract early boot entropy from the passed cmdline
  2017-08-17  3:31   ` Theodore Ts'o
@ 2017-08-17  4:23     ` Daniel Micay
  2017-08-17 20:57       ` Daniel Micay
  2017-08-30  9:57     ` Pavel Machek
  1 sibling, 1 reply; 10+ messages in thread
From: Daniel Micay @ 2017-08-17  4:23 UTC (permalink / raw)
  To: Theodore Ts'o, Laura Abbott
  Cc: Kees Cook, kernel-hardening, linux-kernel, linux-mm, Andrew Morton

On Wed, 2017-08-16 at 23:31 -0400, Theodore Ts'o wrote:
> On Wed, Aug 16, 2017 at 04:14:58PM -0700, Laura Abbott wrote:
> > From: Daniel Micay <danielmicay@gmail.com>
> > 
> > Existing Android bootloaders usually pass data useful as early
> > entropy
> > on the kernel command-line. It may also be the case on other
> > embedded
> > systems.....
> 
> May I suggest a slight adjustment to the beginning commit description?
> 
>    Feed the boot command-line as to the /dev/random entropy pool
> 
>    Existing Android bootloaders usually pass data which may not be
>    known by an external attacker on the kernel command-line.  It may
>    also be the case on other embedded systems.  Sample command-line
>    from a Google Pixel running CopperheadOS....
> 
> The idea here is to if anything, err on the side of under-promising
> the amount of security we can guarantee that this technique will
> provide.  For example, how hard is it really for an attacker who has
> an APK installed locally to get the device serial number?  Or the OS
> version?  And how much variability is there in the bootloader stages
> in milliseconds?

The serial number is currently accessible to local apps up until Android
7.x so it doesn't have value if the adversary has local access. Access
to it without the READ_PHONE_STATE permission is being removed for apps
targeting Android 8.0 and will presumably be restructed for all apps at
some point in the future:

https://android-developers.googleblog.com/2017/04/changes-to-device-identifiers-in.html

Some bootloader stages vary a bit in time each boot. There's not much
variance or measurement precision so there's only a small amount of
entropy from this. The ones that consistently vary in timing do so
independently from each other so that helps a bit. Also worth noting
that before Android 8.0+, local apps can access the boot times since
it's written to a system property. After Android 8.0+, all that stuff is
inaccessible to them (no permission to get them) since there's a
whitelisting model for system property access.

> I think we should definitely do this.  So this is more of a request to
> be very careful what we promise in the commit description, not an
> objection to the change itself.

I did say 'external attacker' but it could be made clearer. It's
primarily aimed at getting a tiny bit of extra entropy for the kernel
stack canary and other probabilistic exploit mitigations set up in early
boot. On non-x86 archs, i.e. 99.9% of Android devices, the kernel stack
canary remains the same after it's set up in that early boot code.

Android devices almost all have a hardware RNG and Android init blocks
until a fair bit of data is read from it along with restoring entropy
that's regularly saved while running, but unfortunately that's not
available at this point in the boot process.

The kernel could save / restore entropy using pstore (which at least
Nexus / Pixel devices have - not sure about others). I don't know how
early that could feasibly be done. Ideally it would do that combined
with early usage of the hwrng.

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

* Re: [PATCHv3 2/2] extract early boot entropy from the passed cmdline
  2017-08-17  4:23     ` Daniel Micay
@ 2017-08-17 20:57       ` Daniel Micay
  2017-08-17 21:44         ` Theodore Ts'o
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel Micay @ 2017-08-17 20:57 UTC (permalink / raw)
  To: Theodore Ts'o, Laura Abbott
  Cc: Kees Cook, kernel-hardening, linux-kernel, linux-mm, Andrew Morton

> I did say 'external attacker' but it could be made clearer.

Er, s/say/mean to imply/

I do think it will have some local value after Android 8 which should
start shipping in a few days though.

I'll look into having the kernel stash some entropy in pstore soon since
that seems like it could be a great improvement. I'm not sure how often
/ where it should hook into for regularly refreshing it though. Doing it
only on powering down isn't ideal.

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

* Re: [PATCHv3 2/2] extract early boot entropy from the passed cmdline
  2017-08-17 20:57       ` Daniel Micay
@ 2017-08-17 21:44         ` Theodore Ts'o
  0 siblings, 0 replies; 10+ messages in thread
From: Theodore Ts'o @ 2017-08-17 21:44 UTC (permalink / raw)
  To: Daniel Micay
  Cc: Laura Abbott, Kees Cook, kernel-hardening, linux-kernel,
	linux-mm, Andrew Morton

On Thu, Aug 17, 2017 at 04:57:07PM -0400, Daniel Micay wrote:
> > I did say 'external attacker' but it could be made clearer.
> 
> Er, s/say/mean to imply/

Right, that's why I had suggested modifying the first few lines of the
commit description to read something like this:

  Feed the boot command-line as to the /dev/random entropy pool

  Existing Android bootloaders usually pass data which may not be known
  by an external attacker on the kernel command-line.  It may also be
  the case on other embedded systems.  Sample command-line from a Google
  Pixel running CopperheadOS:

(Or something like that.)

> I'll look into having the kernel stash some entropy in pstore soon since
> that seems like it could be a great improvement. I'm not sure how often
> / where it should hook into for regularly refreshing it though. Doing it
> only on powering down isn't ideal.

One thing we could do is to agree on a standard place where the
entropy would be stashed, and then have the kernel remove it from
being visible in /proc/cmdline.  That's not a perfect answer, since
the user might be able to look at the command line via other
mechanisms.  (For example, on x86, by looking at GRUB while the system
is booting.)

However, an attacker who is merely running code on the local system is
not likely to be gain access to that value --- so it's definitely an
improvement.

Refreshing the entry immediately after boot, and before a clean
shutdown would be ideal from a security perspective.  I don't know if
there are write endurance issues with updating the pstore that
frequently, though.

						- Ted

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

* Re: [PATCHv3 2/2] extract early boot entropy from the passed cmdline
  2017-08-17  3:31   ` Theodore Ts'o
  2017-08-17  4:23     ` Daniel Micay
@ 2017-08-30  9:57     ` Pavel Machek
  2017-08-30 13:27       ` [kernel-hardening] " Nick Kralevich
  1 sibling, 1 reply; 10+ messages in thread
From: Pavel Machek @ 2017-08-30  9:57 UTC (permalink / raw)
  To: Theodore Ts'o, Laura Abbott, Kees Cook, Daniel Micay,
	kernel-hardening, linux-kernel, linux-mm, Andrew Morton

[-- Attachment #1: Type: text/plain, Size: 1737 bytes --]

On Wed 2017-08-16 23:31:48, Theodore Ts'o wrote:
> On Wed, Aug 16, 2017 at 04:14:58PM -0700, Laura Abbott wrote:
> > From: Daniel Micay <danielmicay@gmail.com>
> > 
> > Existing Android bootloaders usually pass data useful as early entropy
> > on the kernel command-line. It may also be the case on other embedded
> > systems.....
> 
> May I suggest a slight adjustment to the beginning commit description?
> 
>    Feed the boot command-line as to the /dev/random entropy pool
> 
>    Existing Android bootloaders usually pass data which may not be
>    known by an external attacker on the kernel command-line.  It may
>    also be the case on other embedded systems.  Sample command-line
>    from a Google Pixel running CopperheadOS....
> 
> The idea here is to if anything, err on the side of under-promising
> the amount of security we can guarantee that this technique will
> provide.  For example, how hard is it really for an attacker who has
> an APK installed locally to get the device serial number?  Or the OS
> version?  And how much variability is there in the bootloader stages
> in milliseconds?
> 
> I think we should definitely do this.  So this is more of a request to
> be very careful what we promise in the commit description, not an
> objection to the change itself.

The command line is visible to unpriviledged userspace (/proc/cmdline,
dmesg). Is that a problem?

U-boot already does some crypto stuff, so it may have some
randomness. Should we create parameter random=xxxxxxxxxxx that is
"censored" during kernel boot?

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

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

* Re: [kernel-hardening] Re: [PATCHv3 2/2] extract early boot entropy from the passed cmdline
  2017-08-30  9:57     ` Pavel Machek
@ 2017-08-30 13:27       ` Nick Kralevich
  0 siblings, 0 replies; 10+ messages in thread
From: Nick Kralevich @ 2017-08-30 13:27 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Theodore Ts'o, Laura Abbott, Kees Cook, Daniel Micay,
	kernel-hardening, lkml, linux-mm, Andrew Morton

On Wed, Aug 30, 2017 at 2:57 AM, Pavel Machek <pavel@ucw.cz> wrote:
> The command line is visible to unpriviledged userspace (/proc/cmdline,
> dmesg). Is that a problem?

These files are not exposed to untrusted processes on Android.

-- 
Nick Kralevich | Android Security | nnk@google.com | 650.214.4037

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

end of thread, other threads:[~2017-08-30 13:27 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-16 23:14 [PATCHv3 0/2] Command line randomness Laura Abbott
2017-08-16 23:14 ` [PATCHv3 1/2] init: Move stack canary initialization after setup_arch Laura Abbott
2017-08-16 23:14 ` [PATCHv3 2/2] extract early boot entropy from the passed cmdline Laura Abbott
2017-08-16 23:23   ` Kees Cook
2017-08-17  3:31   ` Theodore Ts'o
2017-08-17  4:23     ` Daniel Micay
2017-08-17 20:57       ` Daniel Micay
2017-08-17 21:44         ` Theodore Ts'o
2017-08-30  9:57     ` Pavel Machek
2017-08-30 13:27       ` [kernel-hardening] " Nick Kralevich

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).