Fala João, tudo bem?
Seu código está praticamente certo, foltou só um detalhezinho. Se liga, "mat" é um ponteiro de ponteiro, que no fim será uma matriz. Então você fez certo quando alocou os espaços das linhas e das colunas. No entanto, repara comigo aqui essa linha do código:
mat = malloc(sizeof(int)* linhas);
Nela foi feito a alocação do espaço da memória para um vetor de inteiros (com o tamanho de "linhas"). Mas como a matriz é um ponteiro de ponteiros é necessário alocar espaço para "n linhas" de ponteiros, para assim ser possível alocar "n colunas" em cada "mat[linha]". Então substituindo (int) por (int*) assim:
mat = malloc(sizeof(int*) * linhas);
Você está dizendo para o computador que está alocando "n linhas" de ponteiro para inteiro, para assim depois fazer o malloc das colunas corretamente. Fazendo essa pequena mudança só nessa linha o seu código vai funcionar corretamente, sem dar problema no free();
Conseguiu entender? Qualquer coisa é só falar ;)