Skip to content
This repository was archived by the owner on Mar 10, 2026. It is now read-only.

Commit 6844678

Browse files
committed
Fix potential unaligned accesses in the string pool (Issue #5474)
This set of changes makes the PPD functions use strdup and free - they were modifying the contents of the string in places and doing other things that were not safe for (immutable) strings in the pool.
1 parent 558bba7 commit 6844678

4 files changed

Lines changed: 122 additions & 140 deletions

File tree

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Changes in CUPS v2.2.11
88
- Running ppdmerge with the same input and output filenames did not work as
99
advertised (Issue #5455)
1010
- Fixed a potential memory leak when reading at the end of a file (Issue #5473)
11+
- Fixed potential unaligned accesses in the string pool (Issue #5474)
1112
- Fixed a potential memory leak when loading a PPD file (Issue #5475)
1213
- Added a USB quirks rule for the Lexmark E120n (Issue #5478)
1314
- Fixed a compile error on Linux (Issue #5483)

cups/ppd-cache.c

Lines changed: 59 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* PPD cache implementation for CUPS.
33
*
4-
* Copyright © 2010-2018 by Apple Inc.
4+
* Copyright © 2010-2019 by Apple Inc.
55
*
66
* These coded instructions, statements, and computer programs are the
77
* property of Apple Inc. and are protected by Federal copyright
@@ -508,24 +508,20 @@ _ppdCacheCreateWithFile(
508508
else if (!_cups_strcasecmp(line, "Filter"))
509509
{
510510
if (!pc->filters)
511-
pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0,
512-
(cups_acopy_func_t)_cupsStrAlloc,
513-
(cups_afree_func_t)_cupsStrFree);
511+
pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
514512

515513
cupsArrayAdd(pc->filters, value);
516514
}
517515
else if (!_cups_strcasecmp(line, "PreFilter"))
518516
{
519517
if (!pc->prefilters)
520-
pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0,
521-
(cups_acopy_func_t)_cupsStrAlloc,
522-
(cups_afree_func_t)_cupsStrFree);
518+
pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
523519

524520
cupsArrayAdd(pc->prefilters, value);
525521
}
526522
else if (!_cups_strcasecmp(line, "Product"))
527523
{
528-
pc->product = _cupsStrAlloc(value);
524+
pc->product = strdup(value);
529525
}
530526
else if (!_cups_strcasecmp(line, "SingleFile"))
531527
{
@@ -625,8 +621,8 @@ _ppdCacheCreateWithFile(
625621
}
626622

627623
map = pc->bins + pc->num_bins;
628-
map->pwg = _cupsStrAlloc(pwg_keyword);
629-
map->ppd = _cupsStrAlloc(ppd_keyword);
624+
map->pwg = strdup(pwg_keyword);
625+
map->ppd = strdup(ppd_keyword);
630626

631627
pc->num_bins ++;
632628
}
@@ -680,8 +676,8 @@ _ppdCacheCreateWithFile(
680676
goto create_error;
681677
}
682678

683-
size->map.pwg = _cupsStrAlloc(pwg_keyword);
684-
size->map.ppd = _cupsStrAlloc(ppd_keyword);
679+
size->map.pwg = strdup(pwg_keyword);
680+
size->map.ppd = strdup(ppd_keyword);
685681

686682
pc->num_sizes ++;
687683
}
@@ -709,15 +705,15 @@ _ppdCacheCreateWithFile(
709705

710706
pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
711707
pc->custom_max_width, pc->custom_max_length, NULL);
712-
pc->custom_max_keyword = _cupsStrAlloc(pwg_keyword);
708+
pc->custom_max_keyword = strdup(pwg_keyword);
713709

714710
pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
715711
pc->custom_min_width, pc->custom_min_length, NULL);
716-
pc->custom_min_keyword = _cupsStrAlloc(pwg_keyword);
712+
pc->custom_min_keyword = strdup(pwg_keyword);
717713
}
718714
else if (!_cups_strcasecmp(line, "SourceOption"))
719715
{
720-
pc->source_option = _cupsStrAlloc(value);
716+
pc->source_option = strdup(value);
721717
}
722718
else if (!_cups_strcasecmp(line, "NumSources"))
723719
{
@@ -764,8 +760,8 @@ _ppdCacheCreateWithFile(
764760
}
765761

766762
map = pc->sources + pc->num_sources;
767-
map->pwg = _cupsStrAlloc(pwg_keyword);
768-
map->ppd = _cupsStrAlloc(ppd_keyword);
763+
map->pwg = strdup(pwg_keyword);
764+
map->ppd = strdup(ppd_keyword);
769765

770766
pc->num_sources ++;
771767
}
@@ -813,8 +809,8 @@ _ppdCacheCreateWithFile(
813809
}
814810

815811
map = pc->types + pc->num_types;
816-
map->pwg = _cupsStrAlloc(pwg_keyword);
817-
map->ppd = _cupsStrAlloc(ppd_keyword);
812+
map->pwg = strdup(pwg_keyword);
813+
map->ppd = strdup(ppd_keyword);
818814

819815
pc->num_types ++;
820816
}
@@ -844,13 +840,13 @@ _ppdCacheCreateWithFile(
844840
pc->presets[print_color_mode] + print_quality);
845841
}
846842
else if (!_cups_strcasecmp(line, "SidesOption"))
847-
pc->sides_option = _cupsStrAlloc(value);
843+
pc->sides_option = strdup(value);
848844
else if (!_cups_strcasecmp(line, "Sides1Sided"))
849-
pc->sides_1sided = _cupsStrAlloc(value);
845+
pc->sides_1sided = strdup(value);
850846
else if (!_cups_strcasecmp(line, "Sides2SidedLong"))
851-
pc->sides_2sided_long = _cupsStrAlloc(value);
847+
pc->sides_2sided_long = strdup(value);
852848
else if (!_cups_strcasecmp(line, "Sides2SidedShort"))
853-
pc->sides_2sided_short = _cupsStrAlloc(value);
849+
pc->sides_2sided_short = strdup(value);
854850
else if (!_cups_strcasecmp(line, "Finishings"))
855851
{
856852
if (!pc->finishings)
@@ -871,13 +867,13 @@ _ppdCacheCreateWithFile(
871867
else if (!_cups_strcasecmp(line, "MaxCopies"))
872868
pc->max_copies = atoi(value);
873869
else if (!_cups_strcasecmp(line, "ChargeInfoURI"))
874-
pc->charge_info_uri = _cupsStrAlloc(value);
870+
pc->charge_info_uri = strdup(value);
875871
else if (!_cups_strcasecmp(line, "JobAccountId"))
876872
pc->account_id = !_cups_strcasecmp(value, "true");
877873
else if (!_cups_strcasecmp(line, "JobAccountingUserId"))
878874
pc->accounting_user_id = !_cups_strcasecmp(value, "true");
879875
else if (!_cups_strcasecmp(line, "JobPassword"))
880-
pc->password = _cupsStrAlloc(value);
876+
pc->password = strdup(value);
881877
else if (!_cups_strcasecmp(line, "Mandatory"))
882878
{
883879
if (pc->mandatory)
@@ -888,9 +884,7 @@ _ppdCacheCreateWithFile(
888884
else if (!_cups_strcasecmp(line, "SupportFile"))
889885
{
890886
if (!pc->support_files)
891-
pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0,
892-
(cups_acopy_func_t)_cupsStrAlloc,
893-
(cups_afree_func_t)_cupsStrFree);
887+
pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
894888

895889
cupsArrayAdd(pc->support_files, value);
896890
}
@@ -1130,8 +1124,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
11301124
*/
11311125

11321126
new_size = old_size;
1133-
_cupsStrFree(old_size->map.ppd);
1134-
_cupsStrFree(old_size->map.pwg);
1127+
free(old_size->map.ppd);
1128+
free(old_size->map.pwg);
11351129
}
11361130
}
11371131

@@ -1152,8 +1146,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
11521146
* Save this size...
11531147
*/
11541148

1155-
new_size->map.ppd = _cupsStrAlloc(ppd_size->name);
1156-
new_size->map.pwg = _cupsStrAlloc(pwg_name);
1149+
new_size->map.ppd = strdup(ppd_size->name);
1150+
new_size->map.pwg = strdup(pwg_name);
11571151
new_size->width = new_width;
11581152
new_size->length = new_length;
11591153
new_size->left = new_left;
@@ -1173,14 +1167,14 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
11731167
pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
11741168
PWG_FROM_POINTS(ppd->custom_max[0]),
11751169
PWG_FROM_POINTS(ppd->custom_max[1]), NULL);
1176-
pc->custom_max_keyword = _cupsStrAlloc(pwg_keyword);
1170+
pc->custom_max_keyword = strdup(pwg_keyword);
11771171
pc->custom_max_width = PWG_FROM_POINTS(ppd->custom_max[0]);
11781172
pc->custom_max_length = PWG_FROM_POINTS(ppd->custom_max[1]);
11791173

11801174
pwgFormatSizeName(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
11811175
PWG_FROM_POINTS(ppd->custom_min[0]),
11821176
PWG_FROM_POINTS(ppd->custom_min[1]), NULL);
1183-
pc->custom_min_keyword = _cupsStrAlloc(pwg_keyword);
1177+
pc->custom_min_keyword = strdup(pwg_keyword);
11841178
pc->custom_min_width = PWG_FROM_POINTS(ppd->custom_min[0]);
11851179
pc->custom_min_length = PWG_FROM_POINTS(ppd->custom_min[1]);
11861180

@@ -1199,7 +1193,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
11991193

12001194
if (input_slot)
12011195
{
1202-
pc->source_option = _cupsStrAlloc(input_slot->keyword);
1196+
pc->source_option = strdup(input_slot->keyword);
12031197

12041198
if ((pc->sources = calloc((size_t)input_slot->num_choices, sizeof(pwg_map_t))) == NULL)
12051199
{
@@ -1251,8 +1245,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
12511245
"_");
12521246
}
12531247

1254-
map->pwg = _cupsStrAlloc(pwg_name);
1255-
map->ppd = _cupsStrAlloc(choice->choice);
1248+
map->pwg = strdup(pwg_name);
1249+
map->ppd = strdup(choice->choice);
12561250
}
12571251
}
12581252

