From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/11526 Path: news.gmane.org!.POSTED!not-for-mail From: Omer Anson Newsgroups: gmane.linux.lib.musl.general Subject: [PATCH] Be more precise using va_arg in fcntl Date: Mon, 19 Jun 2017 21:10:43 +0300 Message-ID: <1497895843-4631-1-git-send-email-oaanson@gmail.com> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org X-Trace: blaine.gmane.org 1497895877 25686 195.159.176.226 (19 Jun 2017 18:11:17 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 19 Jun 2017 18:11:17 +0000 (UTC) Cc: Omer Anson To: musl@lists.openwall.com Original-X-From: musl-return-11539-gllmg-musl=m.gmane.org@lists.openwall.com Mon Jun 19 20:11:11 2017 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1dN18o-0006KZ-QE for gllmg-musl@m.gmane.org; Mon, 19 Jun 2017 20:11:10 +0200 Original-Received: (qmail 5906 invoked by uid 550); 19 Jun 2017 18:11:10 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 5828 invoked from network); 19 Jun 2017 18:11:07 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=RO14WbgigN+3qk+L2dQ/LqQWgxoNNPJXh0TRNyo3TPE=; b=D4vrI+b/ehF4XYOJ7GMpxy0te2/09Dj3PRfklw7GTWI4lhRE0wrZu0FI+XDWIKgeV2 gTFJbsq/ELaFTcBvEdlDYWadN3ojk1YiyKeSMuQyRtsjy5eiSgcseFmuByZrl2PbeV+Z 9Otcl97SGSXzsu0/fyC5iBNoiZx2msbbrg5gwc0fVIy8QjJ87lXEeJOAZ7qli44ct9Xl g92ufFkvCG6cBxRG9zq1wur0w5AUISFiZ9PUGqSO1FiHSihdwtntgRAr2zNldb3LT5Kz td68Y6aBXEELJQV+hyyGFVt5gGtLYa9/uRTBcYr0qofa4zwqPmWkqAobGTgJTBhVZNN8 OdYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=RO14WbgigN+3qk+L2dQ/LqQWgxoNNPJXh0TRNyo3TPE=; b=U35Qwb3DvZwBzqA3wseaXJsVOsuDjQfcsUVY/b0Xq5Hb468SXU631gm5Ii7mqaUmE0 Xc92ZnBZAGjLiTV1/q+JG6Lg9CcJGm9yLUsDDN+Dorh07TaRKdJ9a5ww7LaCs6rTGVQg wrNl89Knxv8C6/u0DvqvA++CLdW+p5YLOoT71VQz4dRD2qMHbJPa6rGG3UHjD6a6bayj sveV2nvBg9ISEClRuO7x/XkewNem2Ejj9Y2G6TCpeXXyJ7jLXBDyNetSxL8NdCyhq3zL Lj99fhmXF5pOmvAvEd/BD19u8YDvtvQPejMG6o/jmLJoU8fG3KoVLliInYSmeJFSDbyR Aavg== X-Gm-Message-State: AKS2vOwHoPneRKOfPnYgN+3lhpetTcCNzIq+U91K2uOIDwA+mEjya4Pf 0lm6obVtzG9pgyen X-Received: by 10.223.169.138 with SMTP id b10mr17046577wrd.29.1497895856161; Mon, 19 Jun 2017 11:10:56 -0700 (PDT) X-Mailer: git-send-email 2.4.11 Xref: news.gmane.org gmane.linux.lib.musl.general:11526 Archived-At: Currently, fcntl automatically calls va_arg with type unsigned long, regardless of the actual invoked command, and therefore ignoring whether such an argument exists, or its type. According to the C standard[1][2], calling va_arg if the types do not match, or beyond the end of the parameter list, causes an undefined behaviour. This change modifies fcntl to try and call va_arg only when necessary, and with the correct parameter type. It relies on the cmd argument to know what's the expected command. In case the cmd is unknown, it falls back to the previous behaviour. [1] http://www.open-std.org/jtc1/sc22/wg14/www/standards [2] http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdarg.h.html --- src/fcntl/fcntl.c | 72 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/src/fcntl/fcntl.c b/src/fcntl/fcntl.c index ce615d0..9d6b2cc 100644 --- a/src/fcntl/fcntl.c +++ b/src/fcntl/fcntl.c @@ -5,24 +5,40 @@ #include "syscall.h" #include "libc.h" +#define GET_ARG_MACRO(type) ({ \ + va_list ap; \ + va_start(ap, cmd); \ + type __arg = va_arg(ap, type); \ + va_end(ap); \ + __arg; \ + }) + int fcntl(int fd, int cmd, ...) { - unsigned long arg; - va_list ap; - va_start(ap, cmd); - arg = va_arg(ap, unsigned long); - va_end(ap); - if (cmd == F_SETFL) arg |= O_LARGEFILE; - if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, (void *)arg); - if (cmd == F_GETOWN) { + switch (cmd) { + case F_GETFD: + case F_GETFL: + case F_GETSIG: + case F_GETLEASE: + case F_GET_SEALS: + case F_GETPIPE_SZ: + return syscall(SYS_fcntl, fd, cmd); + case F_GETOWN: { struct f_owner_ex ex; int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex); - if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, (void *)arg); + if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd); if (ret) return __syscall_ret(ret); return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid; } - if (cmd == F_DUPFD_CLOEXEC) { - int ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, arg); + case F_SETFL: { + int arg = GET_ARG_MACRO(int); + arg |= O_LARGEFILE; + return syscall(SYS_fcntl, fd, cmd, arg); + } + case F_DUPFD_CLOEXEC: { + int ret; + int arg = GET_ARG_MACRO(int); + ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, arg); if (ret != -EINVAL) { if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); @@ -37,13 +53,37 @@ int fcntl(int fd, int cmd, ...) if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); return __syscall_ret(ret); } - switch (cmd) { - case F_SETLK: + case F_DUPFD: + case F_SETFD: + case F_SETSIG: + case F_SETLEASE: + case F_ADD_SEALS: + case F_SETOWN: + case F_SETPIPE_SZ: + case F_NOTIFY: { + int arg = GET_ARG_MACRO(int); + return syscall(SYS_fcntl, fd, cmd, arg); + } case F_GETLK: + case F_SETLK: + case F_OFD_SETLK: + case F_OFD_GETLK: { + struct flock * arg = GET_ARG_MACRO(struct flock *); + return syscall(SYS_fcntl, fd, cmd, arg); + } + case F_OFD_SETLKW: + case F_SETLKW: { + struct flock * arg = GET_ARG_MACRO(struct flock *); + return syscall_cp(SYS_fcntl, fd, cmd, arg); + } case F_GETOWN_EX: - case F_SETOWN_EX: - return syscall(SYS_fcntl, fd, cmd, (void *)arg); - default: + case F_SETOWN_EX: { + struct f_owner_ex * arg = GET_ARG_MACRO(struct f_owner_ex *); return syscall(SYS_fcntl, fd, cmd, arg); } + default: { + unsigned long arg = GET_ARG_MACRO(unsigned long); + return syscall(SYS_fcntl, fd, cmd, arg); + } + } } -- 2.4.11