diff mbox series

[v3,7/8] package/petitboot: enable user separation

Message ID 20231009151729.2223963-8-arbab@linux.ibm.com
State Changes Requested
Headers show
Series package/petitboot: misc fixes/enhancement | expand

Commit Message

Reza Arbab Oct. 9, 2023, 3:17 p.m. UTC
Run the petitboot UI as an unprivileged user. This requires using the
agetty package instead of the busybox getty utility, running the initial
pb-console helper at user login rather than directly.

If sudo is installed, with a sudoers policy allowing petituser to
perform sudo with no password (or a blank password), the "drop to shell"
feature of petitboot will automatically become a root shell.

Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
---
 package/petitboot/Config.in      |  1 +
 package/petitboot/S15pb-discover |  4 +++-
 package/petitboot/pb-console     |  6 ++++--
 package/petitboot/petitboot.mk   | 12 ++++++++++++
 package/petitboot/shell_config   | 24 ++++++++++++++++++++++++
 package/petitboot/shell_profile  |  2 ++
 6 files changed, 46 insertions(+), 3 deletions(-)
 create mode 100644 package/petitboot/shell_config
 create mode 100644 package/petitboot/shell_profile

Comments

Arnout Vandecappelle Nov. 5, 2023, 6:26 p.m. UTC | #1
On 09/10/2023 17:17, Reza Arbab wrote:
> Run the petitboot UI as an unprivileged user. This requires using the
> agetty package instead of the busybox getty utility, running the initial
> pb-console helper at user login rather than directly.

  That sounds counterproductive though? It means you have to log in before the 
boot menu is displayed? Or perhaps I misunderstand the statement here.

  It's also not clear why it would need agetty instead of busybox getty.

  This doesn't sound like something that should be done by default.


> If sudo is installed, with a sudoers policy allowing petituser to
> perform sudo with no password (or a blank password), the "drop to shell"
> feature of petitboot will automatically become a root shell.

  It seems to me that the logical thing to do would be to drop into an actual 
getty, which asks for a login and password.

