Function returning PROGMEM stirngs

What is the correct way of returning a pointer to a PROGMEM string?

For example the code

const char str[] PROGMEM = "Hello World!";

const char * getStr() {
  return str;
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  char msg[32];
  sprintf(msg, "%s", getStr()); // <--- This will print strange characters in msg
  Serial.println(msg);
}

Will procduce strange characters in serial monitor. (Yes, I double checked baud)

But substituting the function call inside sprintf with ‘str’ (which is the data actually returned), everything works.

From the PROGMEM doc

const char signMessage[] PROGMEM  = {"I AM PREDATOR,  UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"};

//...

int len = strlen_P(signMessage);
  for (k = 0; k < len; k++)
  {
    myChar =  pgm_read_byte_near(signMessage + k);
    Serial.print(myChar);
  }

Or further in the doc

#include <avr/pgmspace.h>
const char string_0[] PROGMEM = "String 0";   // "String 0" etc are strings to store - change to suit.
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";


// Then set up a table to refer to your strings.

const char* const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};

char buffer[30];    // make sure this is large enough for the largest string it must hold

//.....

strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy.

Should give you ideas