diff mbox series

[meta,classes] sed -i destroys symlinks

Message ID 20231108105644.2884585-1-joakim.tjernlund@infinera.com
State New
Headers show
Series [meta,classes] sed -i destroys symlinks | expand

Commit Message

Joakim Tjernlund Nov. 8, 2023, 10:56 a.m. UTC
If /etc/passwd is a symlink, sed -i on same file will replace the
symlink with a new file. Prevent that by expanding the file with realpath
before giving it to sed.

Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
---

 - I have patches which moves shadow/passwd files to an subdir in order to
   have passwd mgmt on a RO RFS. Is there a interest to have that oprion in OE?
   
 meta/classes/rootfs-postcommands.bbclass | 4 ++--
 meta/classes/useradd_base.bbclass        | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

Comments

Jose Quaresma Nov. 8, 2023, 11:22 a.m. UTC | #1
Hi Joakim,

Joakim Tjernlund via lists.openembedded.org <Joakim.Tjernlund=
infinera.com@lists.openembedded.org> escreveu no dia quarta, 8/11/2023 à(s)
10:56:

> If /etc/passwd is a symlink, sed -i on same file will replace the
> symlink with a new file. Prevent that by expanding the file with realpath
> before giving it to sed.
>

The sed follow-symlinks argument looks more appropriate for this imo.

--follow-symlinks
This option is available only on platforms that support symbolic links and
has an effect only if option -i is specified. In this case, if the file
that is specified on the command line is a symbolic link, sed will follow
the link and edit the ultimate destination of the link. The default
behavior is to break the symbolic link, so that the link destination will
not be modified.

https://www.gnu.org/software/sed/manual/html_node/Command_002dLine-Options.html

Jose


> Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
> ---
>
>  - I have patches which moves shadow/passwd files to an subdir in order to
>    have passwd mgmt on a RO RFS. Is there a interest to have that oprion
> in OE?
>
>  meta/classes/rootfs-postcommands.bbclass | 4 ++--
>  meta/classes/useradd_base.bbclass        | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/meta/classes/rootfs-postcommands.bbclass
> b/meta/classes/rootfs-postcommands.bbclass
> index 5c0b3ec37c..55cc863dbf 100644
> --- a/meta/classes/rootfs-postcommands.bbclass
> +++ b/meta/classes/rootfs-postcommands.bbclass
> @@ -148,10 +148,10 @@ read_only_rootfs_hook () {
>  #
>  zap_empty_root_password () {
>         if [ -e ${IMAGE_ROOTFS}/etc/shadow ]; then
> -               sed -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/shadow
> +               sed -i 's%^root::%root:*:%' $(realpath
> ${IMAGE_ROOTFS}/etc/shadow)
>          fi
>         if [ -e ${IMAGE_ROOTFS}/etc/passwd ]; then
> -               sed -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/passwd
> +               sed -i 's%^root::%root:*:%' $(realpath
> ${IMAGE_ROOTFS}/etc/passwd)
>         fi
>  }
>
> diff --git a/meta/classes/useradd_base.bbclass
> b/meta/classes/useradd_base.bbclass
> index 7f5b9b7219..72732a4d57 100644
> --- a/meta/classes/useradd_base.bbclass
> +++ b/meta/classes/useradd_base.bbclass
> @@ -154,7 +154,7 @@ perform_passwd_expire () {
>         local username=`echo "$opts" | awk '{ print $NF }'`
>         local user_exists="`grep "^$username:" $rootdir/etc/passwd ||
> true`"
>         if test "x$user_exists" != "x"; then
> -               eval flock -x $rootdir${sysconfdir} -c \"$PSEUDO sed -i
> \''s/^\('$username':[^:]*\):[^:]*:/\1:0:/'\' $rootdir/etc/shadow \" || true
> +               eval flock -x $rootdir${sysconfdir} -c \"$PSEUDO sed -i
> \''s/^\('$username':[^:]*\):[^:]*:/\1:0:/'\' $(realpath
> $rootdir/etc/shadow) \" || true
>                 local passwd_lastchanged="`grep "^$username:"
> $rootdir/etc/shadow | cut -d: -f3`"
>                 if test "x$passwd_lastchanged" != "x0"; then
>                         bbfatal "${PN}: passwd --expire operation did not
> succeed."
> --
> 2.41.0
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#190315):
> https://lists.openembedded.org/g/openembedded-core/message/190315
> Mute This Topic: https://lists.openembedded.org/mt/102461303/5052612
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [
> quaresma.jose@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
>
Joakim Tjernlund Nov. 8, 2023, 11:50 a.m. UTC | #2
On Wed, 2023-11-08 at 11:22 +0000, Jose Quaresma wrote:
Hi Joakim,

Joakim Tjernlund via lists.openembedded.org<http://lists.openembedded.org/> <Joakim.Tjernlund=infinera.com@lists.openembedded.org<mailto:infinera.com@lists.openembedded.org>> escreveu no dia quarta, 8/11/2023 à(s) 10:56:
If /etc/passwd is a symlink, sed -i on same file will replace the
symlink with a new file. Prevent that by expanding the file with realpath
before giving it to sed.


The sed follow-symlinks argument looks more appropriate for this imo.


But not all sed impl. support that option(not busybox for one). Is Gnu sed an requirement here?


--follow-symlinks
This option is available only on platforms that support symbolic links and has an effect only if option -i is specified. In this case, if the file that is specified on the command line is a symbolic link, sed will follow the link and edit the ultimate destination of the link. The default behavior is to break the symbolic link, so that the link destination will not be modified.

https://www.gnu.org/software/sed/manual/html_node/Command_002dLine-Options.html

Jose


Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com<mailto:joakim.tjernlund@infinera.com>>
---

 - I have patches which moves shadow/passwd files to an subdir in order to
   have passwd mgmt on a RO RFS. Is there a interest to have that oprion in OE?

 meta/classes/rootfs-postcommands.bbclass | 4 ++--
 meta/classes/useradd_base.bbclass        | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/meta/classes/rootfs-postcommands.bbclass b/meta/classes/rootfs-postcommands.bbclass
index 5c0b3ec37c..55cc863dbf 100644
--- a/meta/classes/rootfs-postcommands.bbclass
+++ b/meta/classes/rootfs-postcommands.bbclass
@@ -148,10 +148,10 @@ read_only_rootfs_hook () {
 #
 zap_empty_root_password () {
        if [ -e ${IMAGE_ROOTFS}/etc/shadow ]; then
-               sed -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/shadow
+               sed -i 's%^root::%root:*:%' $(realpath ${IMAGE_ROOTFS}/etc/shadow)
         fi
        if [ -e ${IMAGE_ROOTFS}/etc/passwd ]; then
-               sed -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/passwd
+               sed -i 's%^root::%root:*:%' $(realpath ${IMAGE_ROOTFS}/etc/passwd)
        fi
 }

diff --git a/meta/classes/useradd_base.bbclass b/meta/classes/useradd_base.bbclass
index 7f5b9b7219..72732a4d57 100644
--- a/meta/classes/useradd_base.bbclass
+++ b/meta/classes/useradd_base.bbclass
@@ -154,7 +154,7 @@ perform_passwd_expire () {
        local username=`echo "$opts" | awk '{ print $NF }'`
        local user_exists="`grep "^$username:" $rootdir/etc/passwd || true`"
        if test "x$user_exists" != "x"; then
-               eval flock -x $rootdir${sysconfdir} -c \"$PSEUDO sed -i \''s/^\('$username':[^:]*\):[^:]*:/\1:0:/'\' $rootdir/etc/shadow \" || true
+               eval flock -x $rootdir${sysconfdir} -c \"$PSEUDO sed -i \''s/^\('$username':[^:]*\):[^:]*:/\1:0:/'\' $(realpath $rootdir/etc/shadow) \" || true
                local passwd_lastchanged="`grep "^$username:" $rootdir/etc/shadow | cut -d: -f3`"
                if test "x$passwd_lastchanged" != "x0"; then
                        bbfatal "${PN}: passwd --expire operation did not succeed."
Jose Quaresma Nov. 8, 2023, 1:17 p.m. UTC | #3
Joakim Tjernlund <Joakim.Tjernlund@infinera.com> escreveu no dia quarta,
8/11/2023 à(s) 11:50:

> On Wed, 2023-11-08 at 11:22 +0000, Jose Quaresma wrote:
>
> Hi Joakim,
>
> Joakim Tjernlund via lists.openembedded.org <Joakim.Tjernlund=
> infinera.com@lists.openembedded.org> escreveu no dia quarta, 8/11/2023
> à(s) 10:56:
>
> If /etc/passwd is a symlink, sed -i on same file will replace the
> symlink with a new file. Prevent that by expanding the file with realpath
> before giving it to sed.
>
>
> The sed follow-symlinks argument looks more appropriate for this imo.
>
>
>
> But not all sed impl. support that option(not busybox for one). Is Gnu sed
> an requirement here?
>

On the target we can use the sed from busybox but on the build host we use
the native sed which is the gnu.


>
>
> --follow-symlinks
> This option is available only on platforms that support symbolic links and
> has an effect only if option -i is specified. In this case, if the file
> that is specified on the command line is a symbolic link, sed will follow
> the link and edit the ultimate destination of the link. The default
> behavior is to break the symbolic link, so that the link destination will
> not be modified.
>
>
> https://www.gnu.org/software/sed/manual/html_node/Command_002dLine-Options.html
>
> Jose
>
>
> Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
> ---
>
>  - I have patches which moves shadow/passwd files to an subdir in order to
>    have passwd mgmt on a RO RFS. Is there a interest to have that oprion
> in OE?
>
>  meta/classes/rootfs-postcommands.bbclass | 4 ++--
>  meta/classes/useradd_base.bbclass        | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/meta/classes/rootfs-postcommands.bbclass
> b/meta/classes/rootfs-postcommands.bbclass
> index 5c0b3ec37c..55cc863dbf 100644
> --- a/meta/classes/rootfs-postcommands.bbclass
> +++ b/meta/classes/rootfs-postcommands.bbclass
> @@ -148,10 +148,10 @@ read_only_rootfs_hook () {
>  #
>  zap_empty_root_password () {
>         if [ -e ${IMAGE_ROOTFS}/etc/shadow ]; then
> -               sed -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/shadow
> +               sed -i 's%^root::%root:*:%' $(realpath
> ${IMAGE_ROOTFS}/etc/shadow)
>          fi
>         if [ -e ${IMAGE_ROOTFS}/etc/passwd ]; then
> -               sed -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/passwd
> +               sed -i 's%^root::%root:*:%' $(realpath
> ${IMAGE_ROOTFS}/etc/passwd)
>         fi
>  }
>
> diff --git a/meta/classes/useradd_base.bbclass
> b/meta/classes/useradd_base.bbclass
> index 7f5b9b7219..72732a4d57 100644
> --- a/meta/classes/useradd_base.bbclass
> +++ b/meta/classes/useradd_base.bbclass
> @@ -154,7 +154,7 @@ perform_passwd_expire () {
>         local username=`echo "$opts" | awk '{ print $NF }'`
>         local user_exists="`grep "^$username:" $rootdir/etc/passwd ||
> true`"
>         if test "x$user_exists" != "x"; then
> -               eval flock -x $rootdir${sysconfdir} -c \"$PSEUDO sed -i
> \''s/^\('$username':[^:]*\):[^:]*:/\1:0:/'\' $rootdir/etc/shadow \" || true
> +               eval flock -x $rootdir${sysconfdir} -c \"$PSEUDO sed -i
> \''s/^\('$username':[^:]*\):[^:]*:/\1:0:/'\' $(realpath
> $rootdir/etc/shadow) \" || true
>                 local passwd_lastchanged="`grep "^$username:"
> $rootdir/etc/shadow | cut -d: -f3`"
>                 if test "x$passwd_lastchanged" != "x0"; then
>                         bbfatal "${PN}: passwd --expire operation did not
> succeed."
>
>
>
Joakim Tjernlund Nov. 8, 2023, 1:27 p.m. UTC | #4
On Wed, 2023-11-08 at 13:17 +0000, Jose Quaresma wrote:


Joakim Tjernlund <Joakim.Tjernlund@infinera.com<mailto:Joakim.Tjernlund@infinera.com>> escreveu no dia quarta, 8/11/2023 à(s) 11:50:
On Wed, 2023-11-08 at 11:22 +0000, Jose Quaresma wrote:
Hi Joakim,

Joakim Tjernlund via lists.openembedded.org<http://lists.openembedded.org/> <Joakim.Tjernlund=infinera.com@lists.openembedded.org<mailto:infinera.com@lists.openembedded.org>> escreveu no dia quarta, 8/11/2023 à(s) 10:56:
If /etc/passwd is a symlink, sed -i on same file will replace the
symlink with a new file. Prevent that by expanding the file with realpath
before giving it to sed.


The sed follow-symlinks argument looks more appropriate for this imo.


But not all sed impl. support that option(not busybox for one). Is Gnu sed an requirement here?


On the target we can use the sed from busybox but on the build host we use the native sed which is the gnu.

Great! These scripts are always native so then we can assume GNU sed.

However, I guess there are cases where it not easy to known which sed is used, do we want to
have two different ways for this?

   Joakim




--follow-symlinks
This option is available only on platforms that support symbolic links and has an effect only if option -i is specified. In this case, if the file that is specified on the command line is a symbolic link, sed will follow the link and edit the ultimate destination of the link. The default behavior is to break the symbolic link, so that the link destination will not be modified.

https://www.gnu.org/software/sed/manual/html_node/Command_002dLine-Options.html

Jose


Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com<mailto:joakim.tjernlund@infinera.com>>
---

 - I have patches which moves shadow/passwd files to an subdir in order to
   have passwd mgmt on a RO RFS. Is there a interest to have that oprion in OE?

 meta/classes/rootfs-postcommands.bbclass | 4 ++--
 meta/classes/useradd_base.bbclass        | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/meta/classes/rootfs-postcommands.bbclass b/meta/classes/rootfs-postcommands.bbclass
index 5c0b3ec37c..55cc863dbf 100644
--- a/meta/classes/rootfs-postcommands.bbclass
+++ b/meta/classes/rootfs-postcommands.bbclass
@@ -148,10 +148,10 @@ read_only_rootfs_hook () {
 #
 zap_empty_root_password () {
        if [ -e ${IMAGE_ROOTFS}/etc/shadow ]; then
-               sed -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/shadow
+               sed -i 's%^root::%root:*:%' $(realpath ${IMAGE_ROOTFS}/etc/shadow)
         fi
        if [ -e ${IMAGE_ROOTFS}/etc/passwd ]; then
-               sed -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/passwd
+               sed -i 's%^root::%root:*:%' $(realpath ${IMAGE_ROOTFS}/etc/passwd)
        fi
 }

diff --git a/meta/classes/useradd_base.bbclass b/meta/classes/useradd_base.bbclass
index 7f5b9b7219..72732a4d57 100644
--- a/meta/classes/useradd_base.bbclass
+++ b/meta/classes/useradd_base.bbclass
@@ -154,7 +154,7 @@ perform_passwd_expire () {
        local username=`echo "$opts" | awk '{ print $NF }'`
        local user_exists="`grep "^$username:" $rootdir/etc/passwd || true`"
        if test "x$user_exists" != "x"; then
-               eval flock -x $rootdir${sysconfdir} -c \"$PSEUDO sed -i \''s/^\('$username':[^:]*\):[^:]*:/\1:0:/'\' $rootdir/etc/shadow \" || true
+               eval flock -x $rootdir${sysconfdir} -c \"$PSEUDO sed -i \''s/^\('$username':[^:]*\):[^:]*:/\1:0:/'\' $(realpath $rootdir/etc/shadow) \" || true
                local passwd_lastchanged="`grep "^$username:" $rootdir/etc/shadow | cut -d: -f3`"
                if test "x$passwd_lastchanged" != "x0"; then
                        bbfatal "${PN}: passwd --expire operation did not succeed."



--
Best regards,

José Quaresma
diff mbox series

Patch

diff --git a/meta/classes/rootfs-postcommands.bbclass b/meta/classes/rootfs-postcommands.bbclass
index 5c0b3ec37c..55cc863dbf 100644
--- a/meta/classes/rootfs-postcommands.bbclass
+++ b/meta/classes/rootfs-postcommands.bbclass
@@ -148,10 +148,10 @@  read_only_rootfs_hook () {
 #
 zap_empty_root_password () {
 	if [ -e ${IMAGE_ROOTFS}/etc/shadow ]; then
-		sed -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/shadow
+		sed -i 's%^root::%root:*:%' $(realpath ${IMAGE_ROOTFS}/etc/shadow)
         fi
 	if [ -e ${IMAGE_ROOTFS}/etc/passwd ]; then
-		sed -i 's%^root::%root:*:%' ${IMAGE_ROOTFS}/etc/passwd
+		sed -i 's%^root::%root:*:%' $(realpath ${IMAGE_ROOTFS}/etc/passwd)
 	fi
 }
 
diff --git a/meta/classes/useradd_base.bbclass b/meta/classes/useradd_base.bbclass
index 7f5b9b7219..72732a4d57 100644
--- a/meta/classes/useradd_base.bbclass
+++ b/meta/classes/useradd_base.bbclass
@@ -154,7 +154,7 @@  perform_passwd_expire () {
 	local username=`echo "$opts" | awk '{ print $NF }'`
 	local user_exists="`grep "^$username:" $rootdir/etc/passwd || true`"
 	if test "x$user_exists" != "x"; then
-		eval flock -x $rootdir${sysconfdir} -c \"$PSEUDO sed -i \''s/^\('$username':[^:]*\):[^:]*:/\1:0:/'\' $rootdir/etc/shadow \" || true
+		eval flock -x $rootdir${sysconfdir} -c \"$PSEUDO sed -i \''s/^\('$username':[^:]*\):[^:]*:/\1:0:/'\' $(realpath $rootdir/etc/shadow) \" || true
 		local passwd_lastchanged="`grep "^$username:" $rootdir/etc/shadow | cut -d: -f3`"
 		if test "x$passwd_lastchanged" != "x0"; then
 			bbfatal "${PN}: passwd --expire operation did not succeed."