summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2020-04-24 03:27:12 +0000
committerDmitry V. Levin <ldv@altlinux.org>2020-04-24 03:27:12 +0000
commit924a93a39b61d3699926136713add09db2976fce (patch)
tree3839cbe230ff3a4eaae8d4799e46d7f365e0a851
parent76916913fc3802ccb5348a69a56fa2bc3946439d (diff)
pam_filter: fix potential off-by-one heap buffer overflow
Reported by gcc-10 -Wstringop-overflow: In file included from /usr/include/string.h:494, from modules/pam_filter/pam_filter.c:14: In function 'strcpy', inlined from 'process_args' at modules/pam_filter/pam_filter.c:137:2, inlined from 'need_a_filter.isra' at modules/pam_filter/pam_filter.c:618:12: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:90:10: warning: '__builtin_memcpy' writing 6 bytes into a region of size 5 [-Wstringop-overflow=] 90 | return __builtin___strcpy_chk (__dest, __src, __bos (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ modules/pam_filter/pam_filter.c: In function 'need_a_filter.isra': modules/pam_filter/pam_filter.c:128:21: note: at offset 0 to an object with size 5 allocated by 'malloc' here 128 | levp[0] = (char *) malloc(size); | ^~~~~~~~~~~~ * modules/pam_filter/pam_filter.c (process_args): Fix off-by-one heap buffer overflow in case of a filter without arguments (argc == 0).
-rw-r--r--modules/pam_filter/pam_filter.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/modules/pam_filter/pam_filter.c b/modules/pam_filter/pam_filter.c
index b9274e83..4f75486d 100644
--- a/modules/pam_filter/pam_filter.c
+++ b/modules/pam_filter/pam_filter.c
@@ -114,33 +114,32 @@ static int process_args(pam_handle_t *pamh
return -1;
}
- for (size=i=0; i<argc; ++i) {
- size += strlen(argv[i])+1;
- }
-
/* the "ARGS" variable */
#define ARGS_NAME "ARGS="
#define ARGS_OFFSET (sizeof(ARGS_NAME) - 1)
- size += ARGS_OFFSET;
+ size = sizeof(ARGS_NAME);
+
+ for (i=0; i<argc; ++i) {
+ size += strlen(argv[i]) + (i != 0);
+ }
- levp[0] = (char *) malloc(size);
+ levp[0] = malloc(size);
if (levp[0] == NULL) {
pam_syslog(pamh, LOG_CRIT, "no memory for filter arguments");
- if (levp) {
- free(levp);
- }
+ free(levp);
return -1;
}
strcpy(levp[0], ARGS_NAME);
- for (i=0,size=ARGS_OFFSET; i<argc; ++i) {
+ size = ARGS_OFFSET;
+ for (i=0; i<argc; ++i) {
+ if (i)
+ levp[0][size++] = ' ';
strcpy(levp[0]+size, argv[i]);
size += strlen(argv[i]);
- levp[0][size++] = ' ';
}
- levp[0][--size] = '\0'; /* <NUL> terminate */
/* the "SERVICE" variable */