@@ -1315,8 +1309,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
13151309
"_");
13161310
}
13171311

1318-
map->pwg = _cupsStrAlloc(pwg_name);
1319-
map->ppd = _cupsStrAlloc(choice->choice);
1312+
map->pwg = strdup(pwg_name);
1313+
map->ppd = strdup(choice->choice);
13201314
}
13211315
}
13221316

@@ -1342,8 +1336,8 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
13421336
{
13431337
pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword), "_");
13441338

1345-
map->pwg = _cupsStrAlloc(pwg_keyword);
1346-
map->ppd = _cupsStrAlloc(choice->choice);
1339+
map->pwg = strdup(pwg_keyword);
1340+
map->ppd = strdup(choice->choice);
13471341
}
13481342
}
13491343

@@ -1558,34 +1552,32 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
15581552

15591553
if (duplex)
15601554
{
1561-
pc->sides_option = _cupsStrAlloc(duplex->keyword);
1555+
pc->sides_option = strdup(duplex->keyword);
15621556

15631557
for (i = duplex->num_choices, choice = duplex->choices;
15641558
i > 0;
15651559
i --, choice ++)
15661560
{
15671561
if ((!_cups_strcasecmp(choice->choice, "None") ||
15681562
!_cups_strcasecmp(choice->choice, "False")) && !pc->sides_1sided)
1569-
pc->sides_1sided = _cupsStrAlloc(choice->choice);
1563+
pc->sides_1sided = strdup(choice->choice);
15701564
else if ((!_cups_strcasecmp(choice->choice, "DuplexNoTumble") ||
15711565
!_cups_strcasecmp(choice->choice, "LongEdge") ||
15721566
!_cups_strcasecmp(choice->choice, "Top")) && !pc->sides_2sided_long)
1573-
pc->sides_2sided_long = _cupsStrAlloc(choice->choice);
1567+
pc->sides_2sided_long = strdup(choice->choice);
15741568
else if ((!_cups_strcasecmp(choice->choice, "DuplexTumble") ||
15751569
!_cups_strcasecmp(choice->choice, "ShortEdge") ||
15761570
!_cups_strcasecmp(choice->choice, "Bottom")) &&
15771571
!pc->sides_2sided_short)
1578-
pc->sides_2sided_short = _cupsStrAlloc(choice->choice);
1572+
pc->sides_2sided_short = strdup(choice->choice);
15791573
}
15801574
}
15811575

