Skip to content

Commit f14cf36

Browse files
committed
(perl #131746) avoid undefined behaviour in Copy() etc
These functions depend on C library functions which have undefined behaviour when passed NULL pointers, even when passed a zero 'n' value. Some compilers use this information, ie. assume the pointers are non-NULL when optimizing any following code, so we do need to prevent such unguarded calls. My initial thought was to add conditionals to each macro to skip the call to the library function when n is zero, but this adds a cost to every use of these macros, even when the n value is always true. So instead I added asserts() which will give us a much more visible indicator of such broken code and revealed the pp_caller and Glob.xs issues also patched here.
1 parent 011c35b commit f14cf36

File tree

5 files changed

+13
-11
lines changed

5 files changed

+13
-11
lines changed

ext/File-Glob/Glob.pm

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pop @{$EXPORT_TAGS{bsd_glob}}; # no "glob"
3737

3838
@EXPORT_OK = (@{$EXPORT_TAGS{'glob'}}, 'csh_glob');
3939

40-
$VERSION = '1.29';
40+
$VERSION = '1.30';
4141

4242
sub import {
4343
require Exporter;

ext/File-Glob/Glob.xs

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ iterate(pTHX_ bool(*globber)(pTHX_ AV *entries, const char *pat, STRLEN len, boo
121121

122122
/* chuck it all out, quick or slow */
123123
if (gimme == G_ARRAY) {
124-
if (!on_stack) {
124+
if (!on_stack && AvFILLp(entries) + 1) {
125125
EXTEND(SP, AvFILLp(entries)+1);
126126
Copy(AvARRAY(entries), SP+1, AvFILLp(entries)+1, SV *);
127127
SP += AvFILLp(entries)+1;

handy.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -2409,17 +2409,17 @@ void Perl_mem_log_del_sv(const SV *sv, const char *filename, const int linenumbe
24092409
#define Safefree(d) safefree(MEM_LOG_FREE((Malloc_t)(d)))
24102410
#endif
24112411

2412-
#define Move(s,d,n,t) (MEM_WRAP_CHECK_(n,t) (void)memmove((char*)(d),(const char*)(s), (n) * sizeof(t)))
2413-
#define Copy(s,d,n,t) (MEM_WRAP_CHECK_(n,t) (void)memcpy((char*)(d),(const char*)(s), (n) * sizeof(t)))
2414-
#define Zero(d,n,t) (MEM_WRAP_CHECK_(n,t) (void)memzero((char*)(d), (n) * sizeof(t)))
2412+
#define Move(s,d,n,t) (MEM_WRAP_CHECK_(n,t) assert(d), assert(s), (void)memmove((char*)(d),(const char*)(s), (n) * sizeof(t)))
2413+
#define Copy(s,d,n,t) (MEM_WRAP_CHECK_(n,t) assert(d), assert(s), (void)memcpy((char*)(d),(const char*)(s), (n) * sizeof(t)))
2414+
#define Zero(d,n,t) (MEM_WRAP_CHECK_(n,t) assert(d), (void)memzero((char*)(d), (n) * sizeof(t)))
24152415

2416-
#define MoveD(s,d,n,t) (MEM_WRAP_CHECK_(n,t) memmove((char*)(d),(const char*)(s), (n) * sizeof(t)))
2417-
#define CopyD(s,d,n,t) (MEM_WRAP_CHECK_(n,t) memcpy((char*)(d),(const char*)(s), (n) * sizeof(t)))
2416+
#define MoveD(s,d,n,t) (MEM_WRAP_CHECK_(n,t) assert(d), assert(s), memmove((char*)(d),(const char*)(s), (n) * sizeof(t)))
2417+
#define CopyD(s,d,n,t) (MEM_WRAP_CHECK_(n,t) assert(d), assert(s), memcpy((char*)(d),(const char*)(s), (n) * sizeof(t)))
24182418
#ifdef HAS_MEMSET
2419-
#define ZeroD(d,n,t) (MEM_WRAP_CHECK_(n,t) memzero((char*)(d), (n) * sizeof(t)))
2419+
#define ZeroD(d,n,t) (MEM_WRAP_CHECK_(n,t) assert(d), memzero((char*)(d), (n) * sizeof(t)))
24202420
#else
24212421
/* Using bzero(), which returns void. */
2422-
#define ZeroD(d,n,t) (MEM_WRAP_CHECK_(n,t) memzero((char*)(d), (n) * sizeof(t)),d)
2422+
#define ZeroD(d,n,t) (MEM_WRAP_CHECK_(n,t) assert(d), memzero((char*)(d), (n) * sizeof(t)),d)
24232423
#endif
24242424

24252425
#define PoisonWith(d,n,t,b) (MEM_WRAP_CHECK_(n,t) (void)memset((char*)(d), (U8)(b), (n) * sizeof(t)))

pp_ctl.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -1991,7 +1991,8 @@ PP(pp_caller)
19911991

19921992
if (AvMAX(PL_dbargs) < AvFILLp(ary) + off)
19931993
av_extend(PL_dbargs, AvFILLp(ary) + off);
1994-
Copy(AvALLOC(ary), AvARRAY(PL_dbargs), AvFILLp(ary) + 1 + off, SV*);
1994+
if (AvFILLp(ary) + 1 + off)
1995+
Copy(AvALLOC(ary), AvARRAY(PL_dbargs), AvFILLp(ary) + 1 + off, SV*);
19951996
AvFILLp(PL_dbargs) = AvFILLp(ary) + off;
19961997
}
19971998
mPUSHi(CopHINTS_get(cx->blk_oldcop));

pp_hot.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -4330,7 +4330,8 @@ PP(pp_entersub)
43304330
AvARRAY(av) = ary;
43314331
}
43324332

4333-
Copy(MARK+1,AvARRAY(av),items,SV*);
4333+
if (items)
4334+
Copy(MARK+1,AvARRAY(av),items,SV*);
43344335
AvFILLp(av) = items - 1;
43354336
}
43364337
if (UNLIKELY((cx->blk_u16 & OPpENTERSUB_LVAL_MASK) == OPpLVAL_INTRO &&

0 commit comments

Comments
 (0)