Обсуждение: [BUGS] BUG #14615: ReplicationOriginShmemInit Memory access cross-border

Поиск
Список
Период
Сортировка

[BUGS] BUG #14615: ReplicationOriginShmemInit Memory access cross-border

От
bret.shao@outlook.com
Дата:
The following bug has been logged on the website:

Bug reference:      14615
Logged by:          bret shao
Email address:      bret.shao@outlook.com
PostgreSQL version: 9.6.2
Operating system:   linux
Description:

MemSet(replication_states, 0, ReplicationOriginShmemSize()); in function
ReplicationOriginShmemInit cause cross-border,because that start address of
the share memory allocated is replication_states_ctl, but call MemSet to
initialize this memory start from replication_states which is variable
states's address in struct ReplicationStateCtl.so call MemSet to set 0 with
the total size of this share memory will cross border of this share memory.

Although, this cross-border will not caused the system failure due to share
memory allocation strategy after my analysis. but i still believe we
shouldn't do like this.

Fix suggestion: 
change to MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize()); then move
to the beginning of if statement.


--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Re: [BUGS] BUG #14615: ReplicationOriginShmemInit Memory access cross-border

От
Michael Paquier
Дата:
On Mon, Apr 10, 2017 at 3:26 PM,  <bret.shao@outlook.com> wrote:
> MemSet(replication_states, 0, ReplicationOriginShmemSize()); in function
> ReplicationOriginShmemInit cause cross-border,because that start address of
> the share memory allocated is replication_states_ctl, but call MemSet to
> initialize this memory start from replication_states which is variable
> states's address in struct ReplicationStateCtl.so call MemSet to set 0 with
> the total size of this share memory will cross border of this share memory.
>
> Although, this cross-border will not caused the system failure due to share
> memory allocation strategy after my analysis. but i still believe we
> shouldn't do like this.
>
> Fix suggestion:
> change to
>  MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize()); then move
> to the beginning of if statement.

Yes, there is a mistake here, but I don't agree with your solution. It
seems to me that using mul_size(max_replication_slots,
sizeof(ReplicationState)) is the way to go as you would reinitialize
what has been set in tranche_id. Per se the attached.
-- 
Michael

-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Вложения

[BUGS] 答复: [BUGS] BUG #14615: ReplicationOriginShmemInit Memory access cross-border

От
shao bret
Дата:

Hi Michael,

Thanks for your quickly response!

I think maybe you have a little misunderstanding with my solution.

 

My solution is that

      if (!found)

       {

              int                 i;

              MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize());

              replication_states_ctl->tranche_id = LWLockNewTrancheId();

              replication_states_ctl->tranche.name = "ReplicationOrigins";

              replication_states_ctl->tranche.array_base =

                     &replication_states[0].lock;

              replication_states_ctl->tranche.array_stride =

                     sizeof(ReplicationState);

 

              //MemSet(replication_states, 0, ReplicationOriginShmemSize());

 

              for (i = 0; i < max_replication_slots; i++)

                     LWLockInitialize(&replication_states[i].lock,

                                                 replication_states_ctl->tranche_id);

       }

So I think it’s easier for understanding code.

What do you think?

 

Thanks.

Bret

 

发送自 Windows 10 邮件应用

 

发件人: Michael Paquier
发送时间: 2017410 14:39
收件人: bret.shao@outlook.com
抄送: PostgreSQL mailing lists; Andres Freund
主题: Re: [BUGS] BUG #14615: ReplicationOriginShmemInit Memory access cross-border

 

On Mon, Apr 10, 2017 at 3:26 PM,  <bret.shao@outlook.com> wrote:
> MemSet(replication_states, 0, ReplicationOriginShmemSize()); in function
> ReplicationOriginShmemInit cause cross-border,because that start address of
> the share memory allocated is replication_states_ctl, but call MemSet to
> initialize this memory start from replication_states which is variable
> states's address in struct ReplicationStateCtl.so call MemSet to set 0 with
> the total size of this share memory will cross border of this share memory.
>
> Although, this cross-border will not caused the system failure due to share
> memory allocation strategy after my analysis. but i still believe we
> shouldn't do like this.
>
> Fix suggestion:
> change to
>  MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize()); then move
> to the beginning of if statement.

