Date:

Share:

Why Git’s maintainers have a list of banned standard C library functions

Related Articles

Table of Contents

introduction

If you look at the Git source code, you might notice that there is a C header file called Banned. H.

This file contains a list of standard C library functions that have been banned from use in the Git source code by the Git maintainer and contributor community.

In this article, we’ll take a closer look at how the blocking of C functions is implemented, the specific C functions that were banned from use, and why these functions were banned from being used in the codebase.

How do you even implement and enforce a ban on the C function?

Before we jump into the standard C functions included in ban, let’s discuss how a function ban can even be implemented.

Git is primarily written in the C programming language, which is a compiled language. This means that as a preliminary step to executing a program, a compiler such as gcc or clang is used to compile the source code into machine code that can be understood by the CPU.

This enables a useful strategy for implementing community-based source code rules such as Git’s function ban:

Find a way to fail the compile phase if a contributor tries to use a forbidden function anywhere in the source code.

This will not only prevent the user from compiling their code locally for testing, but ideally provide them with an understandable message as to why the compilation failed.

How can a forbidden function cause the C compiler to fail?

So the next question becomes: “How do you make the compiler throw an error when a specific function is used?”

The C language has a concept called a Macro, which is just a piece of code named Before compiling, the C preprocessor will parse the source files and replace all uses of the name with the appropriate piece of code. This can be useful for defining reusable constants throughout the program and code snippets to be replaced before the official compilation step.

More specifically, C also provides a subtype of macros called macros Function-like macros, which allow some dynamic behavior that can be useful to avoid repeating yourself. Git implements such a function-like macro as follows:

#define BANNED(func) sorry_##func##_is_a_banned_function

This macro indicates that the name BANNED(func) Must be replaced during the pre-processing step approx sorry_##func##_is_a_banned_function.

Furthermore, the value in parentheses, in this case func can match a dynamic value supplied later. It will be replaced into ##func## A placeholder in a replacement string sorry_##func##_is_a_banned_function.

So the idea is that if and when a forbidden function is used in the source code, it will be caught by the preprocessor macro and replaced with the message above, which will cause the compilation step to fail and provide an understandable error message to the user.

So how do you actually use a C function-like macro?

Now let’s look at the first standard C function included in the ban, strcpy. The following code snippet is included in the file named banned.hwhich was committed to the Git source code root directory on July 26, 2018:

#define BANNED(func) sorry_##func##_is_a_banned_function

#undef strcpy
#define strcpy(x,y) BANNED(strcpy)

#endif /* BANNED_H */

The first line is just the macro definition we already saw above.

Below that, we can see a new macro #define strcpy(x,y) BANNED(strcpy) defined. This is smart because the name of this macro is the actual function to replace, in this case strcpy(x,y) followed by the value of the macro which is the name of the function-like macro defined earlier BANNED(strcpy)Passes the dynamic value strcpy.

This is pretty cool because it actually chains together multiple macros that will effect the override of the forbidden function strcpy with the text sorry_strcpy_is_a_banned_function. This will cause the program to fail to compile, displaying the custom message to the user in the process.

Why was the strcpy function banned from the Git source code?

According to the code notes embedded in banned.h header file, functions are blacklisted for the following general reason:

This header lists functions that have been banned from our codebase because they are too easy to abuse (and even if used correctly, they complicate reviews). Including this header makes them compile-time errors.

In C, it is generally easy to abuse functions when they have unexpected results due to the potential of performing unsafe memory operations when the programmer is not very careful. This is the case for functions like strcpy().

God strcpy() documentation states that this function will be:

Copy a string and return a pointer to the end of the result

The summary of the function is as follows:

char *stpcpy(char *restrict s1, const char *restrict s2);

Note that the documentation even states this “If copying is done between overlapping objects, the behavior is undefined.”

The problem occurs when a string s2 of n Bytes are copied to a string s1 assigned m houses, when m < n. In this case the copied content will exceed the length of s1 and null will not be nullified, resulting in a potentially nasty bug. This will not necessarily crash the program (although it can) and can be difficult to troubleshoot and fix depending on the resulting behavior.

See the Git mailing list for More details on the initial ban of strcpy().

What to use instead of strcpy()?

Better to use a function that better protects against buffer overflows and also ensures that the copied string is always null-terminated. This can be achieved using snprintf() function.

int snprintf (	char * buf,
 	size_t size,
 	const char * fmt,
 	...);

Note that when using this function, the programmer directly specifies the size of the buffer to which data is to be copied, including the trailing null bytes to be added automatically. This reduces the possibility of buffer exceptions and non-zero-terminated strings.

Other C library functions prohibited by Git

Here is the full list of C library functions banned by Git, as of the publication date of this article:

#ifndef BANNED_H
#define BANNED_H

/*
 * This header lists functions that have been banned from our code base,
 * because they're too easy to misuse (and even if used correctly,
 * complicate audits). Including this header turns them into compile-time
 * errors.
 */

#define BANNED(func) sorry_##func##_is_a_banned_function

#undef strcpy
#define strcpy(x,y) BANNED(strcpy)
#undef strcat
#define strcat(x,y) BANNED(strcat)
#undef strncpy
#define strncpy(x,y,n) BANNED(strncpy)
#undef strncat
#define strncat(x,y,n) BANNED(strncat)

#undef sprintf
#undef vsprintf
#define sprintf(...) BANNED(sprintf)
#define vsprintf(...) BANNED(vsprintf)

#undef gmtime
#define gmtime
#undef localtime
#define localtime
#undef ctime
#define ctime
#undef ctime_r
#define ctime_r(t, buf) BANNED(ctime_r)
#undef asctime
#define asctime
#undef asctime_r
#define asctime_r(t, buf) BANNED(asctime_r)

#endif /* BANNED_H */

You can check the current list by visiting Official list of C functions prohibited in the Git source code.

Summary

In this article, we discussed a set of C functions that are forbidden in the Git source code and explained how the blocking is implemented using banned.h Header file in Git code. We saw that this ban was implemented in 2018 and has evolved a bit since then to include a variety of C functions. We also covered that the main reason for banning functions is to prevent the use of functions that repeatedly show the same problems due to their ease of abuse, especially when those problems can lead to complicated memory bugs that can be difficult to solve Boll.

next steps

If you’re interested in learning more about how Git works under the hood, check out our Baby Git guide for developers, which dives into the Git code in an accessible way. We wrote it for developers who are curious to learn how Git works at the code level. To that end, we’ve documented the first version of Git’s code and discussed it in detail.

We hope you enjoyed this post! Feel free to email me at jacob@initialcommit.io with any questions or comments.

References

  1. Official list of banned functions in the Git source code – https://github.com/git/git/blob/master/banned.h
  2. pubs.opengroup strcpy() documentation – https://pubs.opengroup.org/onlinepubs/9699919799/functions/strcpy.html
  3. Git strcpy() ban reference mailing list – https://lore.kernel.org/git/20180719203259.GA7869@sigill.intra.peff.net/
  4. Kernel snprintf() documentation – https://www.kernel.org/doc/htmldocs/kernel-api/API-snprintf.html

Source

Popular Articles