Message ID | 20240807195119.it.782-kees@kernel.org (mailing list archive) |
---|---|
State | Mainlined |
Commit | 3eb3cd5992f7a0c37edc8d05b4c38c98758d8671 |
Headers | show |
Series | [v2] binfmt_flat: Fix corruption when not offsetting data start | expand |
On 2024/08/07 12:51, Kees Cook wrote: > Commit 04d82a6d0881 ("binfmt_flat: allow not offsetting data start") > introduced a RISC-V specific variant of the FLAT format which does > not allocate any space for the (obsolete) array of shared library > pointers. However, it did not disable the code which initializes the > array, resulting in the corruption of sizeof(long) bytes before the DATA > segment, generally the end of the TEXT segment. > > Introduce MAX_SHARED_LIBS_UPDATE which depends on the state of > CONFIG_BINFMT_FLAT_NO_DATA_START_OFFSET to guard the initialization of > the shared library pointer region so that it will only be initialized > if space is reserved for it. > > Fixes: 04d82a6d0881 ("binfmt_flat: allow not offsetting data start") > Co-developed-by: Stefan O'Rear <sorear@fastmail.com> > Signed-off-by: Stefan O'Rear <sorear@fastmail.com> > Signed-off-by: Kees Cook <kees@kernel.org> Looks good to me. Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Hi Kees, On 8/8/24 05:51, Kees Cook wrote: > Commit 04d82a6d0881 ("binfmt_flat: allow not offsetting data start") > introduced a RISC-V specific variant of the FLAT format which does > not allocate any space for the (obsolete) array of shared library > pointers. However, it did not disable the code which initializes the > array, resulting in the corruption of sizeof(long) bytes before the DATA > segment, generally the end of the TEXT segment. > > Introduce MAX_SHARED_LIBS_UPDATE which depends on the state of > CONFIG_BINFMT_FLAT_NO_DATA_START_OFFSET to guard the initialization of > the shared library pointer region so that it will only be initialized > if space is reserved for it. > > Fixes: 04d82a6d0881 ("binfmt_flat: allow not offsetting data start") > Co-developed-by: Stefan O'Rear <sorear@fastmail.com> > Signed-off-by: Stefan O'Rear <sorear@fastmail.com> > Signed-off-by: Kees Cook <kees@kernel.org> Looks good. Acked-by: Greg Ungerer <gerg@linux-m68k.org> Regards Greg > --- > v2: update based on v1 feedback > v1: https://lore.kernel.org/linux-mm/20240326032037.2478816-1-sorear@fastmail.com/ > Cc: Palmer Dabbelt <palmer@dabbelt.com> > Cc: Alexandre Ghiti <alex@ghiti.fr> > Cc: Greg Ungerer <gerg@linux-m68k.org> > Cc: Damien Le Moal <dlemoal@kernel.org> > Cc: Alexander Viro <viro@zeniv.linux.org.uk> > Cc: Christian Brauner <brauner@kernel.org> > Cc: Jan Kara <jack@suse.cz> > Cc: Eric Biederman <ebiederm@xmission.com> > Cc: linux-fsdevel@vger.kernel.org > Cc: linux-mm@kvack.org > --- > fs/binfmt_flat.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c > index c26545d71d39..cd6d5bbb4b9d 100644 > --- a/fs/binfmt_flat.c > +++ b/fs/binfmt_flat.c > @@ -72,8 +72,10 @@ > > #ifdef CONFIG_BINFMT_FLAT_NO_DATA_START_OFFSET > #define DATA_START_OFFSET_WORDS (0) > +#define MAX_SHARED_LIBS_UPDATE (0) > #else > #define DATA_START_OFFSET_WORDS (MAX_SHARED_LIBS) > +#define MAX_SHARED_LIBS_UPDATE (MAX_SHARED_LIBS) > #endif > > struct lib_info { > @@ -880,7 +882,7 @@ static int load_flat_binary(struct linux_binprm *bprm) > return res; > > /* Update data segment pointers for all libraries */ > - for (i = 0; i < MAX_SHARED_LIBS; i++) { > + for (i = 0; i < MAX_SHARED_LIBS_UPDATE; i++) { > if (!libinfo.lib_list[i].loaded) > continue; > for (j = 0; j < MAX_SHARED_LIBS; j++) {
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index c26545d71d39..cd6d5bbb4b9d 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -72,8 +72,10 @@ #ifdef CONFIG_BINFMT_FLAT_NO_DATA_START_OFFSET #define DATA_START_OFFSET_WORDS (0) +#define MAX_SHARED_LIBS_UPDATE (0) #else #define DATA_START_OFFSET_WORDS (MAX_SHARED_LIBS) +#define MAX_SHARED_LIBS_UPDATE (MAX_SHARED_LIBS) #endif struct lib_info { @@ -880,7 +882,7 @@ static int load_flat_binary(struct linux_binprm *bprm) return res; /* Update data segment pointers for all libraries */ - for (i = 0; i < MAX_SHARED_LIBS; i++) { + for (i = 0; i < MAX_SHARED_LIBS_UPDATE; i++) { if (!libinfo.lib_list[i].loaded) continue; for (j = 0; j < MAX_SHARED_LIBS; j++) {