samples/check-exec/inc.c

Source file repositories/reference/linux-study-clean/samples/check-exec/inc.c

File Facts

System
Linux kernel
Corpus path
samples/check-exec/inc.c
Extension
.c
Size
5437 bytes
Lines
213
Domain
Support Tooling And Documentation
Bucket
samples
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (*line != '#' && strlen(line) != 1) {
			fprintf(stderr, "# ERROR: Unknown string\n");
			return 1;
		}
		switch (*line) {
		case '#':
			/* Skips shebang and comments. */
			break;
		case '+':
			/* Increments and prints the number. */
			number++;
			printf("%lld\n", number);
			break;
		case '?':
			/* Reads integer from stdin. */
			fprintf(stderr, "> Enter new number: \n");
			if (scanf("%lld", &number) != 1) {
				fprintf(stderr,
					"# WARNING: Failed to read number from stdin\n");
			}
			break;
		default:
			fprintf(stderr, "# ERROR: Unknown character '%c'\n",
				*line);
			return 1;
		}
		line = strtok_r(NULL, "\n", &saveptr);
	}
	return 0;
}

/* Returns 1 on error, 0 otherwise. */
static int interpret_stream(FILE *script, char *const script_name,
			    char *const *const envp, const bool restrict_stream)
{
	int err;
	char *const script_argv[] = { script_name, NULL };
	char buf[128] = {};
	size_t buf_size = sizeof(buf);

	/*
	 * We pass a valid argv and envp to the kernel to emulate a native
	 * script execution.  We must use the script file descriptor instead of
	 * the script path name to avoid race conditions.
	 */
	err = sys_execveat(fileno(script), "", script_argv, envp,
			   AT_EMPTY_PATH | AT_EXECVE_CHECK);
	if (err && restrict_stream) {
		perror("ERROR: Script execution check");
		return 1;
	}

	/* Reads script. */
	buf_size = fread(buf, 1, buf_size - 1, script);
	return interpret_buffer(buf, buf_size);
}

static void print_usage(const char *argv0)
{
	fprintf(stderr, "usage: %s <script.inc> | -i | -c <command>\n\n",
		argv0);
	fprintf(stderr, "Example:\n");
	fprintf(stderr, "  ./set-exec -fi -- ./inc -i < script-exec.inc\n");
}

int main(const int argc, char *const argv[], char *const *const envp)
{
	int opt;
	char *cmd = NULL;
	char *script_name = NULL;
	bool interpret_stdin = false;
	FILE *script_file = NULL;
	int secbits;
	bool deny_interactive, restrict_file;
	size_t arg_nb;

	secbits = prctl(PR_GET_SECUREBITS);
	if (secbits == -1) {
		/*
		 * This should never happen, except with a buggy seccomp
		 * filter.
		 */
		perror("ERROR: Failed to get securebits");
		return 1;
	}

	deny_interactive = !!(secbits & SECBIT_EXEC_DENY_INTERACTIVE);
	restrict_file = !!(secbits & SECBIT_EXEC_RESTRICT_FILE);

	while ((opt = getopt(argc, argv, "c:i")) != -1) {

Annotation

Implementation Notes