15821576
/*
15831577
* Copy filters and pre-filters...
15841578
*/
15851579

1586-
pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0,
1587-
(cups_acopy_func_t)_cupsStrAlloc,
1588-
(cups_afree_func_t)_cupsStrFree);
1580+
pc->filters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
15891581

15901582
cupsArrayAdd(pc->filters,
15911583
"application/vnd.cups-raw application/octet-stream 0 -");
@@ -1642,9 +1634,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
16421634

16431635
if ((ppd_attr = ppdFindAttr(ppd, "cupsPreFilter", NULL)) != NULL)
16441636
{
1645-
pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0,
1646-
(cups_acopy_func_t)_cupsStrAlloc,
1647-
(cups_afree_func_t)_cupsStrFree);
1637+
pc->prefilters = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
16481638

16491639
do
16501640
{
@@ -1661,7 +1651,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
16611651
*/
16621652

16631653
if (ppd->product)
1664-
pc->product = _cupsStrAlloc(ppd->product);
1654+
pc->product = strdup(ppd->product);
16651655

16661656
/*
16671657
* Copy finishings mapping data...
@@ -1818,7 +1808,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
18181808
*/
18191809

18201810
if ((ppd_attr = ppdFindAttr(ppd, "cupsChargeInfoURI", NULL)) != NULL)
1821-
pc->charge_info_uri = _cupsStrAlloc(ppd_attr->value);
1811+
pc->charge_info_uri = strdup(ppd_attr->value);
18221812

18231813
if ((ppd_attr = ppdFindAttr(ppd, "cupsJobAccountId", NULL)) != NULL)
18241814
pc->account_id = !_cups_strcasecmp(ppd_attr->value, "true");
@@ -1827,7 +1817,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
18271817
pc->accounting_user_id = !_cups_strcasecmp(ppd_attr->value, "true");
18281818

18291819
if ((ppd_attr = ppdFindAttr(ppd, "cupsJobPassword", NULL)) != NULL)
1830-
pc->password = _cupsStrAlloc(ppd_attr->value);
1820+
pc->password = strdup(ppd_attr->value);
18311821

18321822
if ((ppd_attr = ppdFindAttr(ppd, "cupsMandatory", NULL)) != NULL)
18331823
pc->mandatory = _cupsArrayNewStrings(ppd_attr->value, ' ');
@@ -1836,9 +1826,7 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
18361826
* Support files...
18371827
*/
18381828

1839-
pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0,
1840-
(cups_acopy_func_t)_cupsStrAlloc,
1841-
(cups_afree_func_t)_cupsStrFree);
1829+
pc->support_files = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup, (cups_afree_func_t)free);
18421830

