The boy, thought to be 13 or 14, launched the attack at his private school after midday (14:00 GMT).
At least four students were injured and are in hospital in the city in Goiás state, central Brazil.
A police colonel is quoted as saying the boy may have been bullied and that police are investigating whether that motivated the attack.
The suspect is reportedly from an army or police family, and went home to pick up the weapon before carrying out the attack.
He is now in police custody.
“Staff called him smelly because he did not use deodorant,” the student said. “In the break between classes, he took his gun out of his backpack and started shooting.
“He did not select anyone in particular [as a target]. Then everybody ran away.”
The Goyases school, for ages six to 15, is located in a middle-class district of the city.
School shootings of this kind are rare in Brazil. However the country has a high rate of violent crime with nearly 60,000 murders a year.