Yes, there is a mistake here, but I don't agree with your solution. It
seems to me that using mul_size(max_replication_slots,
sizeof(ReplicationState)) is the way to go as you would reinitialize
what has been set in tranche_id. Per se the attached.
--
Michael

 

[BUGS] Re: 答复: [BUGS] BUG #14615: ReplicationOriginShmemInit Memory access cross-border

От
Michael Paquier
Дата:
On Mon, Apr 10, 2017 at 4:02 PM, shao bret <bret.shao@outlook.com> wrote:
> I think maybe you have a little misunderstanding with my solution.

Without a proper patch it is hard to have a clear opinion in this case.

> My solution is that
> [...]
> So I think it’s easier for understanding code.
>
> What do you think?

One way or the other would be fine, at the end the last call will
likely come from Andres in CC as he is the author and committer of
replication origins. To be honest, I find the use of mul_size()
cleaner here, but that's just an opinion.
--
Michael


--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

[BUGS] 答复: 答复: [BUGS] BUG #14615: ReplicationOriginShmemInit Memory access cross-border

От
shao bret
Дата:

 

Please help to see the patch file.

Thanks.

Bret

 

发送自 Windows 10 邮件应用

 

发件人: Michael Paquier
发送时间: 2017411 11:05
收件人: shao bret
抄送: PostgreSQL mailing lists; Andres Freund
主题: Re: 答复: [BUGS] BUG #14615: ReplicationOriginShmemInit Memory access cross-border

 

On Mon, Apr 10, 2017 at 4:02 PM, shao bret <bret.shao@outlook.com> wrote:
> I think maybe you have a little misunderstanding with my solution.

Without a proper patch it is hard to have a clear opinion in this case.

> My solution is that
> [...]
> So I think it
s easier for understanding code.
>
> What do you think?

One way or the other would be fine, at the end the last call will
likely come from Andres in CC as he is the author and committer of
replication origins. To be honest, I find the use of mul_size()
cleaner here, but that's just an opinion.
--
Michael

 

Вложения

Re: [BUGS] BUG #14615: ReplicationOriginShmemInit Memory accesscross-border

От
Andres Freund
Дата:
On 2017-04-10 15:38:56 +0900, Michael Paquier wrote:
> diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
> index 5eaf863e02..0aa468789c 100644
> --- a/src/backend/replication/logical/origin.c
> +++ b/src/backend/replication/logical/origin.c
> @@ -473,7 +473,8 @@ ReplicationOriginShmemInit(void)
>  
>          replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN;
>  
> -        MemSet(replication_states, 0, ReplicationOriginShmemSize());
> +        MemSet(replication_states, 0,
> +               mul_size(max_replication_slots, sizeof(ReplicationState)));

What's the benefit of using mul_size here?  That's usually only
beneficial in the original size computation - during use/initialization
an actual error should be impossible.

To me the right fix seems to be to just do:
-        replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN;
-
-        MemSet(replication_states, 0, ReplicationOriginShmemSize());
+        MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize());
+
+        replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN;

No?

Greetings,

Andres Freund


-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Re: [BUGS] 答复: [BUGS] BUG #14615: ReplicationOriginShmemInit Memory access cross-border

От
Andres Freund
Дата:
On 2017-04-10 07:02:06 +0000, shao bret wrote:
> Hi Michael,
> Thanks for your quickly response!
> I think maybe you have a little misunderstanding with my solution.
> 
> My solution is that
>       if (!found)
>        {
>               int                 i;
>               MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize());
>               replication_states_ctl->tranche_id = LWLockNewTrancheId();
>               replication_states_ctl->tranche.name = "ReplicationOrigins";
>               replication_states_ctl->tranche.array_base =
>                      &replication_states[0].lock;
>               replication_states_ctl->tranche.array_stride =
>                      sizeof(ReplicationState);
> 
>               //MemSet(replication_states, 0, ReplicationOriginShmemSize());
> 
>               for (i = 0; i < max_replication_slots; i++)
>                      LWLockInitialize(&replication_states[i].lock,
>                                                  replication_states_ctl->tranche_id);
>        }
> So I think it’s easier for understanding code.
> What do you think?

