{"action":"created","issue":{"url":"https://api.github.com/repos/CTSRD-CHERI/llvm/issues/144","labels_url":"https://api.github.com/repos/CTSRD-CHERI/llvm/issues/144/labels{/name}","comments_url":"https://api.github.com/repos/CTSRD-CHERI/llvm/issues/144/comments","events_url":"https://api.github.com/repos/CTSRD-CHERI/llvm/issues/144/events","html_url":"https://github.com/CTSRD-CHERI/llvm/issues/144","id":122050473,"number":144,"title":"Possible code generation bug compiling ministat(1) with CheriABI","user":{"login":"rwatson","id":186862,"avatar_url":"https://avatars.githubusercontent.com/u/186862?v=3","gravatar_id":"","url":"https://api.github.com/users/rwatson","html_url":"https://github.com/rwatson","followers_url":"https://api.github.com/users/rwatson/followers","following_url":"https://api.github.com/users/rwatson/following{/other_user}","gists_url":"https://api.github.com/users/rwatson/gists{/gist_id}","starred_url":"https://api.github.com/users/rwatson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rwatson/subscriptions","organizations_url":"https://api.github.com/users/rwatson/orgs","repos_url":"https://api.github.com/users/rwatson/repos","events_url":"https://api.github.com/users/rwatson/events{/privacy}","received_events_url":"https://api.github.com/users/rwatson/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/CTSRD-CHERI/llvm/labels/bug","name":"bug","color":"fc2929"},{"url":"https://api.github.com/repos/CTSRD-CHERI/llvm/labels/works%20at%20-O0","name":"works at -O0","color":"f7c6c7"}],"state":"closed","locked":false,"assignee":{"login":"davidchisnall","id":404454,"avatar_url":"https://avatars.githubusercontent.com/u/404454?v=3","gravatar_id":"","url":"https://api.github.com/users/davidchisnall","html_url":"https://github.com/davidchisnall","followers_url":"https://api.github.com/users/davidchisnall/followers","following_url":"https://api.github.com/users/davidchisnall/following{/other_user}","gists_url":"https://api.github.com/users/davidchisnall/gists{/gist_id}","starred_url":"https://api.github.com/users/davidchisnall/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidchisnall/subscriptions","organizations_url":"https://api.github.com/users/davidchisnall/orgs","repos_url":"https://api.github.com/users/davidchisnall/repos","events_url":"https://api.github.com/users/davidchisnall/events{/privacy}","received_events_url":"https://api.github.com/users/davidchisnall/received_events","type":"User","site_admin":false},"milestone":null,"comments":6,"created_at":"2015-12-14T14:13:25Z","updated_at":"2015-12-16T21:41:08Z","closed_at":"2015-12-16T10:26:07Z","body":"In attempting to compile ```ministat(1)``` with CheriABI:\r\n```\r\ndiff --git a/usr.bin/ministat/Makefile b/usr.bin/ministat/Makefile\r\nindex 2a63797..0c7cf0e 100644\r\n--- a/usr.bin/ministat/Makefile\r\n+++ b/usr.bin/ministat/Makefile\r\n@@ -1,6 +1,9 @@\r\n # $FreeBSD$\r\n PROG=  ministat\r\n \r\n+WANT_CHERI=     pure\r\n+WANT_DUMP=      yes\r\n+\r\n LIBADD=        m\r\n \r\n .include <bsd.prog.mk>\r\n```\r\n\r\nI see a reproducible problem in which a capability-length exception fires when storing a pointer into a presumed 0x20-size allocation. Digging into the source, we see that ```calloc(3)``` is called to allocate an array of pointers of a suitable size:\r\n```\r\nstruct plot {\r\n        double          min;\r\n        double          max;\r\n        double          span;\r\n        int             width;\r\n\r\n        double          x0, dx;\r\n        int             height;\r\n        char            *data;\r\n        char            **bar;\r\n        int             separate_bars;\r\n        int             num_datasets;\r\n};\r\n\r\nstatic struct plot plot;\r\n\r\nstatic void\r\nSetupPlot(int width, int separate, int num_datasets)\r\n{\r\n        struct plot *pl;\r\n\r\n        pl = &plot;\r\n        pl->width = width;\r\n        pl->height = 0;\r\n        pl->data = NULL;\r\n        pl->bar = NULL;\r\n        pl->separate_bars = separate;\r\n        pl->num_datasets = num_datasets;\r\n        pl->min = 999e99;\r\n        pl->max = -999e99;\r\n}\r\n\r\nstatic void\r\nPlotSet(struct dataset *ds, int val)\r\n{\r\n        struct plot *pl;\r\n        int i, j, m, x;\r\n        unsigned n;\r\n        int bar;\r\n\r\n        pl = &plot;\r\n        if (pl->span == 0)\r\n                return;\r\n\r\n        if (pl->separate_bars)\r\n                bar = val-1;\r\n        else\r\n                bar = 0;\r\n\r\n        if (pl->bar == NULL)\r\n                pl->bar = calloc(sizeof(char *), pl->num_datasets);\r\n        if (pl->bar[bar] == NULL) {\r\n                pl->bar[bar] = malloc(pl->width);\r\n                memset(pl->bar[bar], 0, pl->width);\r\n        }\r\n...\r\n}\r\n\r\n...\r\nint\r\nmain(int argc, char **argv)\r\n{\r\n...\r\n        if (!flag_n && !suppress_plot) {\r\n                SetupPlot(termwidth, flag_s, nds);\r\n                for (i = 0; i < nds; i++)\r\n                        DimPlot(ds[i]);\r\n                for (i = 0; i < nds; i++)\r\n                        PlotSet(ds[i], i + 1);\r\n                DumpPlot();\r\n        }\r\n...\r\n}\r\n```\r\n\r\nStreamtrace confirms that ```SetupPlot``` is run and initialises ```pl->num_datasets``` to 1. In ```PlotSet()```, and that the two functions agree on the location of ```pl``` (which is a pointer to the global variable ```plot``` per above). However, in the code generated to call ```calloc(3)```, it looks like the value of ```pl->num_datasets``` is never loaded: instead, the value 0 is always used, leading to 0 being passed as the size argument to ```malloc(3)```:\r\n\r\n```\r\n        if (pl->bar == NULL)\r\n   120004708:   d8750060        clc     c3,zero,96(c21)\r\n   12000470c:   67c1008c        daddiu  at,s8,140\r\n   120004710:   49b85841        csetoffset      c24,c11,at\r\n   120004714:   48950007        cfromptr        c21,c0,zero\r\n   120004718:   49c11d41        cne     at,c3,c21\r\n   12000471c:   1420000c        bnez    at,120004750 <PlotSet+0x168>\r\n   120004720:   67d20090        daddiu  s2,s8,144\r\n                pl->bar = calloc(sizeof(char *), pl->num_datasets);\r\n   120004724:   67818bf8        daddiu  at,gp,-29704\r\n   120004728:   48810047        cfromptr        c1,c0,at\r\n   12000472c:   c8210003        cld     at,zero,0(c1)\r\n   120004730:   48000807        cgetpcc c1\r\n   120004734:   49ac0841        csetoffset      c12,c1,at\r\n   120004738:   64040020        daddiu  a0,zero,32\r\n   12000473c:   48f16000        cjalr   c17,c12\r\n   120004740:   64050000        daddiu  a1,zero,0            <-- Problem here: should be using loaded pl->num_datasets, which is non-zero\r\n```\r\n\r\nEarlier initialisation of ```pl->num_datasets``` appears to be as expected:\r\n```\r\nstatic void\r\nSetupPlot(int width, int separate, int num_datasets)\r\n{\r\n   1200043c8:   67bdffa0        daddiu  sp,sp,-96\r\n   1200043cc:   ebcbeac3        csd     s8,sp,88(c11)\r\n   1200043d0:   03a0f025        move    s8,sp\r\n   1200043d4:   49b96002        cgetoffset      t9,c12\r\n   1200043d8:   3c010008        lui     at,0x8\r\n   1200043dc:   0039082d        daddu   at,at,t9\r\n   1200043e0:   64216228        daddiu  at,at,25128\r\n        struct plot *pl;\r\n\r\n        pl = &plot;\r\n        pl->width = width;\r\n   1200043e4:   dc218060        ld      at,-32672(at)\r\n   1200043e8:   64213960        daddiu  at,at,14688\r\n   1200043ec:   48810047        cfromptr        c1,c0,at\r\n   1200043f0:   e88100c2        csw     a0,zero,24(c1)\r\n        pl->height = 0;\r\n   1200043f4:   e8010182        csw     zero,zero,48(c1)\r\n   1200043f8:   48820007        cfromptr        c2,c0,zero\r\n        pl->data = NULL;\r\n   1200043fc:   f8410040        csc     c2,zero,64(c1)\r\n        pl->bar = NULL;\r\n   120004400:   f8410060        csc     c2,zero,96(c1)\r\n        pl->separate_bars = separate;\r\n   120004404:   64010080        daddiu  at,zero,128\r\n   120004408:   e8a10802        csw     a1,at,0(c1)\r\n        pl->num_datasets = num_datasets;\r\n   12000440c:   64010084        daddiu  at,zero,132\r\n   120004410:   e8c10802        csw     a2,at,0(c1)\r\n...\r\n```\r\n\r\nStreamtrace seems to confirm that a value of 1 was stored as a result of the call to ```SetupPlot()``` prior to ```PlotSet()```."},"comment":{"url":"https://api.github.com/repos/CTSRD-CHERI/llvm/issues/comments/165258046","html_url":"https://github.com/CTSRD-CHERI/llvm/issues/144#issuecomment-165258046","issue_url":"https://api.github.com/repos/CTSRD-CHERI/llvm/issues/144","id":165258046,"user":{"login":"rwatson","id":186862,"avatar_url":"https://avatars.githubusercontent.com/u/186862?v=3","gravatar_id":"","url":"https://api.github.com/users/rwatson","html_url":"https://github.com/rwatson","followers_url":"https://api.github.com/users/rwatson/followers","following_url":"https://api.github.com/users/rwatson/following{/other_user}","gists_url":"https://api.github.com/users/rwatson/gists{/gist_id}","starred_url":"https://api.github.com/users/rwatson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rwatson/subscriptions","organizations_url":"https://api.github.com/users/rwatson/orgs","repos_url":"https://api.github.com/users/rwatson/repos","events_url":"https://api.github.com/users/rwatson/events{/privacy}","received_events_url":"https://api.github.com/users/rwatson/received_events","type":"User","site_admin":false},"created_at":"2015-12-16T21:41:08Z","updated_at":"2015-12-16T21:41:08Z","body":"I can confirm that this appears to be resolved in the cases of ```ncal(1)```, ```ministat(1)```, and ```elfdump(1)```."}}