Australia were 374 for seven at lunch after adding 77 runs during the morning's play at Centurion.
Marsh and Smith took their fifth wicket stand to 233, seeing off the threat of Dale Steyn and Vernon Philander with the second new ball, before Smith was out for 100, caught at second slip off Ryan McLaren.
It was a crucial breakthrough because South Africa's bowling resources looked thin with Steyn and Philander having finished their spells.
Smith took 33 balls to advance from his overnight 91 to his fourth Test century, made off 211 deliveries, but was out two balls later.
More From This Section
Brad Haddin, one of the stars of Australia's 5-0 series win over England, lasted just three balls before he swung across the line against left-arm spinner Robin Peterson and was leg before wicket without scoring.
Marsh took his overnight score of 122 to a Test-best 148 before Philander came back into the attack and had him caught at first slip.
Johnson was unbeaten on 28 at lunch, made off 46 balls with five fours.