Hi,

On Wed, Aug 27, 2025 at 02:13:39PM -0500, Sami Imseih wrote:
> Thanks for reviewing!
> 
> > === 1
> >
> > We need to check if tranche_name is NULL and report an error if that's the 
> > case.
> > If not, strlen() would segfault.
> 
> Added an error. Good call. The error message follows previously used
> convention.
> 
> ```
> +       if (!tranche_name)
> +               elog(ERROR, "tranche name cannot be null");
> ```

+LWLockNewTrancheId(const char *tranche_name)
 {
-       int                     result;
-       int                *LWLockCounter;
+       int                     tranche_id,
+                               index,
+                          *LWLockCounter;
+       Size            tranche_name_length = strlen(tranche_name) + 1;

-       LWLockCounter = (int *) ((char *) MainLWLockArray - sizeof(int));
-       /* We use the ShmemLock spinlock to protect LWLockCounter */
-       SpinLockAcquire(ShmemLock);
-       result = (*LWLockCounter)++;
-       SpinLockRelease(ShmemLock);
+       if (!tranche_name)
+               elog(ERROR, "tranche name cannot be null");

The check has to be done before the strlen() call, if not it segfault:

Breakpoint 1, LWLockNewTrancheId (tranche_name=0x0) at lwlock.c:569
569             Size            tranche_name_length = strlen(tranche_name) + 1;
(gdb) n

Program received signal SIGSEGV, Segmentation fault.

> > === 2
> >
> > +       if (tranche_name_length > MAX_NAMED_TRANCHES_NAME_LEN)
> > +               elog(ERROR, "tranche name too long");
> >
> > I think that we should mention in the doc that the tranche name is limited 
> > to
> > 63 bytes.
> 
> Done. I just mentioned NAMEDATALEN -1 in the docs.

Most of the places where NAMEDATALEN is mentioned in sgml files also mention
it's 64 bytes. Should we do the same here?

> > === 3
> >
> > I was skeptical about using strcpy() while we hold a spinlock. I do see some
> > examples with strlcpy() though (walreceiver.c for example), so that looks 
> > OK-ish.
> >
> > Using strcpy() might be OK too, as we already have validated the length, 
> > but maybe
> > it would be safer to switch to strlcpy(), instead?
> 
> OK, since that is the pattern used, I changed to strlcpy. But since we are 
> doing
> checks in advance, I think it will be safe either way.

Agree.

- * stores the names of all dynamically-created tranches known to the current
- * process.  Any unused entries in the array will contain NULL.
+ * stores the names of all dynamically created tranches in shared memory.
+ * Any unused entries in the array will contain NULL. This variable is
+ * non-static so that postmaster.c can copy it to child processes in
+ * EXEC_BACKEND builds.

"Any unused entries in the array will contain NULL": this is not true anymore.
It now contains empty strings:

(gdb) p *(char(*)[64])NamedLWLockTrancheArray@4
$5 = {"tutu", '\000' <repeats 59 times>, '\000' <repeats 63 times>, '\000' 
<repeats 63 times>, '\000' <repeats 63 times>}

Regards,

-- 
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com


Reply via email to