You can only use one storage class at a time - so you cannot use both static and extern to qualify a single variable.
With dynamically allocated arrays, it is crucial to know which code will release the allocated space.  If you don't, you will have a memory leak.  In small-scale programs, it may not 'matter' in the sense that the program will run despite leaking memory.  However, in large programs, especially long-running programs (word processors, DBMS, etc), it matters crucially.
You can pass dynamically allocated arrays - or the pointer to the dynamically allocated array - to another function.  If you do not want the other function to modify it, you should write the other function so it takes const SomeType *arg as the argument.  The compiler will then ensure that your code does not modify the array.
Hence:
header.h
extern void func2(const char *filename);
extern void func1(void);
a.c
#include "header.h"
#include <stdlib.h>
#include <string.h>
extern const char *other_file_name; // Should be in a header!
void func1(void)
{
    char *filename;
    size_t N = strlen(other_file_name) + 1;
    filename = (char *)malloc(N);
    strcpy(filename, other_file_name); 
    file_name[N-1] = '\0'; 
    file_name[N-2] = 'x';
    func2(filename);
    free(filename);
} 
b.c
#include "header.h"
void func2(const char *filename)
{
    ...operations on filename...
}
main.c
#include "header.h"
int main(void)
{
    ...
    func1();
    ...
    func2("/etc/passwd");
    return 0;
}
Alternatively, but less desirably, you can make filename into a global variable.  In that case, you should declare it in header.h.  However, you cannot then have the compiler enforce the constraint that func2() should treat variable as a constant - one more reason not to use global variables.
See also SO 1433204 for a discussion of extern variables in C.