1// Copyright 2022 The BoringSSL Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//go:build ignore
16
17// check_stack.go checks that each of its arguments has a non-executable stack.
18// See https://www.airs.com/blog/archives/518 for details.
19package main
20
21import (
22	"debug/elf"
23	"fmt"
24	"os"
25)
26
27func checkStack(path string) {
28	file, err := elf.Open(path)
29	if err != nil {
30		fmt.Fprintf(os.Stderr, "Error opening %s: %s\n", path, err)
31		os.Exit(1)
32	}
33	defer file.Close()
34
35	for _, prog := range file.Progs {
36		if prog.Type == elf.PT_GNU_STACK && prog.Flags&elf.PF_X != 0 {
37			fmt.Fprintf(os.Stderr, "%s has an executable stack.\n", path)
38			os.Exit(1)
39		}
40	}
41}
42
43func main() {
44	for _, path := range os.Args[1:] {
45		checkStack(path)
46	}
47}
48