> 
> Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
> ---
>   package/petitboot/Config.in      |  1 +
>   package/petitboot/S15pb-discover |  4 +++-
>   package/petitboot/pb-console     |  6 ++++--
>   package/petitboot/petitboot.mk   | 12 ++++++++++++
>   package/petitboot/shell_config   | 24 ++++++++++++++++++++++++
>   package/petitboot/shell_profile  |  2 ++
>   6 files changed, 46 insertions(+), 3 deletions(-)
>   create mode 100644 package/petitboot/shell_config
>   create mode 100644 package/petitboot/shell_profile
> 
> diff --git a/package/petitboot/Config.in b/package/petitboot/Config.in
> index 5f1d91e77ecb..0f965e71e628 100644
> --- a/package/petitboot/Config.in
> +++ b/package/petitboot/Config.in
> @@ -16,6 +16,7 @@ config BR2_PACKAGE_PETITBOOT
>   	select BR2_PACKAGE_KEXEC_LITE if ( BR2_powerpc || BR2_powerpc64 || BR2_powerpc64le )
>   	select BR2_PACKAGE_NVME if ( BR2_powerpc || BR2_powerpc64 || BR2_powerpc64le )
>   	select BR2_PACKAGE_POWERPC_UTILS if ( BR2_powerpc || BR2_powerpc64 || BR2_powerpc64le )
> +	select BR2_PACKAGE_UTIL_LINUX_AGETTY
>   	help
>   	  Petitboot is a small kexec-based bootloader
>   
> diff --git a/package/petitboot/S15pb-discover b/package/petitboot/S15pb-discover
> index 71ab62d99859..a37e33521f1a 100644
> --- a/package/petitboot/S15pb-discover
> +++ b/package/petitboot/S15pb-discover
> @@ -12,7 +12,9 @@ fi
>   
>   start() {
>   	printf 'Starting %s: ' "$DAEMON"
> -	mkdir -p /var/log/petitboot
> +	# shellcheck disable=SC2174 # only apply -m to deepest dir
> +	mkdir -p -m 0775 /var/log/petitboot
> +	chown root:petitgroup /var/log/petitboot

  Why is it owned by root and not petituser?

>   
>   	# shellcheck disable=SC2086 # we need the word splitting
>   	start-stop-daemon -S -q -b -m -p "$PIDFILE" -x "/usr/sbin/$DAEMON" \
> diff --git a/package/petitboot/pb-console b/package/petitboot/pb-console
> index 407ff3b30232..eea40163d02f 100644
> --- a/package/petitboot/pb-console
> +++ b/package/petitboot/pb-console
> @@ -3,14 +3,16 @@
>   DAEMON="pb-console"
>   
>   PB_CONSOLE_PORT=${2:-"console"}
> -PB_CONSOLE_ARGS="--getty --detach -- -n -i 0 $PB_CONSOLE_PORT linux"
> +PB_CONSOLE_ARGS="--getty=/sbin/agetty --detach -- -a petituser -n -i $PB_CONSOLE_PORT linux"
>   
>   # shellcheck source=/dev/null
>   [ -r "/etc/default/petitboot" ] && . "/etc/default/petitboot"
>   
>   start() {
>   	printf 'Starting %s on %s: ' "$DAEMON" "$PB_CONSOLE_PORT"
> -	mkdir -p /var/log/petitboot
> +	# shellcheck disable=SC2174 # only apply -m to deepest dir
> +	mkdir -p -m 0775 /var/log/petitboot
> +	chown root:petitgroup /var/log/petitboot
>   
>   	# shellcheck disable=SC2086 # we need the word splitting
>   	start-stop-daemon -S -q -x "/usr/libexec/petitboot/$DAEMON" \
> diff --git a/package/petitboot/petitboot.mk b/package/petitboot/petitboot.mk
> index ff87f3498734..5b517eb3b1a6 100644
> --- a/package/petitboot/petitboot.mk
> +++ b/package/petitboot/petitboot.mk
> @@ -71,6 +71,10 @@ define PETITBOOT_POST_INSTALL
>   		$(TARGET_DIR)/usr/sbin/kexec-restart
>   	$(INSTALL) -D -m 0755 $(PETITBOOT_PKGDIR)/pb-console \
>   		$(TARGET_DIR)/etc/init.d/pb-console
> +	$(INSTALL) -D -m 0755 $(PETITBOOT_PKGDIR)/shell_config \
> +		$(TARGET_DIR)/home/petituser/.shrc
> +	$(INSTALL) -D -m 0755 $(PETITBOOT_PKGDIR)/shell_profile \
> +		$(TARGET_DIR)/home/petituser/.profile
>   
>   	mkdir -p $(TARGET_DIR)/etc/udev/rules.d
>   	(for port in $(PETITBOOT_GETTY_PORT); do \
> @@ -84,4 +88,12 @@ endef
>   
>   PETITBOOT_POST_INSTALL_TARGET_HOOKS += PETITBOOT_POST_INSTALL
>   
> +define PETITBOOT_USERS
> +	petituser -1 petitgroup -1 * /home/petituser /bin/sh - petitboot user

  Are petitgroup and petituser standard names? If not, we normally use the 
package name as username and group name, i.e.

	petitboot -1 petitboot -1 ...


  Also, does this user really need a home directory and a shell? It really 
should be a system user, no? It's only when it falls into the shell that you 
need an actual shell...

> +endef
> +
> +define PETITBOOT_PERMISSIONS
> +	/var/petitboot d 775 root petitgroup - - - - -

  What is /var/petitboot used for?

> +endef
> +
>   $(eval $(autotools-package))
> diff --git a/package/petitboot/shell_config b/package/petitboot/shell_config
> new file mode 100644
> index 000000000000..b10b95baae6c
> --- /dev/null
> +++ b/package/petitboot/shell_config
> @@ -0,0 +1,24 @@
> +#!/bin/sh
> +
> +try_sudo() {
> +	[ -x "$(command -v sudo)" ] || return
> +	sudo -K
> +	echo | sudo -S /bin/true >/dev/null 2>&1 || return
> +
> +	echo "No password required, running as root."
> +	sudo -i
> +	sudo -K
> +	exit
> +}
> +
> +reset
> +
> +echo "Exiting petitboot. Type 'exit' to return."
> +echo "You may run 'pb-sos' to gather diagnostic data."
> +
> +if [ "$(id -u)" != "0" ]; then
> +	try_sudo
> +	export PS1='$ '
> +else
> +	export PS1='# '
> +fi
> diff --git a/package/petitboot/shell_profile b/package/petitboot/shell_profile
> new file mode 100644
> index 000000000000..1ca5e6364dba
> --- /dev/null
> +++ b/package/petitboot/shell_profile
> @@ -0,0 +1,2 @@
> +export ENV="/home/petituser/.shrc"

  This needs a bit more explanation. Is ENV something that is used by 
pb-console? How is it evaluated?

  Marked as Changes Requested.

  Regards,
  Arnout

> +exec /usr/libexec/petitboot/pb-console
Reza Arbab Nov. 9, 2023, 4:16 p.m. UTC | #2
On Sun, Nov 05, 2023 at 07:26:16PM +0100, Arnout Vandecappelle wrote:
>On 09/10/2023 17:17, Reza Arbab wrote:
>>Run the petitboot UI as an unprivileged user. This requires using the
>>agetty package instead of the busybox getty utility, running the initial
>>pb-console helper at user login rather than directly.
>
> That sounds counterproductive though? It means you have to log in 
>before the boot menu is displayed? Or perhaps I misunderstand the 
>statement here.
>
> It's also not clear why it would need agetty instead of busybox getty.

Sorry, I didn't explain it very well. The chain goes like this:

1. /etc/init.d/pb-console start console
2. /usr/libexec/petitboot/pb-console --getty --detach -- -n -i 0 console linux
3. /sbin/getty -l/usr/libexec/petitboot/pb-console -n -i 0 console linux
4. /usr/libexec/petitboot/pb-console
5. /usr/sbin/petiboot-nc
  
After the change:

1. /etc/init.d/pb-console start console
2. /usr/libexec/petitboot/pb-console --getty=/sbin/agetty --detach -- -a petituser -n -i console linux
3. /sbin/agetty -a petituser -n -i console linux
4. /home/petituser/.profile
5. /usr/libexec/petitboot/pb-console
6. /usr/sbin/petiboot-nc

Because we're using the -a (autologin) feature of agetty, everything 
from (4) down is running as petituser. If you select "drop to shell" 
from the menu, you then also do

7. /home/petituser/.shrc (the $ENV set in .profile)
8. /bin/sh

>>If sudo is installed, with a sudoers policy allowing petituser to
>>perform sudo with no password (or a blank password), the "drop to shell"
>>feature of petitboot will automatically become a root shell.
>
> It seems to me that the logical thing to do would be to drop into an 
>actual getty, which asks for a login and password.

At this point we're already running getty and (auto)logged in as
petituser. The sudo integration allos system-specific flexibility in 
if/how the the shell may be elevated. As petituser, the shell has 
permission to collect diagnostics/logs by running pb-sos.

>>--- a/package/petitboot/S15pb-discover
>>+++ b/package/petitboot/S15pb-discover
>>@@ -12,7 +12,9 @@ fi
>>  start() {
>>  	printf 'Starting %s: ' "$DAEMON"
>>-	mkdir -p /var/log/petitboot
>>+	# shellcheck disable=SC2174 # only apply -m to deepest dir
>>+	mkdir -p -m 0775 /var/log/petitboot
>>+	chown root:petitgroup /var/log/petitboot
>
> Why is it owned by root and not petituser?

I don't see any reason why it couldn't be owned by petituser.

>>@@ -84,4 +88,12 @@ endef
>>  PETITBOOT_POST_INSTALL_TARGET_HOOKS += PETITBOOT_POST_INSTALL
>>+define PETITBOOT_USERS
>>+	petituser -1 petitgroup -1 * /home/petituser /bin/sh - petitboot user
>
> Are petitgroup and petituser standard names? If not, we normally use 
>the package name as username and group name, i.e.
>
>	petitboot -1 petitboot -1 ...

I think we could change petituser to petitboot, but there is a hardcoded 
reference to petitgroup in the code:

   discover/discover-server.c:     group = getgrnam("petitgroup");

>>+define PETITBOOT_PERMISSIONS
>>+	/var/petitboot d 775 root petitgroup - - - - -
>
> What is /var/petitboot used for?

That is where pb-discover mounts devices, looking for boot sources:

   /var/petitboot/mnt/dev/nvme0n1p1/grub2/grub.cfg
   /var/petitboot/mnt/dev/nvme0n1p1/vmlinux
Arnout Vandecappelle Nov. 10, 2023, 9:01 a.m. UTC | #3
On 09/11/2023 17:16, Reza Arbab wrote:
> On Sun, Nov 05, 2023 at 07:26:16PM +0100, Arnout Vandecappelle wrote:
>> On 09/10/2023 17:17, Reza Arbab wrote:
>>> Run the petitboot UI as an unprivileged user. This requires using the
>>> agetty package instead of the busybox getty utility, running the initial
>>> pb-console helper at user login rather than directly.
>>
>> That sounds counterproductive though? It means you have to log in before the 
>> boot menu is displayed? Or perhaps I misunderstand the statement here.
>>
>> It's also not clear why it would need agetty instead of busybox getty.
> 
> Sorry, I didn't explain it very well. The chain goes like this:
> 
> 1. /etc/init.d/pb-console start console > 2. /usr/libexec/petitboot/pb-console --getty --detach -- -n -i 0 console linux
> 3. /sbin/getty -l/usr/libexec/petitboot/pb-console -n -i 0 console linux
> 4. /usr/libexec/petitboot/pb-console
> 5. /usr/sbin/petiboot-nc
> 
> After the change:
> 
> 1. /etc/init.d/pb-console start console
> 2. /usr/libexec/petitboot/pb-console --getty=/sbin/agetty --detach -- -a 
> petituser -n -i console linux
> 3. /sbin/agetty -a petituser -n -i console linux

  How did the -l option disappear here? Is that due to --getty= instead of --getty?

  Anyway, the only reason to use agetty is for the -a option. Can't we achieve 
the same by using su? I.e. create a wrapper script around pb-console that does 
something like

exec su -s /usr/libexec/petitboot/pb-console petituser

> 4. /home/petituser/.profile

  Something I didn't touch in my earlier review: I don't think .profile is the 
right place to set this up. Either petituser is a normal user - in that case 
logging in through some other means (e.g. ssh, sudo) should give a normal shell. 
I assume you can tell pb-console which "shell" to use in the "drop to shell" case.


> 5. /usr/libexec/petitboot/pb-console
> 6. /usr/sbin/petiboot-nc
> 
> Because we're using the -a (autologin) feature of agetty, everything from (4) 
> down is running as petituser. If you select "drop to shell" from the menu, you 
> then also do
> 
> 7. /home/petituser/.shrc (the $ENV set in .profile)
> 8. /bin/sh
> 
>>> If sudo is installed, with a sudoers policy allowing petituser to
>>> perform sudo with no password (or a blank password), the "drop to shell"
>>> feature of petitboot will automatically become a root shell.
>>
>> It seems to me that the logical thing to do would be to drop into an actual 
>> getty, which asks for a login and password.
> 
> At this point we're already running getty and (auto)logged in as
> petituser. The sudo integration allos system-specific flexibility in if/how the 
> the shell may be elevated. As petituser, the shell has permission to collect 
> diagnostics/logs by running pb-sos.

  I'm anyway wrong - getty or login are not setuid, they need to be executed as 
root, so petituser can't start them.

>>> --- a/package/petitboot/S15pb-discover
>>> +++ b/package/petitboot/S15pb-discover
>>> @@ -12,7 +12,9 @@ fi
>>>  start() {
>>>      printf 'Starting %s: ' "$DAEMON"
>>> -    mkdir -p /var/log/petitboot
>>> +    # shellcheck disable=SC2174 # only apply -m to deepest dir
>>> +    mkdir -p -m 0775 /var/log/petitboot
>>> +    chown root:petitgroup /var/log/petitboot
>>
>> Why is it owned by root and not petituser?
> 
> I don't see any reason why it couldn't be owned by petituser.
> 
>>> @@ -84,4 +88,12 @@ endef
>>>  PETITBOOT_POST_INSTALL_TARGET_HOOKS += PETITBOOT_POST_INSTALL
>>> +define PETITBOOT_USERS
>>> +    petituser -1 petitgroup -1 * /home/petituser /bin/sh - petitboot user
>>
>> Are petitgroup and petituser standard names? If not, we normally use the 
>> package name as username and group name, i.e.
>>
>>     petitboot -1 petitboot -1 ...
> 
> I think we could change petituser to petitboot, but there is a hardcoded 
> reference to petitgroup in the code:
> 
>    discover/discover-server.c:     group = getgrnam("petitgroup");

  Sounds like petitgroup is at least a standard name, and in that case petituser 
fits nicely (and I assume it is already used _somewhere_ at least). So OK to 
keep petituser/petitgroup. Please say something about this in the commit message 
(we want the history to show why we chose "petituser" rather than the more 
typical "petitboot" for the username).


>>> +define PETITBOOT_PERMISSIONS
>>> +    /var/petitboot d 775 root petitgroup - - - - -

  Given the information below, why is it in petitgroup? If pb-discover is just 
going to create directories there on which it can mount things, it's not very 
useful for pb-console to have write access to it, right? Unless pb-console needs 
to delete those directories or rename them?

>>
>> What is /var/petitboot used for?
> 
> That is where pb-discover mounts devices, looking for boot sources:
> 
>    /var/petitboot/mnt/dev/nvme0n1p1/grub2/grub.cfg
>    /var/petitboot/mnt/dev/nvme0n1p1/vmlinux

  Could you mention this in the commit message as well?

  The commit message is going to grow pretty large, but that's fine.

  Regards,
  Arnout
Reza Arbab Nov. 14, 2023, 3:25 p.m. UTC | #4
On Fri, Nov 10, 2023 at 10:01:25AM +0100, Arnout Vandecappelle wrote:
>On 09/11/2023 17:16, Reza Arbab wrote:
>>On Sun, Nov 05, 2023 at 07:26:16PM +0100, Arnout Vandecappelle wrote:
>>>It's also not clear why it would need agetty instead of busybox getty.
>>
>>Sorry, I didn't explain it very well. The chain goes like this:
>>
>>1. /etc/init.d/pb-console start console
>>2. /usr/libexec/petitboot/pb-console --getty --detach -- -n -i 0 console linux
>>3. /sbin/getty -l/usr/libexec/petitboot/pb-console -n -i 0 console linux
>>4. /usr/libexec/petitboot/pb-console
>>5. /usr/sbin/petiboot-nc
>>
>>After the change:
>>
>>1. /etc/init.d/pb-console start console
>>2. /usr/libexec/petitboot/pb-console --getty=/sbin/agetty --detach -- -a petituser -n -i console linux
>>3. /sbin/agetty -a petituser -n -i console linux
>
> How did the -l option disappear here? Is that due to --getty= instead of --getty?

Not because of --getty= exactly, but you've got the right idea. The 
script does not add -l if it sees -a.

> Anyway, the only reason to use agetty is for the -a option. Can't we 
>achieve the same by using su? I.e. create a wrapper script around 
>pb-console that does something like
>
>exec su -s /usr/libexec/petitboot/pb-console petituser

It's tricky. "pb-console --getty" runs getty which runs pb-console 
again, so at least that first invocation has be done as root. Instead of 
a wrapper, it can be made to work by adding this at the right place in 
pb-console:

     # If we're root, rerun as petituser
     if [ "$(id -u)" = "0" ]; then
	exec su -s "$0" petituser $@
     fi

I'm not sure if patching pb-console is preferable to depending on 
"agetty -a" and .profile?

>>4. /home/petituser/.profile
>
> Something I didn't touch in my earlier review: I don't think .profile 
>is the right place to set this up. Either petituser is a normal user - 
>in that case logging in through some other means (e.g. ssh, sudo) 
>should give a normal shell.

In .profile, I can do

     if [ "$PPID" = "1" ]; then
	exec /usr/libexec/petitboot/pb-console
     fi

so it only runs when petituser is logging in by getty/agetty and not 
through ssh or sudo.

>>>>+define PETITBOOT_PERMISSIONS
>>>>+    /var/petitboot d 775 root petitgroup - - - - -
>
> Given the information below, why is it in petitgroup? If pb-discover 
>is just going to create directories there on which it can mount 
>things, it's not very useful for pb-console to have write access to 
>it, right? Unless pb-console needs to delete those directories or 
>rename them?

You're right, I think /var/petitboot is really only used by pb-discover 
(root), so we can probably drop this.

I'll revise and split all this stuff into more than one patch so it's 
easier to understand when looking through the git log.
diff mbox series

Patch

diff --git a/package/petitboot/Config.in b/package/petitboot/Config.in
index 5f1d91e77ecb..0f965e71e628 100644
--- a/package/petitboot/Config.in
+++ b/package/petitboot/Config.in
@@ -16,6 +16,7 @@  config BR2_PACKAGE_PETITBOOT
 	select BR2_PACKAGE_KEXEC_LITE if ( BR2_powerpc || BR2_powerpc64 || BR2_powerpc64le )
 	select BR2_PACKAGE_NVME if ( BR2_powerpc || BR2_powerpc64 || BR2_powerpc64le )
 	select BR2_PACKAGE_POWERPC_UTILS if ( BR2_powerpc || BR2_powerpc64 || BR2_powerpc64le )
+	select BR2_PACKAGE_UTIL_LINUX_AGETTY
 	help
 	  Petitboot is a small kexec-based bootloader
 
diff --git a/package/petitboot/S15pb-discover b/package/petitboot/S15pb-discover
index 71ab62d99859..a37e33521f1a 100644
--- a/package/petitboot/S15pb-discover
+++ b/package/petitboot/S15pb-discover
@@ -12,7 +12,9 @@  fi
 
 start() {
 	printf 'Starting %s: ' "$DAEMON"
-	mkdir -p /var/log/petitboot
+	# shellcheck disable=SC2174 # only apply -m to deepest dir
+	mkdir -p -m 0775 /var/log/petitboot
+	chown root:petitgroup /var/log/petitboot
 
 	# shellcheck disable=SC2086 # we need the word splitting
 	start-stop-daemon -S -q -b -m -p "$PIDFILE" -x "/usr/sbin/$DAEMON" \
diff --git a/package/petitboot/pb-console b/package/petitboot/pb-console
index 407ff3b30232..eea40163d02f 100644
--- a/package/petitboot/pb-console
+++ b/package/petitboot/pb-console
@@ -3,14 +3,16 @@ 
 DAEMON="pb-console"
 
 PB_CONSOLE_PORT=${2:-"console"}
-PB_CONSOLE_ARGS="--getty --detach -- -n -i 0 $PB_CONSOLE_PORT linux"
+PB_CONSOLE_ARGS="--getty=/sbin/agetty --detach -- -a petituser -n -i $PB_CONSOLE_PORT linux"
 
 # shellcheck source=/dev/null
 [ -r "/etc/default/petitboot" ] && . "/etc/default/petitboot"
 
 start() {
 	printf 'Starting %s on %s: ' "$DAEMON" "$PB_CONSOLE_PORT"
-	mkdir -p /var/log/petitboot
+	# shellcheck disable=SC2174 # only apply -m to deepest dir
+	mkdir -p -m 0775 /var/log/petitboot
+	chown root:petitgroup /var/log/petitboot
 
 	# shellcheck disable=SC2086 # we need the word splitting
 	start-stop-daemon -S -q -x "/usr/libexec/petitboot/$DAEMON" \
diff --git a/package/petitboot/petitboot.mk b/package/petitboot/petitboot.mk
index ff87f3498734..5b517eb3b1a6 100644
--- a/package/petitboot/petitboot.mk
+++ b/package/petitboot/petitboot.mk
@@ -71,6 +71,10 @@  define PETITBOOT_POST_INSTALL
 		$(TARGET_DIR)/usr/sbin/kexec-restart
 	$(INSTALL) -D -m 0755 $(PETITBOOT_PKGDIR)/pb-console \
 		$(TARGET_DIR)/etc/init.d/pb-console
+	$(INSTALL) -D -m 0755 $(PETITBOOT_PKGDIR)/shell_config \
+		$(TARGET_DIR)/home/petituser/.shrc
+	$(INSTALL) -D -m 0755 $(PETITBOOT_PKGDIR)/shell_profile \
+		$(TARGET_DIR)/home/petituser/.profile
 
 	mkdir -p $(TARGET_DIR)/etc/udev/rules.d
 	(for port in $(PETITBOOT_GETTY_PORT); do \
@@ -84,4 +88,12 @@  endef
 
 PETITBOOT_POST_INSTALL_TARGET_HOOKS += PETITBOOT_POST_INSTALL
 
+define PETITBOOT_USERS
+	petituser -1 petitgroup -1 * /home/petituser /bin/sh - petitboot user
+endef
+
+define PETITBOOT_PERMISSIONS
+	/var/petitboot d 775 root petitgroup - - - - -
+endef
+
 $(eval $(autotools-package))
diff --git a/package/petitboot/shell_config b/package/petitboot/shell_config
new file mode 100644
index 000000000000..b10b95baae6c
--- /dev/null
+++ b/package/petitboot/shell_config
@@ -0,0 +1,24 @@ 
+#!/bin/sh
+
+try_sudo() {
+	[ -x "$(command -v sudo)" ] || return
+	sudo -K
+	echo | sudo -S /bin/true >/dev/null 2>&1 || return
+
+	echo "No password required, running as root."
+	sudo -i
+	sudo -K
+	exit
+}
+
+reset
+
+echo "Exiting petitboot. Type 'exit' to return."
+echo "You may run 'pb-sos' to gather diagnostic data."
+
+if [ "$(id -u)" != "0" ]; then
+	try_sudo
+	export PS1='$ '
+else
+	export PS1='# '
+fi
diff --git a/package/petitboot/shell_profile b/package/petitboot/shell_profile
new file mode 100644
index 000000000000..1ca5e6364dba
--- /dev/null
+++ b/package/petitboot/shell_profile
@@ -0,0 +1,2 @@ 
+export ENV="/home/petituser/.shrc"
+exec /usr/libexec/petitboot/pb-console