Bug 245807

Summary: [make] cc can not create a target when execd by BSD make but succeeds under gmake
Product: Base System Reporter: Bertrand Petit <bsdpr>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me CC: andrew, bsdpr, lwhsu, sjg, stable
Priority: ---    
Version: CURRENT   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
Truss trace on bsd make, generated with $ truss -f -a -o truss-make.log make CFLAGS=-v ttytest
none
Truss trace on gnu make, generated with $ truss -f -a -o truss-gmake.log gmake CFLAGS=-v ttytest none

Description Bertrand Petit 2020-04-22 00:14:42 UTC
I was flabbergasted to witness the following make output on a 12.1-STABLE (rev 359586) host:

$ make ttytest
cc -O2 -pipe  /home/elrond/ttytest.c  -o ttytest
ld: error: cannot open output file ttytest: Permission denied
cc: error: linker command failed with exit code 1 (use -v to see invocation)
*** Error code 1

Stop.
make: stopped in /home/elrond
$ touch ttytest
$ ls -l ttytest
-rw-r--r--  1 elrond  elrond  0 Apr 22 02:05 ttytest
$ ls -ldo .
drwxr-xr-x  44 elrond  elrond  uarch 91 Apr 22 02:05 .
]$ id
uid=1001(elrond) gid=1001(elrond) groups=1001(elrond),0(wheel),5(operator),44(video),4000(automedia),4001(mixing)


When using gmake, all went smoothly:

$ gmake ttytest  
cc     ttytest.c   -o ttytest
$ ls -l ttytest
-rwxr-xr-x  1 elrond  elrond  24000 Apr 22 02:07 ttytest
$ file ttytest
ttytest: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 12.1 (1201512), FreeBSD-style, with debug_info, not stripped


When trussed, the file creation indeed fails:

36580: openat(AT_FDCWD,"ttytest.tmpc878b15",O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC,0666) ERR#13 'Permission denied'
Comment 1 Bertrand Petit 2020-04-22 00:16:35 UTC
Created attachment 213656 [details]
Truss trace on bsd make, generated with $ truss -f -a -o truss-make.log make CFLAGS=-v ttytest
Comment 2 Bertrand Petit 2020-04-22 00:17:40 UTC
Created attachment 213657 [details]
Truss trace on gnu make, generated with $ truss -f -a -o truss-gmake.log gmake CFLAGS=-v ttytest
Comment 3 Andrew "RhodiumToad" Gierth 2020-04-22 00:28:25 UTC
User error, caused by non-obvious magic behavior (aka "POLA violation") on the part of bmake.

In short, since /usr/obj/home/elrond exists, bsd make is using that as .OBJDIR by default, and changing directory to it before running commands. So it's the permissions on _that_ directory that cause the issue.

It doesn't fail with gmake because that has no such magic behavior.
Comment 4 Bertrand Petit 2020-05-21 18:05:37 UTC
(In reply to andrew from comment #3)
Indeed, a major POLA violation is it, but also it is still a bug since this "magic behavior" should only select an /usr/obj subdirectory as an objdir only when that directory exists *and* is writable by the current user.
Comment 5 Simon J. Gerraty freebsd_committer freebsd_triage 2020-10-30 07:49:17 UTC
(In reply to andrew from comment #3)

The setting of .OBJDIR to /usr/obj/* is controlled by bsd.obj.mk not make.

Yes BSD make is a sharp tool compared to gmake ;-)
Comment 6 Andrew "RhodiumToad" Gierth 2020-10-30 08:40:32 UTC
(In reply to Simon J. Gerraty from comment #5)

Not correct - the use of /usr/obj as the default prefix for .OBJDIR is hardcoded into bmake - you can see it in contrib/bmake/main.c and pathnames.h.

You can also verify this using make -r to skip the use of default .mk files.
Comment 7 Simon J. Gerraty freebsd_committer freebsd_triage 2020-10-31 06:24:25 UTC
(In reply to andrew from comment #6)
You are correct - sorry, I've added a writable check to Main_SetObjdir
in upstream.
Comment 8 Simon J. Gerraty freebsd_committer freebsd_triage 2020-11-07 21:49:35 UTC
Fixed in bmake-20201101
Comment 9 Simon J. Gerraty freebsd_committer freebsd_triage 2020-11-07 21:52:48 UTC
correction, fixed in CURRENT will MFC next week