18431831
for (ppd_attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
18441832
ppd_attr;
@@ -1894,8 +1882,8 @@ _ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */
18941882
{
18951883
for (i = pc->num_bins, map = pc->bins; i > 0; i --, map ++)
18961884
{
1897-
_cupsStrFree(map->pwg);
1898-
_cupsStrFree(map->ppd);
1885+
free(map->pwg);
1886+
free(map->ppd);
18991887
}
19001888

19011889
free(pc->bins);
@@ -1905,22 +1893,21 @@ _ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */
19051893
{
19061894
for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
19071895
{
1908-
_cupsStrFree(size->map.pwg);
1909-
_cupsStrFree(size->map.ppd);
1896+
free(size->map.pwg);
1897+
free(size->map.ppd);
19101898
}
19111899

19121900
free(pc->sizes);
19131901
}
19141902

1915-
if (pc->source_option)
1916-
_cupsStrFree(pc->source_option);
1903+
free(pc->source_option);
19171904

19181905
if (pc->sources)
19191906
{
19201907
for (i = pc->num_sources, map = pc->sources; i > 0; i --, map ++)
19211908
{
1922-
_cupsStrFree(map->pwg);
1923-
_cupsStrFree(map->ppd);
1909+
free(map->pwg);
1910+
free(map->ppd);
19241911
}
19251912

19261913
free(pc->sources);
@@ -1930,26 +1917,23 @@ _ppdCacheDestroy(_ppd_cache_t *pc) /* I - PPD cache and mapping data */
19301917
{
19311918
for (i = pc->num_types, map = pc->types; i > 0; i --, map ++)
19321919
{
1933-
_cupsStrFree(map->pwg);
1934-
_cupsStrFree(map->ppd);
1920+
free(map->pwg);
1921+
free(map->ppd);
19351922
}
19361923

19371924
free(pc->types);
19381925
}
19391926

1940-
if (pc->custom_max_keyword)
1941-
_cupsStrFree(pc->custom_max_keyword);
1942-
1943-
if (pc->custom_min_keyword)
1944-
_cupsStrFree(pc->custom_min_keyword);
1927+
free(pc->custom_max_keyword);
1928+
free(pc->custom_min_keyword);
19451929

1946-
_cupsStrFree(pc->product);
1930+
free(pc->product);
19471931
cupsArrayDelete(pc->filters);
19481932
cupsArrayDelete(pc->prefilters);
19491933
cupsArrayDelete(pc->finishings);
19501934

1951-
_cupsStrFree(pc->charge_info_uri);
1952-
_cupsStrFree(pc->password);
1935+
free(pc->charge_info_uri);
1936+
free(pc->password);
19531937

19541938
cupsArrayDelete(pc->mandatory);
19551939

0 commit comments

Comments
 (0)