$ .include \<bsd.obj.mk\> > Makefile
$ ktrace make -t obj
touch _SUBDIRUSE
Abort trap (core dumped)
$ kdump | tail -4
 89292 make     CALL  utimes(0x199a52c6c90,0)
 89292 make     PLDG  utimes, "fattr", errno 1 Operation not permitted
 89292 make     PSIG  SIGABRT SIG_DFL code <1852990836>
 89292 make     NAMI  "make.core"

The backtrace is as follows:
#0  0x000003ea639a0ada in utimes () at <stdin>:2
#1  0x000003e84ea17a9e in set_times (f=0x3eb37231540 "_SUBDIRUSE") at 
/usr/src/usr.bin/make/timestamp.c:40
#2  0x000003e84ea07b80 in Job_Touch (gn=0x3eb0d3ec400) at 
/usr/src/usr.bin/make/engine.c:275
#3  0x000003e84ea032b9 in CompatMake (gnp=0x3eb0d3ec400, pgnp=0x3eb0d3ea000) at 
/usr/src/usr.bin/make/compat.c:184
#4  0x000003e84ea1e1b0 in Lst_ForEachFrom (ln=0x3eabc6831c0, proc=0x3e84ea02f80 
<CompatMake>, d=0x3eb0d3ea000)
    at /usr/src/usr.bin/make/lst.lib/lstForEachFrom.c:62
#5  0x000003e84ea03151 in CompatMake (gnp=0x3eb0d3ea000, pgnp=0x0) at 
/usr/src/usr.bin/make/compat.c:131
#6  0x000003e84ea0366c in Compat_Run (targs=0x3e84ec2ba10) at 
/usr/src/usr.bin/make/compat.c:287
#7  0x000003e84ea0e716 in main (argc=3, argv=0x7f7ffffc3d68) at 
/usr/src/usr.bin/make/main.c:807

Since all calls to Job_Touch are guarded by 'touchFlag', I first thought
that one could make the wider pledge including "fattr" conditionally on
touchFlag, but unfortunately the .MAKEFLAGS target could add that flag
way after option parsing, so I don't think we can do better than just
add "fattr" to the promises:

Index: main.c
===================================================================
RCS file: /var/cvs/src/usr.bin/make/main.c,v
retrieving revision 1.119
diff -u -p -r1.119 main.c
--- main.c      4 Jan 2016 10:59:23 -0000       1.119
+++ main.c      11 Oct 2016 22:55:00 -0000
@@ -190,7 +190,7 @@ MainParseArgs(int argc, char **argv)
 #define OPTFLAGS "BC:D:I:SV:d:ef:ij:km:npqrst"
 #define OPTLETTERS "BSiknpqrst"
 
-       if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1)
+       if (pledge("stdio rpath wpath cpath fattr proc exec", NULL) == -1)
                err(2, "pledge");
 
        optind = 1;     /* since we're called more than once */

Reply via email to