diff options
author | stu <stwo@users.sourceforge.net> | 2018-06-13 16:15:27 (GMT) |
---|---|---|
committer | stu <stwo@users.sourceforge.net> | 2018-06-13 16:15:27 (GMT) |
commit | eccaf23657cbf949e58c4ef65a12125ec872d306 (patch) | |
tree | 3507b89c096f386912a8e4374d70a86e3851718a /unix | |
parent | d8264cbb73c0078e5f674cf77fe3b0e036717745 (diff) | |
download | tcl-eccaf23657cbf949e58c4ef65a12125ec872d306.zip tcl-eccaf23657cbf949e58c4ef65a12125ec872d306.tar.gz tcl-eccaf23657cbf949e58c4ef65a12125ec872d306.tar.bz2 |
Don't call getsockname(2) in Tcl_MakeFileChannel(3) unless absolutely necessary.
Closes RFE [0ac9d06895].
Permits better constraining of Tcl/tclsh via OpenBSD's pledge(2) or similar mechanisms.
Diffstat (limited to 'unix')
-rw-r--r-- | unix/tclUnixChan.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index ced684a..6eed23b 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -1503,30 +1503,32 @@ Tcl_MakeFileChannel( char channelName[16 + TCL_INTEGER_SPACE]; int fd = PTR2INT(handle); const Tcl_ChannelType *channelTypePtr; - struct sockaddr sockaddr; - socklen_t sockaddrLen = sizeof(sockaddr); + struct stat buf; if (mode == 0) { return NULL; } - sockaddr.sa_family = AF_UNSPEC; - #ifdef SUPPORTS_TTY if (isatty(fd)) { channelTypePtr = &ttyChannelType; sprintf(channelName, "serial%d", fd); } else #endif /* SUPPORTS_TTY */ - if ((getsockname(fd, (struct sockaddr *)&sockaddr, &sockaddrLen) == 0) - && (sockaddrLen > 0) - && (sockaddr.sa_family == AF_INET || sockaddr.sa_family == AF_INET6)) { - return TclpMakeTcpClientChannelMode(INT2PTR(fd), mode); - } else { - channelTypePtr = &fileChannelType; - sprintf(channelName, "file%d", fd); + if (fstat(fd, &buf) == 0 && S_ISSOCK(buf.st_mode)) { + struct sockaddr sockaddr; + socklen_t sockaddrLen = sizeof(sockaddr); + sockaddr.sa_family = AF_UNSPEC; + if ((getsockname(fd, (struct sockaddr *)&sockaddr, &sockaddrLen) == 0) + && (sockaddrLen > 0) + && (sockaddr.sa_family == AF_INET || sockaddr.sa_family == AF_INET6)) { + return TclpMakeTcpClientChannelMode(INT2PTR(fd), mode); + } } + channelTypePtr = &fileChannelType; + sprintf(channelName, "file%d", fd); + fsPtr = ckalloc(sizeof(FileState)); fsPtr->fd = fd; fsPtr->validMask = mode | TCL_EXCEPTION; |