| Summary: | dev-util/oprofile-1.0.0 - In function ‘open’, inlined from ‘copy_dumpfile’ at opjitconv.c:219:6: /usr/include/bits/fcntl2.h:50:24: error: call to ‘__open_missing_mode’ declared with attribute error: open with O_CREAT in second argument needs 3 arg | ||
|---|---|---|---|
| Product: | Gentoo Linux | Reporter: | Jeroen Roovers (RETIRED) <jer> |
| Component: | [OLD] Development | Assignee: | Andrew Savchenko <bircoph> |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | CC: | bircoph |
| Priority: | Normal | Keywords: | PATCH |
| Version: | unspecified | ||
| Hardware: | All | ||
| OS: | Linux | ||
| URL: | http://marc.info/?l=oprofile-list&m=141537142104196 | ||
| Whiteboard: | |||
| Package list: | Runtime testing required: | --- | |
| Attachments: | oprofile-1.0.0-open.patch | ||
I think this bug is more important than the -Wparentheses bug. Since this involves temporary file creation, and since the error in the Summary is triggered only with fortification checks enabled, it may not be very hard to construct a case for an exploit. I'd like to contact upstream on this issues as well as testing patch, this will take some time. I plan to start in a few days. The issue and the patch are pretty straightforward. The code is calling open(2) with the optional third argument as its second argument. I caught this because it caused an issue in the C preprocessor on HPPA where incidentally O_CREAT == S_IRUSR and I had extra compiler warnings enabled. See /usr/include/bits/fcntl2.h for the mechanism whereby O_CREAT triggers a check for a third argument and bails out when it isn't present. It is not an issue for the C preprocessor on x86 and amd64 (and probably others) because there it happens to be the case that S_IRUSR used as an open(2) flag instead of a mode modifier matches O_NOCTTY. O_CREAT : 64 O_NOCTTY: 256 S_IRUSR: 256 In testing the reduced test case from comment #0 on amd64, I see that it fails to create the file, probably in line with what O_NOCTTY is supposed to do. In that case the output is: rm: cannot remove ‘oprofile_file’: No such file or directory O_CREAT: 64 S_IRUSR: 256 File: ‘oprofile_file’ Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 803h/2051d Inode: 1142119 Links: 1 Access: (0400/-r--------) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2015-02-06 21:18:35.227178044 +0100 Modify: 2015-02-06 21:18:35.227178044 +0100 Change: 2015-02-06 21:18:35.227178044 +0100 Birth: - removed ‘oprofile_file’ stat: cannot stat ‘oprofile_file’: No such file or directory rm: cannot remove ‘oprofile_file’: No such file or directory The first, correct call to open(2) as used after my patch, creates a file if it doesn't exist. The second call to open(2) succeeds on amd64 but it creates no file. That means the dumpfile is not created at all on some popular architectures. The copy_dumpfile() function then proceeds to copy that dumpfile to tmp_dumpfile through a call to system(3) designed to preserve dumpfile's permissions, which the author thinks have just been set to 0400 or (S_IRUSR): sprintf(sys_cmd_buffer, "/bin/cp -p %s %s", dumpfile, tmp_dumpfile); So that should always fail there. Comment on attachment 395510 [details, diff] oprofile-1.0.0-open.patch http://sourceforge.net/p/oprofile/oprofile/ci/4598ca73b0a367ca46d4a2843261e20e1896773b/ So someone already discovered that on MIPS, with the same error message. Fixed in -r1. |
Created attachment 395510 [details, diff] oprofile-1.0.0-open.patch opjitconv/opjitconv.c:219: int fd = open(dumpfile, S_IRUSR); Seems to confuse flags/mode. I'm not sure the attached patch is correct, since copy_dumpfile() looks utterly confusing as is. A test case might look like this: %< %< %< %< %< %< %< %< %< %< %< %< %< %< #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char ** argv) { int fd; system("rm -v oprofile_file"); printf("O_CREAT: %d\nS_IRUSR: %d\n\n", O_CREAT, S_IRUSR); fd = open("oprofile_file", O_CREAT, S_IRUSR); close(fd); system("stat oprofile_file"); system("rm -v oprofile_file"); fd = open("oprofile_file", S_IRUSR); close(fd); system("stat oprofile_file"); system("rm -v oprofile_file"); return 0; } %< %< %< %< %< %< %< %< %< %< %< %< %< %< with the output on one HPPA system looking like this: removed ‘oprofile_file’ O_CREAT: 256 S_IRUSR: 256 File: ‘oprofile_file’ Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 804h/2052d Inode: 751292 Links: 1 Access: (0400/-r--------) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2015-02-04 12:37:04.000000000 +0100 Modify: 2015-02-04 12:37:04.000000000 +0100 Change: 2015-02-04 12:37:04.000000000 +0100 Birth: - removed ‘oprofile_file’ File: ‘oprofile_file’ Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 804h/2052d Inode: 751292 Links: 1 Access: (7745/-rwsr-Sr-t) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2015-02-04 12:37:04.000000000 +0100 Modify: 2015-02-04 12:37:04.000000000 +0100 Change: 2015-02-04 12:37:04.000000000 +0100 Birth: - removed ‘oprofile_file’