summaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
authorstu <stwo@users.sourceforge.net>2018-06-13 16:15:27 (GMT)
committerstu <stwo@users.sourceforge.net>2018-06-13 16:15:27 (GMT)
commiteccaf23657cbf949e58c4ef65a12125ec872d306 (patch)
tree3507b89c096f386912a8e4374d70a86e3851718a /unix
parentd8264cbb73c0078e5f674cf77fe3b0e036717745 (diff)
downloadtcl-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.c24
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;