That's imo just more work to maintain if additional fields added.

- Andres


-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Re: [BUGS] BUG #14615: ReplicationOriginShmemInit Memory access cross-border

От
Michael Paquier
Дата:
On Wed, Apr 12, 2017 at 12:20 AM, Andres Freund <andres@anarazel.de> wrote:
> On 2017-04-10 15:38:56 +0900, Michael Paquier wrote:
>> diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
>> index 5eaf863e02..0aa468789c 100644
>> --- a/src/backend/replication/logical/origin.c
>> +++ b/src/backend/replication/logical/origin.c
>> @@ -473,7 +473,8 @@ ReplicationOriginShmemInit(void)
>>
>>               replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN;
>>
>> -             MemSet(replication_states, 0, ReplicationOriginShmemSize());
>> +             MemSet(replication_states, 0,
>> +                        mul_size(max_replication_slots, sizeof(ReplicationState)));
>
> What's the benefit of using mul_size here?  That's usually only
> beneficial in the original size computation - during use/initialization
> an actual error should be impossible.

Clarity in initializing only the replication states.

> To me the right fix seems to be to just do:
> -               replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN;
> -
> -               MemSet(replication_states, 0, ReplicationOriginShmemSize());
> +               MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize());
> +
> +               replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN;
>
> No?

That's what Bret is proposing. I am fine either way.
-- 
Michael


-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Hi Andres,

 

Yes, your solution is same with my.  I have attached the patch file in former email.

Sorry for my mistake for this code. This code is come from 9.5.3.  after that ,I create a patch file using 9.6.2.

The attachment is the email.

>if (!found)
>        {
>               int                 i;
>               MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize());
>               replication_states_ctl->tranche_id = LWLockNewTrancheId();
>               replication_states_ctl->tranche.name = "ReplicationOrigins";
>               replication_states_ctl->tranche.array_base =
>                      &replication_states[0].lock;
>               replication_states_ctl->tranche.array_stride =
>                      sizeof(ReplicationState);
>
>               //MemSet(replication_states, 0, ReplicationOriginShmemSize());
>
>               for (i = 0; i < max_replication_slots; i++)
>                      LWLockInitialize(&replication_states[i].lock,
>                                                  replication_states_ctl->tranche_id);
>        }

 

Thanks

Bret

 

发送自 Windows 10 邮件应用

 

发件人: Andres Freund
发送时间: 2017411 23:22
收件人: shao bret
抄送: Michael Paquier; PostgreSQL mailing lists
主题: Re: [BUGS] 答复: [BUGS] BUG #14615: ReplicationOriginShmemInit Memory access cross-border

 

On 2017-04-10 07:02:06 +0000, shao bret wrote:
> Hi Michael,
> Thanks for your quickly response!
> I think maybe you have a little misunderstanding with my solution.
>
> My solution is that
>       if (!found)
>        {
>               int                 i;
>               MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize());
>               replication_states_ctl->tranche_id = LWLockNewTrancheId();
>               replication_states_ctl->tranche.name = "ReplicationOrigins";
>               replication_states_ctl->tranche.array_base =
>                      &replication_states[0].lock;
>               replication_states_ctl->tranche.array_stride =
>                      sizeof(ReplicationState);
>
>               //MemSet(replication_states, 0, ReplicationOriginShmemSize());
>
>               for (i = 0; i < max_replication_slots; i++)
>                      LWLockInitialize(&replication_states[i].lock,
>                                                  replication_states_ctl->tranche_id);
>        }
> So I think it
s easier for understanding code.
> What do you think?

That's imo just more work to maintain if additional fields added.

- Andres

 

Вложения