ehds opened a new pull request, #2415: URL: https://github.com/apache/brpc/pull/2415
### What problem does this PR solve? Issue Number: Problem Summary: DirReaderPosix 析构时关闭只应调用 `closedir(dir_)` , 不应同时调用 `close(fd_)`, 否则会导致同一个 `fd` 被close 两次。 > Upon calling closedir() the file descriptor is closed. https://man.freebsd.org/cgi/man.cgi?query=fdopendir&sektion=3 https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopendir.html PoC : 如果在 `close(fd_)` 和 `closedir(dir_)` 之间有新的 `open` 操作,`fd_` 可能会被复用,则 `closedir(dir_)` 导致改 `fd_` 失效,后续对 `fd_` 的操作将会导致 `errno = 9 (Bad File Descriptor)` ### What is changed and the side effects? ``` c++ #include <errno.h> #include <unistd.h> #include <assert.h> #include <string.h> int main(int argc, char *argv[]) { DIR *d; struct dirent *dp; int dfd = 0; if ((d = fdopendir((dfd = open("./tmp", O_RDONLY)))) == NULL) { fprintf(stderr, "Cannot open ./tmp directory\n"); exit(1); } // close dfd first. dfd = 3 close(dfd); // then open a new file, ffd maybe be reused, ffd = 3; int ffd = open("./tmp/testfile", O_RDONLY); assert(ffd > 0); closedir(d); // note this implicitly closes dfd = 3, so ffd is invalid. // read ffd would be failed. int rc = read(ffd, 0, 2); if(rc < 0) { printf("Read failed, error %d (%s)\n", errno, strerror(errno)); } return 0; } ``` Changed: ~DirReaderUnix() 中只需调用 `closedir(dir_)` 即可 Side effects: - Performance effects(性能影响): No - Breaking backward compatibility(向后兼容性): No --- ### Check List: - Please make sure your changes are compilable(请确保你的更改可以通过编译). - When providing us with a new feature, it is best to add related tests(如果你向我们增加一个新的功能, 请添加相关测试). - Please follow [Contributor Covenant Code of Conduct](../../master/CODE_OF_CONDUCT.md).(请遵循贡献者准则). -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
