autofs-5.1.7 - add buffer length checks to autofs mount_mount() From: Ian Kent --- CHANGELOG | 1 + modules/mount_autofs.c | 59 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6ab4813d..17926916 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -88,6 +88,7 @@ - add some buffer length checks to master map parser. - add buffer length check to rmdir_path(). - eliminate buffer usage from handle_mounts_cleanup(). +- add buffer length checks to autofs mount_mount(). 25/01/2021 autofs-5.1.7 - make bind mounts propagation slave by default. diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c index 0bcbb343..b2233573 100644 --- a/modules/mount_autofs.c +++ b/modules/mount_autofs.c @@ -50,8 +50,8 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, { struct startup_cond suc; pthread_t thid; - char realpath[PATH_MAX]; - char mountpoint[PATH_MAX]; + char realpath[PATH_MAX + 1]; + char mountpoint[PATH_MAX + 1]; const char **argv; int argc, status; int nobind = ap->flags & MOUNT_FLAG_NOBIND; @@ -68,32 +68,53 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, struct mnt_list *mnt; char buf[MAX_ERR_BUF]; char *options, *p; - int len, ret; + int err, ret; int hosts = 0; /* Root offset of multi-mount */ - len = strlen(root); - if (root[len - 1] == '/') { - strcpy(realpath, ap->path); - strcat(realpath, "/"); - strcat(realpath, name); - len--; - strncpy(mountpoint, root, len); - mountpoint[len] = '\0'; + if (root[strlen(root) - 1] == '/') { + err = snprintf(realpath, PATH_MAX + 1, "%s/%s", ap->path, name); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for realpath"); + return 1; + } + err = snprintf(mountpoint, PATH_MAX + 1, "%s", root); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for mountpoint"); + return 1; + } + mountpoint[err - 1] = 0; } else if (*name == '/') { if (ap->flags & MOUNT_FLAG_REMOUNT) { - strcpy(mountpoint, name); - strcpy(realpath, name); + err = snprintf(mountpoint, PATH_MAX + 1, "%s", name); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for mountpoint"); + return 1; + } + err = snprintf(realpath, PATH_MAX + 1, "%s", name); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for realpath"); + return 1; + } } else { - strcpy(mountpoint, root); - strcpy(realpath, name); + err = snprintf(mountpoint, PATH_MAX + 1, "%s", root); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for mountpoint"); + return 1; + } + err = snprintf(realpath, PATH_MAX + 1, "%s", name); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for realpath"); + return 1; + } } } else { - strcpy(mountpoint, root); - strcat(mountpoint, "/"); + err = snprintf(mountpoint, PATH_MAX + 1, "%s/%s", root, name); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for mountpoint"); + return 1; + } strcpy(realpath, mountpoint); - strcat(mountpoint, name); - strcat(realpath, name); } options = NULL;